blob: 796f12d59daa4bfba90b862bb80ad34bdcbd88d7 [file] [log] [blame]
Hans Verkuilbd985162005-11-13 16:07:56 -08001/* cx25840 - Conexant CX25840 audio/video decoder driver
2 *
3 * Copyright (C) 2004 Ulf Eklund
4 *
5 * Based on the saa7115 driver and on the first verison of Chris Kennedy's
6 * cx25840 driver.
7 *
8 * Changes by Tyler Trafford <tatrafford@comcast.net>
9 * - cleanup/rewrite for V4L2 API (2005)
10 *
11 * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
12 *
Christopher Neufeld3e3bf272006-05-24 10:16:45 -030013 * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
14 * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
15 *
Steven Toth6d897612008-09-03 17:12:12 -030016 * CX23885 support by Steven Toth <stoth@linuxtv.org>.
Steven Tothf2340812008-01-10 01:22:39 -030017 *
Hans Verkuilbd985162005-11-13 16:07:56 -080018 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 */
32
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/slab.h>
37#include <linux/videodev2.h>
38#include <linux/i2c.h>
Michael Krufkyf61b48f2007-09-01 02:02:51 -030039#include <linux/delay.h>
Hans Verkuilbd985162005-11-13 16:07:56 -080040#include <media/v4l2-common.h>
Hans Verkuil3434eb72007-04-27 12:31:08 -030041#include <media/v4l2-chip-ident.h>
Hans Verkuilb6198ad2009-03-29 08:55:46 -030042#include <media/v4l2-i2c-drv.h>
Hans Verkuil31bc09b2006-03-25 10:26:09 -030043#include <media/cx25840.h>
Hans Verkuilbd985162005-11-13 16:07:56 -080044
Hans Verkuil31bc09b2006-03-25 10:26:09 -030045#include "cx25840-core.h"
Hans Verkuilbd985162005-11-13 16:07:56 -080046
47MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
Hans Verkuil1f4b3362005-11-13 16:08:05 -080048MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
Hans Verkuilbd985162005-11-13 16:07:56 -080049MODULE_LICENSE("GPL");
50
Adrian Bunkfe0d3df2008-07-21 16:33:48 -030051static int cx25840_debug;
Hans Verkuilbd985162005-11-13 16:07:56 -080052
Hans Verkuilb5fc7142006-01-11 22:41:36 -020053module_param_named(debug,cx25840_debug, int, 0644);
Hans Verkuilbd985162005-11-13 16:07:56 -080054
Hans Verkuilfac9e892006-01-09 15:32:40 -020055MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
Hans Verkuilbd985162005-11-13 16:07:56 -080056
Hans Verkuilbd985162005-11-13 16:07:56 -080057
58/* ----------------------------------------------------------------------- */
59
60int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
61{
62 u8 buffer[3];
63 buffer[0] = addr >> 8;
64 buffer[1] = addr & 0xff;
65 buffer[2] = value;
66 return i2c_master_send(client, buffer, 3);
67}
68
69int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
70{
71 u8 buffer[6];
72 buffer[0] = addr >> 8;
73 buffer[1] = addr & 0xff;
Hans Verkuil4a56eb32007-12-02 07:03:45 -030074 buffer[2] = value & 0xff;
75 buffer[3] = (value >> 8) & 0xff;
76 buffer[4] = (value >> 16) & 0xff;
77 buffer[5] = value >> 24;
Hans Verkuilbd985162005-11-13 16:07:56 -080078 return i2c_master_send(client, buffer, 6);
79}
80
81u8 cx25840_read(struct i2c_client * client, u16 addr)
82{
83 u8 buffer[2];
84 buffer[0] = addr >> 8;
85 buffer[1] = addr & 0xff;
86
87 if (i2c_master_send(client, buffer, 2) < 2)
88 return 0;
89
90 if (i2c_master_recv(client, buffer, 1) < 1)
91 return 0;
92
93 return buffer[0];
94}
95
96u32 cx25840_read4(struct i2c_client * client, u16 addr)
97{
98 u8 buffer[4];
99 buffer[0] = addr >> 8;
100 buffer[1] = addr & 0xff;
101
102 if (i2c_master_send(client, buffer, 2) < 2)
103 return 0;
104
105 if (i2c_master_recv(client, buffer, 4) < 4)
106 return 0;
107
Hans Verkuil17531c12006-08-08 09:10:12 -0300108 return (buffer[3] << 24) | (buffer[2] << 16) |
109 (buffer[1] << 8) | buffer[0];
Hans Verkuilbd985162005-11-13 16:07:56 -0800110}
111
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300112int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask,
Hans Verkuilbd985162005-11-13 16:07:56 -0800113 u8 or_value)
114{
115 return cx25840_write(client, addr,
116 (cx25840_read(client, addr) & and_mask) |
117 or_value);
118}
119
120/* ----------------------------------------------------------------------- */
121
Hans Verkuila8bbf122006-01-09 15:25:42 -0200122static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
123 enum cx25840_audio_input aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800124
125/* ----------------------------------------------------------------------- */
126
Hans Verkuild92c20e2006-01-09 15:32:41 -0200127static void init_dll1(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800128{
129 /* This is the Hauppauge sequence used to
130 * initialize the Delay Lock Loop 1 (ADC DLL). */
131 cx25840_write(client, 0x159, 0x23);
132 cx25840_write(client, 0x15a, 0x87);
133 cx25840_write(client, 0x15b, 0x06);
Tyler Trafford38051452007-08-28 17:56:47 -0300134 udelay(10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800135 cx25840_write(client, 0x159, 0xe1);
Tyler Trafford38051452007-08-28 17:56:47 -0300136 udelay(10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800137 cx25840_write(client, 0x15a, 0x86);
138 cx25840_write(client, 0x159, 0xe0);
139 cx25840_write(client, 0x159, 0xe1);
140 cx25840_write(client, 0x15b, 0x10);
141}
142
Hans Verkuild92c20e2006-01-09 15:32:41 -0200143static void init_dll2(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800144{
145 /* This is the Hauppauge sequence used to
146 * initialize the Delay Lock Loop 2 (ADC DLL). */
147 cx25840_write(client, 0x15d, 0xe3);
148 cx25840_write(client, 0x15e, 0x86);
149 cx25840_write(client, 0x15f, 0x06);
Tyler Trafford38051452007-08-28 17:56:47 -0300150 udelay(10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800151 cx25840_write(client, 0x15d, 0xe1);
152 cx25840_write(client, 0x15d, 0xe0);
153 cx25840_write(client, 0x15d, 0xe1);
154}
155
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300156static void cx25836_initialize(struct i2c_client *client)
157{
158 /* reset configuration is described on page 3-77 of the CX25836 datasheet */
159 /* 2. */
160 cx25840_and_or(client, 0x000, ~0x01, 0x01);
161 cx25840_and_or(client, 0x000, ~0x01, 0x00);
162 /* 3a. */
163 cx25840_and_or(client, 0x15a, ~0x70, 0x00);
164 /* 3b. */
165 cx25840_and_or(client, 0x15b, ~0x1e, 0x06);
166 /* 3c. */
167 cx25840_and_or(client, 0x159, ~0x02, 0x02);
168 /* 3d. */
Tyler Trafford38051452007-08-28 17:56:47 -0300169 udelay(10);
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300170 /* 3e. */
171 cx25840_and_or(client, 0x159, ~0x02, 0x00);
172 /* 3f. */
173 cx25840_and_or(client, 0x159, ~0xc0, 0xc0);
174 /* 3g. */
175 cx25840_and_or(client, 0x159, ~0x01, 0x00);
176 cx25840_and_or(client, 0x159, ~0x01, 0x01);
177 /* 3h. */
178 cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
179}
180
Hans Verkuil21340ae2007-08-26 10:53:16 -0300181static void cx25840_work_handler(struct work_struct *work)
182{
183 struct cx25840_state *state = container_of(work, struct cx25840_state, fw_work);
184 cx25840_loadfw(state->c);
185 wake_up(&state->fw_wait);
186}
187
Hans Verkuil89fc4eb2007-08-04 05:00:07 -0300188static void cx25840_initialize(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800189{
Hans Verkuil21340ae2007-08-26 10:53:16 -0300190 DEFINE_WAIT(wait);
Hans Verkuil9357b312008-11-29 12:50:06 -0300191 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil21340ae2007-08-26 10:53:16 -0300192 struct workqueue_struct *q;
Hans Verkuilbd985162005-11-13 16:07:56 -0800193
194 /* datasheet startup in numbered steps, refer to page 3-77 */
195 /* 2. */
196 cx25840_and_or(client, 0x803, ~0x10, 0x00);
197 /* The default of this register should be 4, but I get 0 instead.
198 * Set this register to 4 manually. */
199 cx25840_write(client, 0x000, 0x04);
200 /* 3. */
201 init_dll1(client);
202 init_dll2(client);
203 cx25840_write(client, 0x136, 0x0a);
204 /* 4. */
205 cx25840_write(client, 0x13c, 0x01);
206 cx25840_write(client, 0x13c, 0x00);
207 /* 5. */
Hans Verkuil21340ae2007-08-26 10:53:16 -0300208 /* Do the firmware load in a work handler to prevent.
209 Otherwise the kernel is blocked waiting for the
210 bit-banging i2c interface to finish uploading the
211 firmware. */
212 INIT_WORK(&state->fw_work, cx25840_work_handler);
213 init_waitqueue_head(&state->fw_wait);
214 q = create_singlethread_workqueue("cx25840_fw");
215 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
216 queue_work(q, &state->fw_work);
217 schedule();
218 finish_wait(&state->fw_wait, &wait);
219 destroy_workqueue(q);
220
Hans Verkuilbd985162005-11-13 16:07:56 -0800221 /* 6. */
222 cx25840_write(client, 0x115, 0x8c);
223 cx25840_write(client, 0x116, 0x07);
224 cx25840_write(client, 0x118, 0x02);
225 /* 7. */
226 cx25840_write(client, 0x4a5, 0x80);
227 cx25840_write(client, 0x4a5, 0x00);
228 cx25840_write(client, 0x402, 0x00);
229 /* 8. */
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300230 cx25840_and_or(client, 0x401, ~0x18, 0);
231 cx25840_and_or(client, 0x4a2, ~0x10, 0x10);
232 /* steps 8c and 8d are done in change_input() */
Hans Verkuilbd985162005-11-13 16:07:56 -0800233 /* 10. */
234 cx25840_write(client, 0x8d3, 0x1f);
235 cx25840_write(client, 0x8e3, 0x03);
236
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300237 cx25840_std_setup(client);
Hans Verkuilbd985162005-11-13 16:07:56 -0800238
239 /* trial and error says these are needed to get audio */
240 cx25840_write(client, 0x914, 0xa0);
241 cx25840_write(client, 0x918, 0xa0);
242 cx25840_write(client, 0x919, 0x01);
243
244 /* stereo prefered */
245 cx25840_write(client, 0x809, 0x04);
246 /* AC97 shift */
247 cx25840_write(client, 0x8cf, 0x0f);
248
Hans Verkuila8bbf122006-01-09 15:25:42 -0200249 /* (re)set input */
250 set_input(client, state->vid_input, state->aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800251
252 /* start microcontroller */
253 cx25840_and_or(client, 0x803, ~0x10, 0x10);
254}
255
Steven Tothf2340812008-01-10 01:22:39 -0300256static void cx23885_initialize(struct i2c_client *client)
257{
258 DEFINE_WAIT(wait);
Hans Verkuil9357b312008-11-29 12:50:06 -0300259 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Steven Tothf2340812008-01-10 01:22:39 -0300260 struct workqueue_struct *q;
261
Andy Wallse283d782009-09-27 00:00:48 -0300262 /*
263 * Come out of digital power down
264 * The CX23888, at least, needs this, otherwise registers aside from
265 * 0x0-0x2 can't be read or written.
266 */
267 cx25840_write(client, 0x000, 0);
268
Steven Tothf2340812008-01-10 01:22:39 -0300269 /* Internal Reset */
270 cx25840_and_or(client, 0x102, ~0x01, 0x01);
271 cx25840_and_or(client, 0x102, ~0x01, 0x00);
272
273 /* Stop microcontroller */
274 cx25840_and_or(client, 0x803, ~0x10, 0x00);
275
276 /* DIF in reset? */
277 cx25840_write(client, 0x398, 0);
278
Andy Wallse283d782009-09-27 00:00:48 -0300279 /*
280 * Trust the default xtal, no division
281 * '885: 28.636363... MHz
282 * '887: 25.000000 MHz
283 * '888: 50.000000 MHz
284 */
Steven Tothf2340812008-01-10 01:22:39 -0300285 cx25840_write(client, 0x2, 0x76);
286
Andy Wallse283d782009-09-27 00:00:48 -0300287 /* Power up all the PLL's and DLL */
Steven Tothf2340812008-01-10 01:22:39 -0300288 cx25840_write(client, 0x1, 0x40);
289
Andy Wallse283d782009-09-27 00:00:48 -0300290 /* Sys PLL */
291 switch (state->id) {
292 case V4L2_IDENT_CX23888_AV:
293 /*
294 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
295 * 572.73 MHz before post divide
296 */
297 cx25840_write4(client, 0x11c, 0x00e8ba26);
298 cx25840_write4(client, 0x118, 0x0000040b);
299 break;
300 case V4L2_IDENT_CX23887_AV:
301 /*
302 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
303 * 572.73 MHz before post divide
304 */
305 cx25840_write4(client, 0x11c, 0x01d1744c);
306 cx25840_write4(client, 0x118, 0x00000416);
307 break;
308 case V4L2_IDENT_CX23885_AV:
309 default:
310 /*
311 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
312 * 572.73 MHz before post divide
313 */
314 cx25840_write4(client, 0x11c, 0x00000000);
315 cx25840_write4(client, 0x118, 0x00000414);
316 break;
317 }
Steven Tothf2340812008-01-10 01:22:39 -0300318
319 /* Disable DIF bypass */
320 cx25840_write4(client, 0x33c, 0x00000001);
321
322 /* DIF Src phase inc */
323 cx25840_write4(client, 0x340, 0x0df7df83);
324
Andy Wallse283d782009-09-27 00:00:48 -0300325 /*
326 * Vid PLL
327 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
328 *
329 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
330 * 432.0 MHz before post divide
331 */
332 cx25840_write4(client, 0x10c, 0x002be2c9);
333 cx25840_write4(client, 0x108, 0x0000040f);
Steven Tothf2340812008-01-10 01:22:39 -0300334
335 /* Luma */
336 cx25840_write4(client, 0x414, 0x00107d12);
337
338 /* Chroma */
339 cx25840_write4(client, 0x420, 0x3d008282);
340
Andy Wallse283d782009-09-27 00:00:48 -0300341 /*
342 * Aux PLL
343 * Initial setup for audio sample clock:
344 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
345 * Intial I2S output/master clock(?):
346 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
347 */
348 switch (state->id) {
349 case V4L2_IDENT_CX23888_AV:
350 /*
351 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
352 * 368.64 MHz before post divide
353 * 122.88 MHz / 0xa = 12.288 MHz
354 */
355 cx25840_write4(client, 0x114, 0x00bedfa4);
356 cx25840_write4(client, 0x110, 0x000a0307);
357 break;
358 case V4L2_IDENT_CX23887_AV:
359 /*
360 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
361 * 368.64 MHz before post divide
362 * 122.88 MHz / 0xa = 12.288 MHz
363 */
364 cx25840_write4(client, 0x114, 0x017dbf48);
365 cx25840_write4(client, 0x110, 0x000a030e);
366 break;
367 case V4L2_IDENT_CX23885_AV:
368 default:
369 /*
370 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
371 * 368.64 MHz before post divide
372 * 122.88 MHz / 0xa = 12.288 MHz
373 */
374 cx25840_write4(client, 0x114, 0x01bf0c9e);
375 cx25840_write4(client, 0x110, 0x000a030c);
376 break;
377 };
Steven Tothf2340812008-01-10 01:22:39 -0300378
379 /* ADC2 input select */
380 cx25840_write(client, 0x102, 0x10);
381
382 /* VIN1 & VIN5 */
383 cx25840_write(client, 0x103, 0x11);
384
385 /* Enable format auto detect */
386 cx25840_write(client, 0x400, 0);
387 /* Fast subchroma lock */
388 /* White crush, Chroma AGC & Chroma Killer enabled */
389 cx25840_write(client, 0x401, 0xe8);
390
391 /* Select AFE clock pad output source */
392 cx25840_write(client, 0x144, 0x05);
393
Steven Tothf3d6f632009-07-23 12:18:54 -0300394 /* Drive GPIO2 direction and values for HVR1700
395 * where an onboard mux selects the output of demodulator
396 * vs the 417. Failure to set this results in no DTV.
397 * It's safe to set this across all Hauppauge boards
398 * currently, regardless of the board type.
399 */
400 cx25840_write(client, 0x160, 0x1d);
401 cx25840_write(client, 0x164, 0x00);
402
Steven Tothf2340812008-01-10 01:22:39 -0300403 /* Do the firmware load in a work handler to prevent.
404 Otherwise the kernel is blocked waiting for the
405 bit-banging i2c interface to finish uploading the
406 firmware. */
407 INIT_WORK(&state->fw_work, cx25840_work_handler);
408 init_waitqueue_head(&state->fw_wait);
409 q = create_singlethread_workqueue("cx25840_fw");
410 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
411 queue_work(q, &state->fw_work);
412 schedule();
413 finish_wait(&state->fw_wait, &wait);
414 destroy_workqueue(q);
415
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300416 cx25840_std_setup(client);
Steven Tothf2340812008-01-10 01:22:39 -0300417
418 /* (re)set input */
419 set_input(client, state->vid_input, state->aud_input);
420
421 /* start microcontroller */
422 cx25840_and_or(client, 0x803, ~0x10, 0x10);
423}
424
Hans Verkuilbd985162005-11-13 16:07:56 -0800425/* ----------------------------------------------------------------------- */
426
Sri Deevi149783b2009-03-03 06:07:42 -0300427static void cx231xx_initialize(struct i2c_client *client)
428{
429 DEFINE_WAIT(wait);
430 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
431 struct workqueue_struct *q;
432
433 /* Internal Reset */
434 cx25840_and_or(client, 0x102, ~0x01, 0x01);
435 cx25840_and_or(client, 0x102, ~0x01, 0x00);
436
437 /* Stop microcontroller */
438 cx25840_and_or(client, 0x803, ~0x10, 0x00);
439
440 /* DIF in reset? */
441 cx25840_write(client, 0x398, 0);
442
443 /* Trust the default xtal, no division */
444 /* This changes for the cx23888 products */
445 cx25840_write(client, 0x2, 0x76);
446
447 /* Bring down the regulator for AUX clk */
448 cx25840_write(client, 0x1, 0x40);
449
450 /* Disable DIF bypass */
451 cx25840_write4(client, 0x33c, 0x00000001);
452
453 /* DIF Src phase inc */
454 cx25840_write4(client, 0x340, 0x0df7df83);
455
Sri Deevi149783b2009-03-03 06:07:42 -0300456 /* Luma */
457 cx25840_write4(client, 0x414, 0x00107d12);
458
459 /* Chroma */
460 cx25840_write4(client, 0x420, 0x3d008282);
461
Sri Deevi149783b2009-03-03 06:07:42 -0300462 /* ADC2 input select */
463 cx25840_write(client, 0x102, 0x10);
464
465 /* VIN1 & VIN5 */
466 cx25840_write(client, 0x103, 0x11);
467
468 /* Enable format auto detect */
469 cx25840_write(client, 0x400, 0);
470 /* Fast subchroma lock */
471 /* White crush, Chroma AGC & Chroma Killer enabled */
472 cx25840_write(client, 0x401, 0xe8);
473
Sri Deevi149783b2009-03-03 06:07:42 -0300474 /* Do the firmware load in a work handler to prevent.
475 Otherwise the kernel is blocked waiting for the
476 bit-banging i2c interface to finish uploading the
477 firmware. */
478 INIT_WORK(&state->fw_work, cx25840_work_handler);
479 init_waitqueue_head(&state->fw_wait);
480 q = create_singlethread_workqueue("cx25840_fw");
481 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
482 queue_work(q, &state->fw_work);
483 schedule();
484 finish_wait(&state->fw_wait, &wait);
485 destroy_workqueue(q);
486
487 cx25840_std_setup(client);
488
489 /* (re)set input */
490 set_input(client, state->vid_input, state->aud_input);
491
492 /* start microcontroller */
493 cx25840_and_or(client, 0x803, ~0x10, 0x10);
494}
495
496/* ----------------------------------------------------------------------- */
497
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300498void cx25840_std_setup(struct i2c_client *client)
499{
Hans Verkuil9357b312008-11-29 12:50:06 -0300500 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300501 v4l2_std_id std = state->std;
502 int hblank, hactive, burst, vblank, vactive, sc;
503 int vblank656, src_decimation;
504 int luma_lpf, uv_lpf, comb;
505 u32 pll_int, pll_frac, pll_post;
506
507 /* datasheet startup, step 8d */
508 if (std & ~V4L2_STD_NTSC)
509 cx25840_write(client, 0x49f, 0x11);
510 else
511 cx25840_write(client, 0x49f, 0x14);
512
513 if (std & V4L2_STD_625_50) {
514 hblank = 132;
515 hactive = 720;
516 burst = 93;
517 vblank = 36;
518 vactive = 580;
519 vblank656 = 40;
520 src_decimation = 0x21f;
521 luma_lpf = 2;
522
523 if (std & V4L2_STD_SECAM) {
524 uv_lpf = 0;
525 comb = 0;
526 sc = 0x0a425f;
527 } else if (std == V4L2_STD_PAL_Nc) {
528 uv_lpf = 1;
529 comb = 0x20;
530 sc = 556453;
531 } else {
532 uv_lpf = 1;
533 comb = 0x20;
534 sc = 688739;
535 }
536 } else {
537 hactive = 720;
538 hblank = 122;
539 vactive = 487;
540 luma_lpf = 1;
541 uv_lpf = 1;
542
543 src_decimation = 0x21f;
544 if (std == V4L2_STD_PAL_60) {
545 vblank = 26;
546 vblank656 = 26;
547 burst = 0x5b;
548 luma_lpf = 2;
549 comb = 0x20;
550 sc = 688739;
551 } else if (std == V4L2_STD_PAL_M) {
552 vblank = 20;
553 vblank656 = 24;
554 burst = 0x61;
555 comb = 0x20;
556 sc = 555452;
557 } else {
558 vblank = 26;
559 vblank656 = 26;
560 burst = 0x5b;
561 comb = 0x66;
562 sc = 556063;
563 }
564 }
565
566 /* DEBUG: Displays configured PLL frequency */
Andy Walls2a03f032009-09-26 23:47:21 -0300567 if (!is_cx231xx(state)) {
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300568 pll_int = cx25840_read(client, 0x108);
569 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
570 pll_post = cx25840_read(client, 0x109);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300571 v4l_dbg(1, cx25840_debug, client,
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300572 "PLL regs = int: %u, frac: %u, post: %u\n",
573 pll_int, pll_frac, pll_post);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300574
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300575 if (pll_post) {
576 int fin, fsc;
577 int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300578
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300579 pll /= pll_post;
580 v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
581 pll / 1000000, pll % 1000000);
582 v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
583 pll / 8000000, (pll / 8) % 1000000);
584
585 fin = ((u64)src_decimation * pll) >> 12;
586 v4l_dbg(1, cx25840_debug, client,
587 "ADC Sampling freq = %d.%06d MHz\n",
588 fin / 1000000, fin % 1000000);
589
590 fsc = (((u64)sc) * pll) >> 24L;
591 v4l_dbg(1, cx25840_debug, client,
592 "Chroma sub-carrier freq = %d.%06d MHz\n",
593 fsc / 1000000, fsc % 1000000);
594
595 v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
596 "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
597 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
598 "sc 0x%06x\n",
599 hblank, hactive, vblank, vactive, vblank656,
600 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
601 }
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300602 }
603
604 /* Sets horizontal blanking delay and active lines */
605 cx25840_write(client, 0x470, hblank);
606 cx25840_write(client, 0x471,
607 0xff & (((hblank >> 8) & 0x3) | (hactive << 4)));
608 cx25840_write(client, 0x472, hactive >> 4);
609
610 /* Sets burst gate delay */
611 cx25840_write(client, 0x473, burst);
612
613 /* Sets vertical blanking delay and active duration */
614 cx25840_write(client, 0x474, vblank);
615 cx25840_write(client, 0x475,
616 0xff & (((vblank >> 8) & 0x3) | (vactive << 4)));
617 cx25840_write(client, 0x476, vactive >> 4);
618 cx25840_write(client, 0x477, vblank656);
619
620 /* Sets src decimation rate */
621 cx25840_write(client, 0x478, 0xff & src_decimation);
622 cx25840_write(client, 0x479, 0xff & (src_decimation >> 8));
623
624 /* Sets Luma and UV Low pass filters */
625 cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
626
627 /* Enables comb filters */
628 cx25840_write(client, 0x47b, comb);
629
630 /* Sets SC Step*/
631 cx25840_write(client, 0x47c, sc);
632 cx25840_write(client, 0x47d, 0xff & sc >> 8);
633 cx25840_write(client, 0x47e, 0xff & sc >> 16);
634
635 /* Sets VBI parameters */
636 if (std & V4L2_STD_625_50) {
637 cx25840_write(client, 0x47f, 0x01);
638 state->vbi_line_offset = 5;
639 } else {
640 cx25840_write(client, 0x47f, 0x00);
641 state->vbi_line_offset = 8;
642 }
643}
644
645/* ----------------------------------------------------------------------- */
646
Hans Verkuilbd985162005-11-13 16:07:56 -0800647static void input_change(struct i2c_client *client)
648{
Hans Verkuil9357b312008-11-29 12:50:06 -0300649 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil081b4962008-04-22 14:45:51 -0300650 v4l2_std_id std = state->std;
Hans Verkuilbd985162005-11-13 16:07:56 -0800651
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300652 /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
653 if (std & V4L2_STD_SECAM) {
654 cx25840_write(client, 0x402, 0);
655 }
656 else {
657 cx25840_write(client, 0x402, 0x04);
658 cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
659 }
660 cx25840_and_or(client, 0x401, ~0x60, 0);
661 cx25840_and_or(client, 0x401, ~0x60, 0x60);
Hans Verkuil82677612007-08-07 07:16:07 -0300662 cx25840_and_or(client, 0x810, ~0x01, 1);
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300663
Hans Verkuil39c4ad62007-08-05 14:24:17 -0300664 if (state->radio) {
665 cx25840_write(client, 0x808, 0xf9);
666 cx25840_write(client, 0x80b, 0x00);
667 }
668 else if (std & V4L2_STD_525_60) {
Hans Verkuild97a11e2006-02-07 06:48:40 -0200669 /* Certain Hauppauge PVR150 models have a hardware bug
670 that causes audio to drop out. For these models the
671 audio standard must be set explicitly.
672 To be precise: it affects cards with tuner models
673 85, 99 and 112 (model numbers from tveeprom). */
674 int hw_fix = state->pvr150_workaround;
675
676 if (std == V4L2_STD_NTSC_M_JP) {
Hans Verkuilf95006f2005-12-01 00:51:42 -0800677 /* Japan uses EIAJ audio standard */
Hans Verkuild97a11e2006-02-07 06:48:40 -0200678 cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
679 } else if (std == V4L2_STD_NTSC_M_KR) {
680 /* South Korea uses A2 audio standard */
681 cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
Hans Verkuilf95006f2005-12-01 00:51:42 -0800682 } else {
683 /* Others use the BTSC audio standard */
Hans Verkuild97a11e2006-02-07 06:48:40 -0200684 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
Hans Verkuilf95006f2005-12-01 00:51:42 -0800685 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800686 cx25840_write(client, 0x80b, 0x00);
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300687 } else if (std & V4L2_STD_PAL) {
Aleksandr V. Piskunov3c3099d2009-09-25 18:16:21 -0300688 /* Autodetect audio standard and audio system */
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300689 cx25840_write(client, 0x808, 0xff);
Aleksandr V. Piskunov3c3099d2009-09-25 18:16:21 -0300690 /* Since system PAL-L is pretty much non-existant and
691 not used by any public broadcast network, force
692 6.5 MHz carrier to be interpreted as System DK,
693 this avoids DK audio detection instability */
694 cx25840_write(client, 0x80b, 0x00);
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300695 } else if (std & V4L2_STD_SECAM) {
Aleksandr V. Piskunov3c3099d2009-09-25 18:16:21 -0300696 /* Autodetect audio standard and audio system */
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300697 cx25840_write(client, 0x808, 0xff);
Aleksandr V. Piskunov3c3099d2009-09-25 18:16:21 -0300698 /* If only one of SECAM-DK / SECAM-L is required, then force
699 6.5MHz carrier, else autodetect it */
700 if ((std & V4L2_STD_SECAM_DK) &&
701 !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
702 /* 6.5 MHz carrier to be interpreted as System DK */
703 cx25840_write(client, 0x80b, 0x00);
704 } else if (!(std & V4L2_STD_SECAM_DK) &&
705 (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
706 /* 6.5 MHz carrier to be interpreted as System L */
707 cx25840_write(client, 0x80b, 0x08);
708 } else {
709 /* 6.5 MHz carrier to be autodetected */
710 cx25840_write(client, 0x80b, 0x10);
711 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800712 }
713
Hans Verkuil82677612007-08-07 07:16:07 -0300714 cx25840_and_or(client, 0x810, ~0x01, 0);
Hans Verkuilbd985162005-11-13 16:07:56 -0800715}
716
Hans Verkuila8bbf122006-01-09 15:25:42 -0200717static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
718 enum cx25840_audio_input aud_input)
Hans Verkuilbd985162005-11-13 16:07:56 -0800719{
Hans Verkuil9357b312008-11-29 12:50:06 -0300720 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuila8bbf122006-01-09 15:25:42 -0200721 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
722 vid_input <= CX25840_COMPOSITE8);
David T.L. Wongfb29ab92009-10-20 12:13:39 -0300723 u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
724 CX25840_COMPONENT_ON;
725 int luma = vid_input & 0xf0;
726 int chroma = vid_input & 0xf00;
Hans Verkuila8bbf122006-01-09 15:25:42 -0200727 u8 reg;
Hans Verkuilbd985162005-11-13 16:07:56 -0800728
Steven Tothf2340812008-01-10 01:22:39 -0300729 v4l_dbg(1, cx25840_debug, client,
730 "decoder set video input %d, audio input %d\n",
731 vid_input, aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800732
Steven Tothf2340812008-01-10 01:22:39 -0300733 if (vid_input >= CX25840_VIN1_CH1) {
734 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
735 vid_input);
736 reg = vid_input & 0xff;
737 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
738 is_composite = 0;
David T.L. Wongfb29ab92009-10-20 12:13:39 -0300739 else if ((vid_input & CX25840_COMPONENT_ON) == 0)
Steven Tothf2340812008-01-10 01:22:39 -0300740 is_composite = 1;
741
742 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
743 reg, is_composite);
David T.L. Wongfb29ab92009-10-20 12:13:39 -0300744 } else if (is_composite) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200745 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
746 } else {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200747 if ((vid_input & ~0xff0) ||
Hans Verkuil45270a12008-06-07 11:18:17 -0300748 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
Hans Verkuila8bbf122006-01-09 15:25:42 -0200749 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
Steven Tothf2340812008-01-10 01:22:39 -0300750 v4l_err(client, "0x%04x is not a valid video input!\n",
751 vid_input);
Hans Verkuila8bbf122006-01-09 15:25:42 -0200752 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -0800753 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200754 reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
755 if (chroma >= CX25840_SVIDEO_CHROMA7) {
756 reg &= 0x3f;
757 reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
Hans Verkuilbd985162005-11-13 16:07:56 -0800758 } else {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200759 reg &= 0xcf;
760 reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
Hans Verkuilbd985162005-11-13 16:07:56 -0800761 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200762 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800763
Steven Tothf2340812008-01-10 01:22:39 -0300764 /* The caller has previously prepared the correct routing
765 * configuration in reg (for the cx23885) so we have no
766 * need to attempt to flip bits for earlier av decoders.
767 */
Andy Walls2a03f032009-09-26 23:47:21 -0300768 if (!is_cx2388x(state) && !is_cx231xx(state)) {
Steven Tothf2340812008-01-10 01:22:39 -0300769 switch (aud_input) {
770 case CX25840_AUDIO_SERIAL:
771 /* do nothing, use serial audio input */
772 break;
773 case CX25840_AUDIO4: reg &= ~0x30; break;
774 case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
775 case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
776 case CX25840_AUDIO7: reg &= ~0xc0; break;
777 case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
Hans Verkuilbd985162005-11-13 16:07:56 -0800778
Steven Tothf2340812008-01-10 01:22:39 -0300779 default:
780 v4l_err(client, "0x%04x is not a valid audio input!\n",
781 aud_input);
782 return -EINVAL;
783 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800784 }
785
Hans Verkuila8bbf122006-01-09 15:25:42 -0200786 cx25840_write(client, 0x103, reg);
Steven Tothf2340812008-01-10 01:22:39 -0300787
David T.L. Wongfb29ab92009-10-20 12:13:39 -0300788 /* Set INPUT_MODE to Composite, S-Video or Component */
789 if (is_component)
790 cx25840_and_or(client, 0x401, ~0x6, 0x6);
791 else
792 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
Steven Tothf2340812008-01-10 01:22:39 -0300793
Andy Walls2a03f032009-09-26 23:47:21 -0300794 if (!is_cx2388x(state) && !is_cx231xx(state)) {
Steven Tothf2340812008-01-10 01:22:39 -0300795 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
796 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
797 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
798 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
799 cx25840_and_or(client, 0x102, ~0x4, 4);
800 else
801 cx25840_and_or(client, 0x102, ~0x4, 0);
802 } else {
David T.L. Wongfb29ab92009-10-20 12:13:39 -0300803 /* Set DUAL_MODE_ADC2 to 1 if component*/
804 cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
805 if (is_composite) {
Steven Tothf2340812008-01-10 01:22:39 -0300806 /* ADC2 input select channel 2 */
807 cx25840_and_or(client, 0x102, ~0x2, 0);
David T.L. Wongfb29ab92009-10-20 12:13:39 -0300808 } else if (!is_component) {
809 /* S-Video */
810 if (chroma >= CX25840_SVIDEO_CHROMA7) {
811 /* ADC2 input select channel 3 */
812 cx25840_and_or(client, 0x102, ~0x2, 2);
813 } else {
814 /* ADC2 input select channel 2 */
815 cx25840_and_or(client, 0x102, ~0x2, 0);
816 }
817 }
Steven Tothf2340812008-01-10 01:22:39 -0300818 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200819
820 state->vid_input = vid_input;
821 state->aud_input = aud_input;
Andy Walls2a03f032009-09-26 23:47:21 -0300822 if (!is_cx2583x(state)) {
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300823 cx25840_audio_set_path(client);
824 input_change(client);
825 }
Steven Tothf2340812008-01-10 01:22:39 -0300826
Andy Walls2a03f032009-09-26 23:47:21 -0300827 if (is_cx2388x(state)) {
Steven Tothf2340812008-01-10 01:22:39 -0300828 /* Audio channel 1 src : Parallel 1 */
829 cx25840_write(client, 0x124, 0x03);
830
831 /* Select AFE clock pad output source */
832 cx25840_write(client, 0x144, 0x05);
833
834 /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
835 cx25840_write(client, 0x914, 0xa0);
836
837 /* I2S_OUT_CTL:
838 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
839 * I2S_OUT_MASTER_MODE = Master
840 */
841 cx25840_write(client, 0x918, 0xa0);
842 cx25840_write(client, 0x919, 0x01);
Andy Walls2a03f032009-09-26 23:47:21 -0300843 } else if (is_cx231xx(state)) {
Sri Deevi149783b2009-03-03 06:07:42 -0300844 /* Audio channel 1 src : Parallel 1 */
845 cx25840_write(client, 0x124, 0x03);
846
847 /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
848 cx25840_write(client, 0x914, 0xa0);
849
850 /* I2S_OUT_CTL:
851 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
852 * I2S_OUT_MASTER_MODE = Master
853 */
854 cx25840_write(client, 0x918, 0xa0);
855 cx25840_write(client, 0x919, 0x01);
Steven Tothf2340812008-01-10 01:22:39 -0300856 }
857
Hans Verkuilbd985162005-11-13 16:07:56 -0800858 return 0;
859}
860
861/* ----------------------------------------------------------------------- */
862
Hans Verkuil081b4962008-04-22 14:45:51 -0300863static int set_v4lstd(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800864{
Hans Verkuil9357b312008-11-29 12:50:06 -0300865 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil081b4962008-04-22 14:45:51 -0300866 u8 fmt = 0; /* zero is autodetect */
867 u8 pal_m = 0;
Hans Verkuilbd985162005-11-13 16:07:56 -0800868
Mauro Carvalho Chehab468a0a52005-12-19 08:54:11 -0200869 /* First tests should be against specific std */
Hans Verkuil081b4962008-04-22 14:45:51 -0300870 if (state->std == V4L2_STD_NTSC_M_JP) {
871 fmt = 0x2;
872 } else if (state->std == V4L2_STD_NTSC_443) {
873 fmt = 0x3;
874 } else if (state->std == V4L2_STD_PAL_M) {
875 pal_m = 1;
876 fmt = 0x5;
877 } else if (state->std == V4L2_STD_PAL_N) {
878 fmt = 0x6;
879 } else if (state->std == V4L2_STD_PAL_Nc) {
880 fmt = 0x7;
881 } else if (state->std == V4L2_STD_PAL_60) {
882 fmt = 0x8;
Mauro Carvalho Chehab468a0a52005-12-19 08:54:11 -0200883 } else {
884 /* Then, test against generic ones */
Hans Verkuil081b4962008-04-22 14:45:51 -0300885 if (state->std & V4L2_STD_NTSC)
886 fmt = 0x1;
887 else if (state->std & V4L2_STD_PAL)
888 fmt = 0x4;
889 else if (state->std & V4L2_STD_SECAM)
890 fmt = 0xc;
Hans Verkuilbd985162005-11-13 16:07:56 -0800891 }
892
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300893 v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
894
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300895 /* Follow step 9 of section 3.16 in the cx25840 datasheet.
896 Without this PAL may display a vertical ghosting effect.
897 This happens for example with the Yuan MPC622. */
898 if (fmt >= 4 && fmt < 8) {
899 /* Set format to NTSC-M */
900 cx25840_and_or(client, 0x400, ~0xf, 1);
901 /* Turn off LCOMB */
902 cx25840_and_or(client, 0x47b, ~6, 0);
903 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800904 cx25840_and_or(client, 0x400, ~0xf, fmt);
Hans Verkuil081b4962008-04-22 14:45:51 -0300905 cx25840_and_or(client, 0x403, ~0x3, pal_m);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300906 cx25840_std_setup(client);
Andy Walls2a03f032009-09-26 23:47:21 -0300907 if (!is_cx2583x(state))
Hans Verkuil081b4962008-04-22 14:45:51 -0300908 input_change(client);
Hans Verkuilbd985162005-11-13 16:07:56 -0800909 return 0;
910}
911
Hans Verkuilbd985162005-11-13 16:07:56 -0800912/* ----------------------------------------------------------------------- */
913
Hans Verkuil9357b312008-11-29 12:50:06 -0300914static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
Hans Verkuilbd985162005-11-13 16:07:56 -0800915{
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300916 struct cx25840_state *state = to_state(sd);
Hans Verkuil9357b312008-11-29 12:50:06 -0300917 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800918
919 switch (ctrl->id) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200920 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
921 state->pvr150_workaround = ctrl->value;
922 set_input(client, state->vid_input, state->aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800923 break;
924
925 case V4L2_CID_BRIGHTNESS:
926 if (ctrl->value < 0 || ctrl->value > 255) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200927 v4l_err(client, "invalid brightness setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800928 ctrl->value);
929 return -ERANGE;
930 }
931
932 cx25840_write(client, 0x414, ctrl->value - 128);
933 break;
934
935 case V4L2_CID_CONTRAST:
936 if (ctrl->value < 0 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200937 v4l_err(client, "invalid contrast setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800938 ctrl->value);
939 return -ERANGE;
940 }
941
942 cx25840_write(client, 0x415, ctrl->value << 1);
943 break;
944
945 case V4L2_CID_SATURATION:
946 if (ctrl->value < 0 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200947 v4l_err(client, "invalid saturation setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800948 ctrl->value);
949 return -ERANGE;
950 }
951
952 cx25840_write(client, 0x420, ctrl->value << 1);
953 cx25840_write(client, 0x421, ctrl->value << 1);
954 break;
955
956 case V4L2_CID_HUE:
Hans Verkuilde6476f52009-01-29 16:09:13 -0300957 if (ctrl->value < -128 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200958 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
Hans Verkuilbd985162005-11-13 16:07:56 -0800959 return -ERANGE;
960 }
961
962 cx25840_write(client, 0x422, ctrl->value);
963 break;
964
965 case V4L2_CID_AUDIO_VOLUME:
966 case V4L2_CID_AUDIO_BASS:
967 case V4L2_CID_AUDIO_TREBLE:
968 case V4L2_CID_AUDIO_BALANCE:
969 case V4L2_CID_AUDIO_MUTE:
Andy Walls2a03f032009-09-26 23:47:21 -0300970 if (is_cx2583x(state))
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300971 return -EINVAL;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300972 return cx25840_audio_s_ctrl(sd, ctrl);
Hans Verkuil3faeeae2006-01-09 15:25:44 -0200973
974 default:
975 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -0800976 }
977
978 return 0;
979}
980
Hans Verkuil9357b312008-11-29 12:50:06 -0300981static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
Hans Verkuilbd985162005-11-13 16:07:56 -0800982{
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300983 struct cx25840_state *state = to_state(sd);
Hans Verkuil9357b312008-11-29 12:50:06 -0300984 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800985
986 switch (ctrl->id) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200987 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
988 ctrl->value = state->pvr150_workaround;
Hans Verkuilbd985162005-11-13 16:07:56 -0800989 break;
990 case V4L2_CID_BRIGHTNESS:
Hans Verkuil0de71222006-01-09 15:32:44 -0200991 ctrl->value = (s8)cx25840_read(client, 0x414) + 128;
Hans Verkuilbd985162005-11-13 16:07:56 -0800992 break;
993 case V4L2_CID_CONTRAST:
994 ctrl->value = cx25840_read(client, 0x415) >> 1;
995 break;
996 case V4L2_CID_SATURATION:
997 ctrl->value = cx25840_read(client, 0x420) >> 1;
998 break;
999 case V4L2_CID_HUE:
Hans Verkuilc5099a62006-01-09 15:32:43 -02001000 ctrl->value = (s8)cx25840_read(client, 0x422);
Hans Verkuilbd985162005-11-13 16:07:56 -08001001 break;
1002 case V4L2_CID_AUDIO_VOLUME:
1003 case V4L2_CID_AUDIO_BASS:
1004 case V4L2_CID_AUDIO_TREBLE:
1005 case V4L2_CID_AUDIO_BALANCE:
1006 case V4L2_CID_AUDIO_MUTE:
Andy Walls2a03f032009-09-26 23:47:21 -03001007 if (is_cx2583x(state))
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001008 return -EINVAL;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -03001009 return cx25840_audio_g_ctrl(sd, ctrl);
Hans Verkuilbd985162005-11-13 16:07:56 -08001010 default:
1011 return -EINVAL;
1012 }
1013
1014 return 0;
1015}
1016
1017/* ----------------------------------------------------------------------- */
1018
Hans Verkuil9357b312008-11-29 12:50:06 -03001019static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
Hans Verkuilbd985162005-11-13 16:07:56 -08001020{
1021 switch (fmt->type) {
1022 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -03001023 return cx25840_vbi_g_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -08001024 default:
1025 return -EINVAL;
1026 }
Hans Verkuilbd985162005-11-13 16:07:56 -08001027 return 0;
1028}
1029
Hans Verkuil9357b312008-11-29 12:50:06 -03001030static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
Hans Verkuilbd985162005-11-13 16:07:56 -08001031{
Hans Verkuil9357b312008-11-29 12:50:06 -03001032 struct cx25840_state *state = to_state(sd);
1033 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001034 struct v4l2_pix_format *pix;
1035 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
Hans Verkuil081b4962008-04-22 14:45:51 -03001036 int is_50Hz = !(state->std & V4L2_STD_525_60);
Hans Verkuilbd985162005-11-13 16:07:56 -08001037
1038 switch (fmt->type) {
1039 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1040 pix = &(fmt->fmt.pix);
1041
1042 Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
1043 Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
1044
1045 Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
1046 Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
1047
Servaas Vandenbergheba70d592007-04-29 16:27:30 -03001048 Vlines = pix->height + (is_50Hz ? 4 : 7);
Hans Verkuilbd985162005-11-13 16:07:56 -08001049
1050 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
1051 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
Hans Verkuilfac9e892006-01-09 15:32:40 -02001052 v4l_err(client, "%dx%d is not a valid size!\n",
Hans Verkuilbd985162005-11-13 16:07:56 -08001053 pix->width, pix->height);
1054 return -ERANGE;
1055 }
1056
1057 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
1058 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
1059 VSC &= 0x1fff;
1060
1061 if (pix->width >= 385)
1062 filter = 0;
1063 else if (pix->width > 192)
1064 filter = 1;
1065 else if (pix->width > 96)
1066 filter = 2;
1067 else
1068 filter = 3;
1069
Hans Verkuilb5fc7142006-01-11 22:41:36 -02001070 v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
Hans Verkuilbd985162005-11-13 16:07:56 -08001071 pix->width, pix->height, HSC, VSC);
1072
1073 /* HSCALE=HSC */
1074 cx25840_write(client, 0x418, HSC & 0xff);
1075 cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
1076 cx25840_write(client, 0x41a, HSC >> 16);
1077 /* VSCALE=VSC */
1078 cx25840_write(client, 0x41c, VSC & 0xff);
1079 cx25840_write(client, 0x41d, VSC >> 8);
1080 /* VS_INTRLACE=1 VFILT=filter */
1081 cx25840_write(client, 0x41e, 0x8 | filter);
1082 break;
1083
1084 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -03001085 return cx25840_vbi_s_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -08001086
1087 case V4L2_BUF_TYPE_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -03001088 return cx25840_vbi_s_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -08001089
1090 default:
1091 return -EINVAL;
1092 }
1093
1094 return 0;
1095}
1096
1097/* ----------------------------------------------------------------------- */
1098
Hans Verkuil1a392752007-09-13 11:44:47 -03001099static void log_video_status(struct i2c_client *client)
1100{
1101 static const char *const fmt_strs[] = {
1102 "0x0",
1103 "NTSC-M", "NTSC-J", "NTSC-4.43",
1104 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
1105 "0x9", "0xA", "0xB",
1106 "SECAM",
1107 "0xD", "0xE", "0xF"
1108 };
1109
Hans Verkuil9357b312008-11-29 12:50:06 -03001110 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil1a392752007-09-13 11:44:47 -03001111 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
1112 u8 gen_stat1 = cx25840_read(client, 0x40d);
1113 u8 gen_stat2 = cx25840_read(client, 0x40e);
1114 int vid_input = state->vid_input;
1115
1116 v4l_info(client, "Video signal: %spresent\n",
1117 (gen_stat2 & 0x20) ? "" : "not ");
1118 v4l_info(client, "Detected format: %s\n",
1119 fmt_strs[gen_stat1 & 0xf]);
1120
1121 v4l_info(client, "Specified standard: %s\n",
1122 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
1123
1124 if (vid_input >= CX25840_COMPOSITE1 &&
1125 vid_input <= CX25840_COMPOSITE8) {
1126 v4l_info(client, "Specified video input: Composite %d\n",
1127 vid_input - CX25840_COMPOSITE1 + 1);
1128 } else {
1129 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1130 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1131 }
1132
1133 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1134}
1135
1136/* ----------------------------------------------------------------------- */
1137
1138static void log_audio_status(struct i2c_client *client)
1139{
Hans Verkuil9357b312008-11-29 12:50:06 -03001140 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil1a392752007-09-13 11:44:47 -03001141 u8 download_ctl = cx25840_read(client, 0x803);
1142 u8 mod_det_stat0 = cx25840_read(client, 0x804);
1143 u8 mod_det_stat1 = cx25840_read(client, 0x805);
1144 u8 audio_config = cx25840_read(client, 0x808);
1145 u8 pref_mode = cx25840_read(client, 0x809);
1146 u8 afc0 = cx25840_read(client, 0x80b);
1147 u8 mute_ctl = cx25840_read(client, 0x8d3);
1148 int aud_input = state->aud_input;
1149 char *p;
1150
1151 switch (mod_det_stat0) {
1152 case 0x00: p = "mono"; break;
1153 case 0x01: p = "stereo"; break;
1154 case 0x02: p = "dual"; break;
1155 case 0x04: p = "tri"; break;
1156 case 0x10: p = "mono with SAP"; break;
1157 case 0x11: p = "stereo with SAP"; break;
1158 case 0x12: p = "dual with SAP"; break;
1159 case 0x14: p = "tri with SAP"; break;
1160 case 0xfe: p = "forced mode"; break;
1161 default: p = "not defined";
1162 }
1163 v4l_info(client, "Detected audio mode: %s\n", p);
1164
1165 switch (mod_det_stat1) {
1166 case 0x00: p = "not defined"; break;
1167 case 0x01: p = "EIAJ"; break;
1168 case 0x02: p = "A2-M"; break;
1169 case 0x03: p = "A2-BG"; break;
1170 case 0x04: p = "A2-DK1"; break;
1171 case 0x05: p = "A2-DK2"; break;
1172 case 0x06: p = "A2-DK3"; break;
1173 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
1174 case 0x08: p = "AM-L"; break;
1175 case 0x09: p = "NICAM-BG"; break;
1176 case 0x0a: p = "NICAM-DK"; break;
1177 case 0x0b: p = "NICAM-I"; break;
1178 case 0x0c: p = "NICAM-L"; break;
1179 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
1180 case 0x0e: p = "IF FM Radio"; break;
1181 case 0x0f: p = "BTSC"; break;
1182 case 0x10: p = "high-deviation FM"; break;
1183 case 0x11: p = "very high-deviation FM"; break;
1184 case 0xfd: p = "unknown audio standard"; break;
1185 case 0xfe: p = "forced audio standard"; break;
1186 case 0xff: p = "no detected audio standard"; break;
1187 default: p = "not defined";
1188 }
1189 v4l_info(client, "Detected audio standard: %s\n", p);
1190 v4l_info(client, "Audio muted: %s\n",
1191 (state->unmute_volume >= 0) ? "yes" : "no");
1192 v4l_info(client, "Audio microcontroller: %s\n",
1193 (download_ctl & 0x10) ?
1194 ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
1195
1196 switch (audio_config >> 4) {
1197 case 0x00: p = "undefined"; break;
1198 case 0x01: p = "BTSC"; break;
1199 case 0x02: p = "EIAJ"; break;
1200 case 0x03: p = "A2-M"; break;
1201 case 0x04: p = "A2-BG"; break;
1202 case 0x05: p = "A2-DK1"; break;
1203 case 0x06: p = "A2-DK2"; break;
1204 case 0x07: p = "A2-DK3"; break;
1205 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
1206 case 0x09: p = "AM-L"; break;
1207 case 0x0a: p = "NICAM-BG"; break;
1208 case 0x0b: p = "NICAM-DK"; break;
1209 case 0x0c: p = "NICAM-I"; break;
1210 case 0x0d: p = "NICAM-L"; break;
1211 case 0x0e: p = "FM radio"; break;
1212 case 0x0f: p = "automatic detection"; break;
1213 default: p = "undefined";
1214 }
1215 v4l_info(client, "Configured audio standard: %s\n", p);
1216
1217 if ((audio_config >> 4) < 0xF) {
1218 switch (audio_config & 0xF) {
1219 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
1220 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
1221 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
1222 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
1223 case 0x04: p = "STEREO"; break;
1224 case 0x05: p = "DUAL1 (AB)"; break;
1225 case 0x06: p = "DUAL2 (AC) (FM)"; break;
1226 case 0x07: p = "DUAL3 (BC) (FM)"; break;
1227 case 0x08: p = "DUAL4 (AC) (AM)"; break;
1228 case 0x09: p = "DUAL5 (BC) (AM)"; break;
1229 case 0x0a: p = "SAP"; break;
1230 default: p = "undefined";
1231 }
1232 v4l_info(client, "Configured audio mode: %s\n", p);
1233 } else {
1234 switch (audio_config & 0xF) {
1235 case 0x00: p = "BG"; break;
1236 case 0x01: p = "DK1"; break;
1237 case 0x02: p = "DK2"; break;
1238 case 0x03: p = "DK3"; break;
1239 case 0x04: p = "I"; break;
1240 case 0x05: p = "L"; break;
1241 case 0x06: p = "BTSC"; break;
1242 case 0x07: p = "EIAJ"; break;
1243 case 0x08: p = "A2-M"; break;
1244 case 0x09: p = "FM Radio"; break;
1245 case 0x0f: p = "automatic standard and mode detection"; break;
1246 default: p = "undefined";
1247 }
1248 v4l_info(client, "Configured audio system: %s\n", p);
1249 }
1250
1251 if (aud_input) {
1252 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
1253 } else {
1254 v4l_info(client, "Specified audio input: External\n");
1255 }
1256
1257 switch (pref_mode & 0xf) {
1258 case 0: p = "mono/language A"; break;
1259 case 1: p = "language B"; break;
1260 case 2: p = "language C"; break;
1261 case 3: p = "analog fallback"; break;
1262 case 4: p = "stereo"; break;
1263 case 5: p = "language AC"; break;
1264 case 6: p = "language BC"; break;
1265 case 7: p = "language AB"; break;
1266 default: p = "undefined";
1267 }
1268 v4l_info(client, "Preferred audio mode: %s\n", p);
1269
1270 if ((audio_config & 0xf) == 0xf) {
1271 switch ((afc0 >> 3) & 0x3) {
1272 case 0: p = "system DK"; break;
1273 case 1: p = "system L"; break;
1274 case 2: p = "autodetect"; break;
1275 default: p = "undefined";
1276 }
1277 v4l_info(client, "Selected 65 MHz format: %s\n", p);
1278
1279 switch (afc0 & 0x7) {
1280 case 0: p = "chroma"; break;
1281 case 1: p = "BTSC"; break;
1282 case 2: p = "EIAJ"; break;
1283 case 3: p = "A2-M"; break;
1284 case 4: p = "autodetect"; break;
1285 default: p = "undefined";
1286 }
1287 v4l_info(client, "Selected 45 MHz format: %s\n", p);
1288 }
1289}
1290
1291/* ----------------------------------------------------------------------- */
1292
Hans Verkuilcc26b072009-03-29 19:20:26 -03001293/* This load_fw operation must be called to load the driver's firmware.
Hans Verkuil6ca187a2009-01-15 05:53:18 -03001294 Without this the audio standard detection will fail and you will
1295 only get mono.
1296
1297 Since loading the firmware is often problematic when the driver is
1298 compiled into the kernel I recommend postponing calling this function
1299 until the first open of the video device. Another reason for
1300 postponing it is that loading this firmware takes a long time (seconds)
1301 due to the slow i2c bus speed. So it will speed up the boot process if
1302 you can avoid loading the fw as long as the video device isn't used. */
Hans Verkuilcc26b072009-03-29 19:20:26 -03001303static int cx25840_load_fw(struct v4l2_subdev *sd)
Hans Verkuilbd985162005-11-13 16:07:56 -08001304{
Hans Verkuil9357b312008-11-29 12:50:06 -03001305 struct cx25840_state *state = to_state(sd);
1306 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001307
1308 if (!state->is_initialized) {
Hans Verkuilcc26b072009-03-29 19:20:26 -03001309 /* initialize and load firmware */
Hans Verkuilc976bc82007-07-22 12:52:40 -03001310 state->is_initialized = 1;
Andy Walls2a03f032009-09-26 23:47:21 -03001311 if (is_cx2583x(state))
Hans Verkuilc976bc82007-07-22 12:52:40 -03001312 cx25836_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001313 else if (is_cx2388x(state))
Steven Tothf2340812008-01-10 01:22:39 -03001314 cx23885_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001315 else if (is_cx231xx(state))
Sri Deevi149783b2009-03-03 06:07:42 -03001316 cx231xx_initialize(client);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001317 else
Hans Verkuil89fc4eb2007-08-04 05:00:07 -03001318 cx25840_initialize(client);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001319 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001320 return 0;
1321}
Hans Verkuilc976bc82007-07-22 12:52:40 -03001322
Hans Verkuilbd985162005-11-13 16:07:56 -08001323#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001324static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9357b312008-11-29 12:50:06 -03001325{
1326 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001327
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001328 if (!v4l2_chip_match_i2c_client(client, &reg->match))
Hans Verkuil9357b312008-11-29 12:50:06 -03001329 return -EINVAL;
1330 if (!capable(CAP_SYS_ADMIN))
1331 return -EPERM;
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001332 reg->size = 1;
Hans Verkuil9357b312008-11-29 12:50:06 -03001333 reg->val = cx25840_read(client, reg->reg & 0x0fff);
1334 return 0;
1335}
Steven Tothf2340812008-01-10 01:22:39 -03001336
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001337static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9357b312008-11-29 12:50:06 -03001338{
1339 struct i2c_client *client = v4l2_get_subdevdata(sd);
1340
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001341 if (!v4l2_chip_match_i2c_client(client, &reg->match))
Hans Verkuil9357b312008-11-29 12:50:06 -03001342 return -EINVAL;
1343 if (!capable(CAP_SYS_ADMIN))
1344 return -EPERM;
1345 cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
1346 return 0;
1347}
Hans Verkuilbd985162005-11-13 16:07:56 -08001348#endif
1349
Andy Walls3ccc6462009-12-24 13:06:08 -03001350static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)
1351{
1352 struct cx25840_state *state = to_state(sd);
1353 struct i2c_client *client = v4l2_get_subdevdata(sd);
1354 u8 v;
1355
1356 if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))
1357 return 0;
1358
1359 v4l_dbg(1, cx25840_debug, client, "%s audio output\n",
1360 enable ? "enable" : "disable");
1361
1362 if (enable) {
1363 v = cx25840_read(client, 0x115) | 0x80;
1364 cx25840_write(client, 0x115, v);
1365 v = cx25840_read(client, 0x116) | 0x03;
1366 cx25840_write(client, 0x116, v);
1367 } else {
1368 v = cx25840_read(client, 0x115) & ~(0x80);
1369 cx25840_write(client, 0x115, v);
1370 v = cx25840_read(client, 0x116) & ~(0x03);
1371 cx25840_write(client, 0x116, v);
1372 }
1373 return 0;
1374}
1375
Hans Verkuil9357b312008-11-29 12:50:06 -03001376static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1377{
1378 struct cx25840_state *state = to_state(sd);
1379 struct i2c_client *client = v4l2_get_subdevdata(sd);
Andy Walls3ccc6462009-12-24 13:06:08 -03001380 u8 v;
Hans Verkuil9357b312008-11-29 12:50:06 -03001381
Andy Walls3ccc6462009-12-24 13:06:08 -03001382 v4l_dbg(1, cx25840_debug, client, "%s video output\n",
Hans Verkuil9357b312008-11-29 12:50:06 -03001383 enable ? "enable" : "disable");
1384 if (enable) {
Andy Walls2a03f032009-09-26 23:47:21 -03001385 if (is_cx2388x(state) || is_cx231xx(state)) {
Andy Walls3ccc6462009-12-24 13:06:08 -03001386 v = cx25840_read(client, 0x421) | 0x0b;
Steven Tothf2340812008-01-10 01:22:39 -03001387 cx25840_write(client, 0x421, v);
1388 } else {
Andy Walls3ccc6462009-12-24 13:06:08 -03001389 v = cx25840_read(client, 0x115) | 0x0c;
1390 cx25840_write(client, 0x115, v);
1391 v = cx25840_read(client, 0x116) | 0x04;
1392 cx25840_write(client, 0x116, v);
Steven Tothf2340812008-01-10 01:22:39 -03001393 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001394 } else {
Andy Walls2a03f032009-09-26 23:47:21 -03001395 if (is_cx2388x(state) || is_cx231xx(state)) {
Andy Walls3ccc6462009-12-24 13:06:08 -03001396 v = cx25840_read(client, 0x421) & ~(0x0b);
Steven Tothf2340812008-01-10 01:22:39 -03001397 cx25840_write(client, 0x421, v);
1398 } else {
Andy Walls3ccc6462009-12-24 13:06:08 -03001399 v = cx25840_read(client, 0x115) & ~(0x0c);
1400 cx25840_write(client, 0x115, v);
1401 v = cx25840_read(client, 0x116) & ~(0x04);
1402 cx25840_write(client, 0x116, v);
Steven Tothf2340812008-01-10 01:22:39 -03001403 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001404 }
1405 return 0;
1406}
1407
1408static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1409{
1410 struct cx25840_state *state = to_state(sd);
1411
1412 switch (qc->id) {
1413 case V4L2_CID_BRIGHTNESS:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001414 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
Hans Verkuil9357b312008-11-29 12:50:06 -03001415 case V4L2_CID_CONTRAST:
1416 case V4L2_CID_SATURATION:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001417 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
Hans Verkuil9357b312008-11-29 12:50:06 -03001418 case V4L2_CID_HUE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001419 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
Hans Verkuil9357b312008-11-29 12:50:06 -03001420 default:
Hans Verkuilbd985162005-11-13 16:07:56 -08001421 break;
Hans Verkuil9357b312008-11-29 12:50:06 -03001422 }
Andy Walls2a03f032009-09-26 23:47:21 -03001423 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001424 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -08001425
Hans Verkuil9357b312008-11-29 12:50:06 -03001426 switch (qc->id) {
1427 case V4L2_CID_AUDIO_VOLUME:
1428 return v4l2_ctrl_query_fill(qc, 0, 65535,
1429 65535 / 100, state->default_volume);
1430 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001431 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
Hans Verkuil9357b312008-11-29 12:50:06 -03001432 case V4L2_CID_AUDIO_BALANCE:
1433 case V4L2_CID_AUDIO_BASS:
1434 case V4L2_CID_AUDIO_TREBLE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001435 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
Hans Verkuil9357b312008-11-29 12:50:06 -03001436 default:
Hans Verkuild92c20e2006-01-09 15:32:41 -02001437 return -EINVAL;
1438 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001439 return -EINVAL;
1440}
Hans Verkuild92c20e2006-01-09 15:32:41 -02001441
Hans Verkuil9357b312008-11-29 12:50:06 -03001442static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1443{
1444 struct cx25840_state *state = to_state(sd);
1445 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001446
Hans Verkuil9357b312008-11-29 12:50:06 -03001447 if (state->radio == 0 && state->std == std)
1448 return 0;
1449 state->radio = 0;
1450 state->std = std;
1451 return set_v4lstd(client);
1452}
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001453
Hans Verkuil9357b312008-11-29 12:50:06 -03001454static int cx25840_s_radio(struct v4l2_subdev *sd)
1455{
1456 struct cx25840_state *state = to_state(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001457
Hans Verkuil9357b312008-11-29 12:50:06 -03001458 state->radio = 1;
1459 return 0;
1460}
Hans Verkuilbd985162005-11-13 16:07:56 -08001461
Hans Verkuil5325b422009-04-02 11:26:22 -03001462static int cx25840_s_video_routing(struct v4l2_subdev *sd,
1463 u32 input, u32 output, u32 config)
Hans Verkuil9357b312008-11-29 12:50:06 -03001464{
1465 struct cx25840_state *state = to_state(sd);
1466 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001467
Hans Verkuil5325b422009-04-02 11:26:22 -03001468 return set_input(client, input, state->aud_input);
Hans Verkuil9357b312008-11-29 12:50:06 -03001469}
Hans Verkuila8bbf122006-01-09 15:25:42 -02001470
Hans Verkuil5325b422009-04-02 11:26:22 -03001471static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
1472 u32 input, u32 output, u32 config)
Hans Verkuil9357b312008-11-29 12:50:06 -03001473{
1474 struct cx25840_state *state = to_state(sd);
1475 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuila8bbf122006-01-09 15:25:42 -02001476
Andy Walls2a03f032009-09-26 23:47:21 -03001477 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001478 return -EINVAL;
Hans Verkuil5325b422009-04-02 11:26:22 -03001479 return set_input(client, state->vid_input, input);
Hans Verkuil9357b312008-11-29 12:50:06 -03001480}
Hans Verkuilbd985162005-11-13 16:07:56 -08001481
Hans Verkuil9357b312008-11-29 12:50:06 -03001482static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
1483{
1484 struct cx25840_state *state = to_state(sd);
1485 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001486
Andy Walls2a03f032009-09-26 23:47:21 -03001487 if (!is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001488 input_change(client);
1489 return 0;
1490}
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001491
Hans Verkuil9357b312008-11-29 12:50:06 -03001492static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1493{
1494 struct cx25840_state *state = to_state(sd);
1495 struct i2c_client *client = v4l2_get_subdevdata(sd);
1496 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
1497 u8 mode;
1498 int val = 0;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001499
Hans Verkuil9357b312008-11-29 12:50:06 -03001500 if (state->radio)
1501 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001502
Hans Verkuil9357b312008-11-29 12:50:06 -03001503 vt->signal = vpres ? 0xffff : 0x0;
Andy Walls2a03f032009-09-26 23:47:21 -03001504 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001505 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001506
Hans Verkuil9357b312008-11-29 12:50:06 -03001507 vt->capability |=
1508 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
1509 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
Hans Verkuilbd985162005-11-13 16:07:56 -08001510
Hans Verkuil9357b312008-11-29 12:50:06 -03001511 mode = cx25840_read(client, 0x804);
Hans Verkuilbd985162005-11-13 16:07:56 -08001512
Hans Verkuil9357b312008-11-29 12:50:06 -03001513 /* get rxsubchans and audmode */
1514 if ((mode & 0xf) == 1)
1515 val |= V4L2_TUNER_SUB_STEREO;
1516 else
1517 val |= V4L2_TUNER_SUB_MONO;
Hans Verkuilbd985162005-11-13 16:07:56 -08001518
Hans Verkuil9357b312008-11-29 12:50:06 -03001519 if (mode == 2 || mode == 4)
1520 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
Hans Verkuilbd985162005-11-13 16:07:56 -08001521
Hans Verkuil9357b312008-11-29 12:50:06 -03001522 if (mode & 0x10)
1523 val |= V4L2_TUNER_SUB_SAP;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001524
Hans Verkuil9357b312008-11-29 12:50:06 -03001525 vt->rxsubchans = val;
1526 vt->audmode = state->audmode;
1527 return 0;
1528}
1529
1530static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1531{
1532 struct cx25840_state *state = to_state(sd);
1533 struct i2c_client *client = v4l2_get_subdevdata(sd);
1534
Andy Walls2a03f032009-09-26 23:47:21 -03001535 if (state->radio || is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001536 return 0;
1537
1538 switch (vt->audmode) {
Hans Verkuilbd985162005-11-13 16:07:56 -08001539 case V4L2_TUNER_MODE_MONO:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001540 /* mono -> mono
1541 stereo -> mono
1542 bilingual -> lang1 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001543 cx25840_and_or(client, 0x809, ~0xf, 0x00);
1544 break;
Hans Verkuil301e22d2006-03-18 17:15:00 -03001545 case V4L2_TUNER_MODE_STEREO:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001546 case V4L2_TUNER_MODE_LANG1:
1547 /* mono -> mono
1548 stereo -> stereo
1549 bilingual -> lang1 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001550 cx25840_and_or(client, 0x809, ~0xf, 0x04);
1551 break;
Hans Verkuil301e22d2006-03-18 17:15:00 -03001552 case V4L2_TUNER_MODE_LANG1_LANG2:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001553 /* mono -> mono
1554 stereo -> stereo
1555 bilingual -> lang1/lang2 */
1556 cx25840_and_or(client, 0x809, ~0xf, 0x07);
1557 break;
Hans Verkuilbd985162005-11-13 16:07:56 -08001558 case V4L2_TUNER_MODE_LANG2:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001559 /* mono -> mono
Hans Verkuil301e22d2006-03-18 17:15:00 -03001560 stereo -> stereo
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001561 bilingual -> lang2 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001562 cx25840_and_or(client, 0x809, ~0xf, 0x01);
1563 break;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001564 default:
1565 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -08001566 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001567 state->audmode = vt->audmode;
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001568 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001569}
1570
Hans Verkuil9357b312008-11-29 12:50:06 -03001571static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1572{
1573 struct cx25840_state *state = to_state(sd);
1574 struct i2c_client *client = v4l2_get_subdevdata(sd);
1575
Andy Walls2a03f032009-09-26 23:47:21 -03001576 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001577 cx25836_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001578 else if (is_cx2388x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001579 cx23885_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001580 else if (is_cx231xx(state))
Sri Deevi149783b2009-03-03 06:07:42 -03001581 cx231xx_initialize(client);
Hans Verkuil9357b312008-11-29 12:50:06 -03001582 else
1583 cx25840_initialize(client);
1584 return 0;
1585}
1586
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001587static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil9357b312008-11-29 12:50:06 -03001588{
1589 struct cx25840_state *state = to_state(sd);
1590 struct i2c_client *client = v4l2_get_subdevdata(sd);
1591
1592 return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
1593}
1594
1595static int cx25840_log_status(struct v4l2_subdev *sd)
1596{
1597 struct cx25840_state *state = to_state(sd);
1598 struct i2c_client *client = v4l2_get_subdevdata(sd);
1599
1600 log_video_status(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001601 if (!is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001602 log_audio_status(client);
1603 return 0;
1604}
1605
Hans Verkuil9357b312008-11-29 12:50:06 -03001606/* ----------------------------------------------------------------------- */
1607
1608static const struct v4l2_subdev_core_ops cx25840_core_ops = {
1609 .log_status = cx25840_log_status,
1610 .g_chip_ident = cx25840_g_chip_ident,
1611 .g_ctrl = cx25840_g_ctrl,
1612 .s_ctrl = cx25840_s_ctrl,
1613 .queryctrl = cx25840_queryctrl,
Hans Verkuilf41737e2009-04-01 03:52:39 -03001614 .s_std = cx25840_s_std,
Hans Verkuil9357b312008-11-29 12:50:06 -03001615 .reset = cx25840_reset,
Hans Verkuilcc26b072009-03-29 19:20:26 -03001616 .load_fw = cx25840_load_fw,
Hans Verkuil9357b312008-11-29 12:50:06 -03001617#ifdef CONFIG_VIDEO_ADV_DEBUG
1618 .g_register = cx25840_g_register,
1619 .s_register = cx25840_s_register,
1620#endif
1621};
1622
1623static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1624 .s_frequency = cx25840_s_frequency,
Hans Verkuil9357b312008-11-29 12:50:06 -03001625 .s_radio = cx25840_s_radio,
1626 .g_tuner = cx25840_g_tuner,
1627 .s_tuner = cx25840_s_tuner,
1628};
1629
1630static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1631 .s_clock_freq = cx25840_s_clock_freq,
1632 .s_routing = cx25840_s_audio_routing,
Andy Walls3ccc6462009-12-24 13:06:08 -03001633 .s_stream = cx25840_s_audio_stream,
Hans Verkuil9357b312008-11-29 12:50:06 -03001634};
1635
1636static const struct v4l2_subdev_video_ops cx25840_video_ops = {
1637 .s_routing = cx25840_s_video_routing,
1638 .g_fmt = cx25840_g_fmt,
1639 .s_fmt = cx25840_s_fmt,
1640 .decode_vbi_line = cx25840_decode_vbi_line,
1641 .s_stream = cx25840_s_stream,
1642};
1643
1644static const struct v4l2_subdev_ops cx25840_ops = {
1645 .core = &cx25840_core_ops,
1646 .tuner = &cx25840_tuner_ops,
1647 .audio = &cx25840_audio_ops,
1648 .video = &cx25840_video_ops,
1649};
1650
Hans Verkuilbd985162005-11-13 16:07:56 -08001651/* ----------------------------------------------------------------------- */
1652
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001653static u32 get_cx2388x_ident(struct i2c_client *client)
1654{
1655 u32 ret;
1656
1657 /* Come out of digital power down */
1658 cx25840_write(client, 0x000, 0);
1659
Steven Toth8c2d7822009-09-27 15:54:47 -03001660 /* Detecting whether the part is cx23885/7/8 is more
1661 * difficult than it needs to be. No ID register. Instead we
1662 * probe certain registers indicated in the datasheets to look
1663 * for specific defaults that differ between the silicon designs. */
1664
1665 /* It's either 885/7 if the IR Tx Clk Divider register exists */
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001666 if (cx25840_read4(client, 0x204) & 0xffff) {
Steven Toth8c2d7822009-09-27 15:54:47 -03001667 /* CX23885 returns bogus repetitive byte values for the DIF,
1668 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
1669 ret = cx25840_read4(client, 0x300);
1670 if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
1671 /* No DIF */
1672 ret = V4L2_IDENT_CX23885_AV;
1673 } else {
1674 /* CX23887 has a broken DIF, but the registers
1675 * appear valid (but unsed), good enough to detect. */
1676 ret = V4L2_IDENT_CX23887_AV;
1677 }
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001678 } else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
1679 /* DIF PLL Freq Word reg exists; chip must be a CX23888 */
1680 ret = V4L2_IDENT_CX23888_AV;
1681 } else {
Steven Toth8c2d7822009-09-27 15:54:47 -03001682 v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001683 ret = V4L2_IDENT_CX23887_AV;
1684 }
1685
1686 /* Back into digital power down */
1687 cx25840_write(client, 0x000, 2);
1688 return ret;
1689}
1690
Jean Delvared2653e92008-04-29 23:11:39 +02001691static int cx25840_probe(struct i2c_client *client,
1692 const struct i2c_device_id *did)
Hans Verkuilbd985162005-11-13 16:07:56 -08001693{
Hans Verkuilbd985162005-11-13 16:07:56 -08001694 struct cx25840_state *state;
Hans Verkuil9357b312008-11-29 12:50:06 -03001695 struct v4l2_subdev *sd;
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001696 u32 id = V4L2_IDENT_NONE;
Hans Verkuilbd985162005-11-13 16:07:56 -08001697 u16 device_id;
1698
Hans Verkuil188f3452007-09-16 10:47:15 -03001699 /* Check if the adapter supports the needed features */
1700 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1701 return -EIO;
1702
Hans Verkuil21340ae2007-08-26 10:53:16 -03001703 v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", client->addr << 1);
Hans Verkuilbd985162005-11-13 16:07:56 -08001704
1705 device_id = cx25840_read(client, 0x101) << 8;
1706 device_id |= cx25840_read(client, 0x100);
Steven Tothf2340812008-01-10 01:22:39 -03001707 v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id);
Hans Verkuilbd985162005-11-13 16:07:56 -08001708
1709 /* The high byte of the device ID should be
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001710 * 0x83 for the cx2583x and 0x84 for the cx2584x */
1711 if ((device_id & 0xff00) == 0x8300) {
1712 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001713 } else if ((device_id & 0xff00) == 0x8400) {
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001714 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
Hans Verkuil00ca7322009-03-13 13:36:00 -03001715 } else if (device_id == 0x0000) {
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001716 id = get_cx2388x_ident(client);
Sri Deevi149783b2009-03-03 06:07:42 -03001717 } else if ((device_id & 0xfff0) == 0x5A30) {
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001718 /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
1719 id = V4L2_IDENT_CX2310X_AV;
1720 } else if ((device_id & 0xff) == (device_id >> 8)) {
1721 v4l_err(client,
1722 "likely a confused/unresponsive cx2388[578] A/V decoder"
1723 " found @ 0x%x (%s)\n",
1724 client->addr << 1, client->adapter->name);
1725 v4l_err(client, "A method to reset it from the cx25840 driver"
1726 " software is not known at this time\n");
1727 return -ENODEV;
1728 } else {
Hans Verkuilb5fc7142006-01-11 22:41:36 -02001729 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
Hans Verkuil188f3452007-09-16 10:47:15 -03001730 return -ENODEV;
Hans Verkuilbd985162005-11-13 16:07:56 -08001731 }
1732
Hans Verkuil21340ae2007-08-26 10:53:16 -03001733 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
Hans Verkuil9357b312008-11-29 12:50:06 -03001734 if (state == NULL)
Hans Verkuil21340ae2007-08-26 10:53:16 -03001735 return -ENOMEM;
Hans Verkuil21340ae2007-08-26 10:53:16 -03001736
Hans Verkuil9357b312008-11-29 12:50:06 -03001737 sd = &state->sd;
1738 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001739 switch (id) {
1740 case V4L2_IDENT_CX23885_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001741 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
1742 client->addr << 1, client->adapter->name);
1743 break;
1744 case V4L2_IDENT_CX23887_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001745 v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
1746 client->addr << 1, client->adapter->name);
1747 break;
1748 case V4L2_IDENT_CX23888_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001749 v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
1750 client->addr << 1, client->adapter->name);
1751 break;
1752 case V4L2_IDENT_CX2310X_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001753 v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
1754 device_id, client->addr << 1, client->adapter->name);
1755 break;
1756 case V4L2_IDENT_CX25840:
1757 case V4L2_IDENT_CX25841:
1758 case V4L2_IDENT_CX25842:
1759 case V4L2_IDENT_CX25843:
1760 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1761 marking skips from 0x1 == 22 to 0x3 == 23. */
1762 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
1763 (device_id & 0xfff0) >> 4,
1764 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
1765 : (device_id & 0x0f),
1766 client->addr << 1, client->adapter->name);
1767 break;
1768 case V4L2_IDENT_CX25836:
1769 case V4L2_IDENT_CX25837:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001770 default:
1771 v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
1772 (device_id & 0xfff0) >> 4, device_id & 0x0f,
1773 client->addr << 1, client->adapter->name);
1774 break;
1775 }
Hans Verkuilbd985162005-11-13 16:07:56 -08001776
Hans Verkuil21340ae2007-08-26 10:53:16 -03001777 state->c = client;
Hans Verkuila8bbf122006-01-09 15:25:42 -02001778 state->vid_input = CX25840_COMPOSITE7;
1779 state->aud_input = CX25840_AUDIO8;
Hans Verkuil3578d3d2006-01-09 15:25:41 -02001780 state->audclk_freq = 48000;
Hans Verkuila8bbf122006-01-09 15:25:42 -02001781 state->pvr150_workaround = 0;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001782 state->audmode = V4L2_TUNER_MODE_LANG1;
Hans Verkuil87410da2007-08-05 08:00:36 -03001783 state->unmute_volume = -1;
Hans Verkuilca130ee2008-07-17 12:26:45 -03001784 state->default_volume = 228 - cx25840_read(client, 0x8d4);
1785 state->default_volume = ((state->default_volume / 2) + 23) << 9;
Christopher Neufeld3e3bf272006-05-24 10:16:45 -03001786 state->vbi_line_offset = 8;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001787 state->id = id;
Hans Verkuil3434eb72007-04-27 12:31:08 -03001788 state->rev = device_id;
Steven Tothf2340812008-01-10 01:22:39 -03001789
Hans Verkuilbd985162005-11-13 16:07:56 -08001790 return 0;
1791}
1792
Hans Verkuil1a392752007-09-13 11:44:47 -03001793static int cx25840_remove(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -08001794{
Hans Verkuil9357b312008-11-29 12:50:06 -03001795 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1796
1797 v4l2_device_unregister_subdev(sd);
1798 kfree(to_state(sd));
Hans Verkuilbd985162005-11-13 16:07:56 -08001799 return 0;
1800}
1801
Jean Delvareaf294862008-05-18 20:49:40 +02001802static const struct i2c_device_id cx25840_id[] = {
1803 { "cx25840", 0 },
1804 { }
1805};
1806MODULE_DEVICE_TABLE(i2c, cx25840_id);
1807
Hans Verkuil1a392752007-09-13 11:44:47 -03001808static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1809 .name = "cx25840",
Hans Verkuil1a392752007-09-13 11:44:47 -03001810 .probe = cx25840_probe,
1811 .remove = cx25840_remove,
Jean Delvareaf294862008-05-18 20:49:40 +02001812 .id_table = cx25840_id,
Hans Verkuilbd985162005-11-13 16:07:56 -08001813};