1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/sched.h>
4 #include <linux/string.h>
5 #include <linux/timer.h>
6 #include <linux/delay.h>
7 #include <linux/errno.h>
8 #include <linux/slab.h>
9 #include <linux/poll.h>
10 #include <linux/i2c.h>
11 #include <linux/types.h>
12 #include <linux/videodev.h>
13 #include <linux/init.h>
14
15 #include <media/id.h>
16 #include <media/saa6752hs.h>
17
18 /* Addresses to scan */
19 static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
20 static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
21 I2C_CLIENT_INSMOD;
22
23 MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
24 MODULE_AUTHOR("Andrew de Quincey");
25 MODULE_LICENSE("GPL");
26
27 static struct i2c_driver driver;
28 static struct i2c_client client_template;
29
30
31 enum saa6752hs_command {
32 SAA6752HS_COMMAND_RESET = 0,
33 SAA6752HS_COMMAND_STOP = 1,
34 SAA6752HS_COMMAND_START = 2,
35 SAA6752HS_COMMAND_PAUSE = 3,
36 SAA6752HS_COMMAND_RECONFIGURE = 4,
37 SAA6752HS_COMMAND_SLEEP = 5,
38 SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6,
39
40 SAA6752HS_COMMAND_MAX
41 };
42
43
44 /* ---------------------------------------------------------------------- */
45
46 static u8 PAT[] = {
47 0xc2, // i2c register
48 0x00, // table number for encoder
49
50 0x47, // sync
51 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0)
52 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
53
54 0x00, // PSI pointer to start of table
55
56 0x00, // tid(0)
57 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13)
58
59 0x00, 0x01, // transport_stream_id(1)
60
61 0xc1, // version_number(0), current_next_indicator(1)
62
63 0x00, 0x00, // section_number(0), last_section_number(0)
64
65 0x00, 0x01, // program_number(1)
66
67 0xe0, 0x10, // PMT PID(0x10)
68
69 0x76, 0xf1, 0x44, 0xd1 // CRC32
70 };
71
72 static u8 PMT[] = {
73 0xc2, // i2c register
74 0x01, // table number for encoder
75
76 0x47, // sync
77 0x40, 0x10, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0x10)
78 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
79
80 0x00, // PSI pointer to start of table
81
82 0x02, // tid(2)
83 0xb0, 0x17, // section_syntax_indicator(1), section_length(23)
84
85 0x00, 0x01, // program_number(1)
86
87 0xc1, // version_number(0), current_next_indicator(1)
88
89 0x00, 0x00, // section_number(0), last_section_number(0)
90
91 0xe1, 0x04, // PCR_PID (0x104)
92
93 0xf0, 0x00, // program_info_length(0)
94
95 0x02, 0xe1, 0x00, 0xf0, 0x00, // video stream type(2), pid(0x100)
96 0x04, 0xe1, 0x03, 0xf0, 0x00, // audio stream type(4), pid(0x103)
97
98 0xa1, 0xca, 0x0f, 0x82 // CRC32
99 };
100
101 static struct mpeg_params mpeg_params_template =
102 {
103 .bitrate_mode = MPEG_BITRATE_MODE_CBR,
104 .video_target_bitrate = 5000,
105 .audio_bitrate = MPEG_AUDIO_BITRATE_256,
106 .total_bitrate = 6000,
107 };
108
109
110 /* ---------------------------------------------------------------------- */
111
112
113 static int saa6752hs_chip_command(struct i2c_client* client,
114 enum saa6752hs_command command)
115 {
116 unsigned char buf[3];
117 unsigned long timeout;
118 int status = 0;
119
120 // execute the command
121 switch(command) {
122 case SAA6752HS_COMMAND_RESET:
123 buf[0] = 0x00;
124 break;
125
126 case SAA6752HS_COMMAND_STOP:
127 buf[0] = 0x03;
128 break;
129
130 case SAA6752HS_COMMAND_START:
131 buf[0] = 0x02;
132 break;
133
134 case SAA6752HS_COMMAND_PAUSE:
135 buf[0] = 0x04;
136 break;
137
138 case SAA6752HS_COMMAND_RECONFIGURE:
139 buf[0] = 0x05;
140 break;
141
142 case SAA6752HS_COMMAND_SLEEP:
143 buf[0] = 0x06;
144 break;
145
146 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
147 buf[0] = 0x07;
148 break;
149
150 default:
151 return -EINVAL;
152 }
153
154 // set it and wait for it to be so
155 i2c_master_send(client, buf, 1);
156 timeout = jiffies + HZ * 3;
157 for (;;) {
158 // get the current status
159 buf[0] = 0x10;
160 i2c_master_send(client, buf, 1);
161 i2c_master_recv(client, buf, 1);
162
163 if (!(buf[0] & 0x20))
164 break;
165 if (time_after(jiffies,timeout)) {
166 status = -ETIMEDOUT;
167 break;
168 }
169
170 // wait a bit
171 msleep(10);
172 }
173
174 // delay a bit to let encoder settle
175 msleep(50);
176
177 // done
178 return status;
179 }
180
181
182 static int saa6752hs_set_bitrate(struct i2c_client* client,
183 struct mpeg_params* params)
184 {
185 u8 buf[3];
186
187 // set the bitrate mode
188 buf[0] = 0x71;
189 buf[1] = params->bitrate_mode;
190 i2c_master_send(client, buf, 2);
191
192 // set the video bitrate
193 if (params->bitrate_mode == MPEG_BITRATE_MODE_VBR) {
194 // set the target bitrate
195 buf[0] = 0x80;
196 buf[1] = params->video_target_bitrate >> 8;
197 buf[2] = params->video_target_bitrate & 0xff;
198 i2c_master_send(client, buf, 3);
199
200 // set the max bitrate
201 buf[0] = 0x81;
202 buf[1] = params->video_max_bitrate >> 8;
203 buf[2] = params->video_max_bitrate & 0xff;
204 i2c_master_send(client, buf, 3);
205 } else {
206 // set the target bitrate (no max bitrate for CBR)
207 buf[0] = 0x81;
208 buf[1] = params->video_target_bitrate >> 8;
209 buf[2] = params->video_target_bitrate & 0xff;
210 i2c_master_send(client, buf, 3);
211 }
212
213 // set the audio bitrate
214 buf[0] = 0x94;
215 buf[1] = params->audio_bitrate;
216 i2c_master_send(client, buf, 2);
217
218 // set the total bitrate
219 buf[0] = 0xb1;
220 buf[1] = params->total_bitrate >> 8;
221 buf[2] = params->total_bitrate & 0xff;
222 i2c_master_send(client, buf, 3);
223
224 return 0;
225 }
226
227
228 static int saa6752hs_init(struct i2c_client* client, struct mpeg_params* params)
229 {
230 unsigned char buf[3];
231 void *data;
232
233 // check the bitrate parameters first
234 if (params != NULL) {
235 if (params->bitrate_mode >= MPEG_BITRATE_MODE_MAX)
236 return -EINVAL;
237 if (params->video_target_bitrate >= MPEG_VIDEO_TARGET_BITRATE_MAX)
238 return -EINVAL;
239 if (params->video_max_bitrate >= MPEG_VIDEO_MAX_BITRATE_MAX)
240 return -EINVAL;
241 if (params->audio_bitrate >= MPEG_AUDIO_BITRATE_MAX)
242 return -EINVAL;
243 if (params->total_bitrate >= MPEG_TOTAL_BITRATE_MAX)
244 return -EINVAL;
245 if (params->bitrate_mode == MPEG_BITRATE_MODE_MAX &&
246 params->video_target_bitrate <= params->video_max_bitrate)
247 return -EINVAL;
248 }
249
250 // Set GOP structure {3, 13}
251 buf[0] = 0x72;
252 buf[1] = 0x03;
253 buf[2] = 0x0D;
254 i2c_master_send(client,buf,3);
255
256 // Set minimum Q-scale {4}
257 buf[0] = 0x82;
258 buf[1] = 0x04;
259 i2c_master_send(client,buf,2);
260
261 // Set maximum Q-scale {12}
262 buf[0] = 0x83;
263 buf[1] = 0x0C;
264 i2c_master_send(client,buf,2);
265
266 // Set Output Protocol
267 buf[0] = 0xD0;
268 buf[1] = 0x01;
269 i2c_master_send(client,buf,2);
270
271 // Set video output stream format {TS}
272 buf[0] = 0xB0;
273 buf[1] = 0x05;
274 i2c_master_send(client,buf,2);
275
276 // Set Audio PID {0x103}
277 buf[0] = 0xC1;
278 buf[1] = 0x01;
279 buf[2] = 0x03;
280 i2c_master_send(client,buf,3);
281
282 // setup bitrate settings
283 data = i2c_get_clientdata(client);
284 if (params) {
285 saa6752hs_set_bitrate(client, params);
286 memcpy(data, params, sizeof(struct mpeg_params));
287 } else {
288 // parameters were not supplied. use the previous set
289 saa6752hs_set_bitrate(client, (struct mpeg_params*) data);
290 }
291
292 // Send SI tables
293 i2c_master_send(client,PAT,sizeof(PAT));
294 i2c_master_send(client,PMT,sizeof(PMT));
295
296 // mute then unmute audio. This removes buzzing artefacts
297 buf[0] = 0xa4;
298 buf[1] = 1;
299 i2c_master_send(client, buf, 2);
300 buf[1] = 0;
301 i2c_master_send(client, buf, 2);
302
303 // start it going
304 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
305
306 return 0;
307 }
308
309 static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
310 {
311 struct i2c_client *client;
312 struct mpeg_params* params;
313
314 client_template.adapter = adap;
315 client_template.addr = addr;
316
317 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
318
319 if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
320 return -ENOMEM;
321 memcpy(client,&client_template,sizeof(struct i2c_client));
322 strlcpy(client->name, "saa6752hs", sizeof(client->name));
323
324 if (NULL == (params = kmalloc(sizeof(struct mpeg_params), GFP_KERNEL)))
325 return -ENOMEM;
326 memcpy(params,&mpeg_params_template,sizeof(struct mpeg_params));
327 i2c_set_clientdata(client, params);
328
329 i2c_attach_client(client);
330
331 return 0;
332 }
333
334 static int saa6752hs_probe(struct i2c_adapter *adap)
335 {
336 if (adap->class & I2C_CLASS_TV_ANALOG)
337 return i2c_probe(adap, &addr_data, saa6752hs_attach);
338 return 0;
339 }
340
341 static int saa6752hs_detach(struct i2c_client *client)
342 {
343 void *data;
344
345 data = i2c_get_clientdata(client);
346 i2c_detach_client(client);
347 kfree(data);
348 kfree(client);
349 return 0;
350 }
351
352 static int
353 saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
354 {
355 struct mpeg_params* init_arg = arg;
356
357 switch (cmd) {
358 case MPEG_SETPARAMS:
359 return saa6752hs_init(client, init_arg);
360
361 default:
362 /* nothing */
363 break;
364 }
365
366 return 0;
367 }
368
369 /* ----------------------------------------------------------------------- */
370
371 static struct i2c_driver driver = {
372 .owner = THIS_MODULE,
373 .name = "i2c saa6752hs MPEG encoder",
374 .id = I2C_DRIVERID_SAA6752HS,
375 .flags = I2C_DF_NOTIFY,
376 .attach_adapter = saa6752hs_probe,
377 .detach_client = saa6752hs_detach,
378 .command = saa6752hs_command,
379 };
380
381 static struct i2c_client client_template =
382 {
383 I2C_DEVNAME("(saa6752hs unset)"),
384 .flags = I2C_CLIENT_ALLOW_USE,
385 .driver = &driver,
386 };
387
388 static int __init saa6752hs_init_module(void)
389 {
390 return i2c_add_driver(&driver);
391 }
392
393 static void __exit saa6752hs_cleanup_module(void)
394 {
395 i2c_del_driver(&driver);
396 }
397
398 module_init(saa6752hs_init_module);
399 module_exit(saa6752hs_cleanup_module);
400
401 /*
402 * Overrides for Emacs so that we follow Linus's tabbing style.
403 * ---------------------------------------------------------------------------
404 * Local variables:
405 * c-basic-offset: 8
406 * End:
407 */
408
|
This page was automatically generated by the
LXR engine.
|