blob: a6446e637f1734ec926973c04abf1d9997279dfb [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
262 /* Internal Reset */
263 cx25840_and_or(client, 0x102, ~0x01, 0x01);
264 cx25840_and_or(client, 0x102, ~0x01, 0x00);
265
266 /* Stop microcontroller */
267 cx25840_and_or(client, 0x803, ~0x10, 0x00);
268
269 /* DIF in reset? */
270 cx25840_write(client, 0x398, 0);
271
272 /* Trust the default xtal, no division */
273 /* This changes for the cx23888 products */
274 cx25840_write(client, 0x2, 0x76);
275
276 /* Bring down the regulator for AUX clk */
277 cx25840_write(client, 0x1, 0x40);
278
279 /* Sys PLL frac */
280 cx25840_write4(client, 0x11c, 0x01d1744c);
281
282 /* Sys PLL int */
283 cx25840_write4(client, 0x118, 0x00000416);
284
285 /* Disable DIF bypass */
286 cx25840_write4(client, 0x33c, 0x00000001);
287
288 /* DIF Src phase inc */
289 cx25840_write4(client, 0x340, 0x0df7df83);
290
291 /* Vid PLL frac */
292 cx25840_write4(client, 0x10c, 0x01b6db7b);
293
294 /* Vid PLL int */
295 cx25840_write4(client, 0x108, 0x00000512);
296
297 /* Luma */
298 cx25840_write4(client, 0x414, 0x00107d12);
299
300 /* Chroma */
301 cx25840_write4(client, 0x420, 0x3d008282);
302
303 /* Aux PLL frac */
304 cx25840_write4(client, 0x114, 0x017dbf48);
305
306 /* Aux PLL int */
307 cx25840_write4(client, 0x110, 0x000a030e);
308
309 /* ADC2 input select */
310 cx25840_write(client, 0x102, 0x10);
311
312 /* VIN1 & VIN5 */
313 cx25840_write(client, 0x103, 0x11);
314
315 /* Enable format auto detect */
316 cx25840_write(client, 0x400, 0);
317 /* Fast subchroma lock */
318 /* White crush, Chroma AGC & Chroma Killer enabled */
319 cx25840_write(client, 0x401, 0xe8);
320
321 /* Select AFE clock pad output source */
322 cx25840_write(client, 0x144, 0x05);
323
Steven Tothf3d6f632009-07-23 12:18:54 -0300324 /* Drive GPIO2 direction and values for HVR1700
325 * where an onboard mux selects the output of demodulator
326 * vs the 417. Failure to set this results in no DTV.
327 * It's safe to set this across all Hauppauge boards
328 * currently, regardless of the board type.
329 */
330 cx25840_write(client, 0x160, 0x1d);
331 cx25840_write(client, 0x164, 0x00);
332
Steven Tothf2340812008-01-10 01:22:39 -0300333 /* Do the firmware load in a work handler to prevent.
334 Otherwise the kernel is blocked waiting for the
335 bit-banging i2c interface to finish uploading the
336 firmware. */
337 INIT_WORK(&state->fw_work, cx25840_work_handler);
338 init_waitqueue_head(&state->fw_wait);
339 q = create_singlethread_workqueue("cx25840_fw");
340 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
341 queue_work(q, &state->fw_work);
342 schedule();
343 finish_wait(&state->fw_wait, &wait);
344 destroy_workqueue(q);
345
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300346 cx25840_std_setup(client);
Steven Tothf2340812008-01-10 01:22:39 -0300347
348 /* (re)set input */
349 set_input(client, state->vid_input, state->aud_input);
350
351 /* start microcontroller */
352 cx25840_and_or(client, 0x803, ~0x10, 0x10);
353}
354
Hans Verkuilbd985162005-11-13 16:07:56 -0800355/* ----------------------------------------------------------------------- */
356
Sri Deevi149783b2009-03-03 06:07:42 -0300357static void cx231xx_initialize(struct i2c_client *client)
358{
359 DEFINE_WAIT(wait);
360 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
361 struct workqueue_struct *q;
362
363 /* Internal Reset */
364 cx25840_and_or(client, 0x102, ~0x01, 0x01);
365 cx25840_and_or(client, 0x102, ~0x01, 0x00);
366
367 /* Stop microcontroller */
368 cx25840_and_or(client, 0x803, ~0x10, 0x00);
369
370 /* DIF in reset? */
371 cx25840_write(client, 0x398, 0);
372
373 /* Trust the default xtal, no division */
374 /* This changes for the cx23888 products */
375 cx25840_write(client, 0x2, 0x76);
376
377 /* Bring down the regulator for AUX clk */
378 cx25840_write(client, 0x1, 0x40);
379
380 /* Disable DIF bypass */
381 cx25840_write4(client, 0x33c, 0x00000001);
382
383 /* DIF Src phase inc */
384 cx25840_write4(client, 0x340, 0x0df7df83);
385
Sri Deevi149783b2009-03-03 06:07:42 -0300386 /* Luma */
387 cx25840_write4(client, 0x414, 0x00107d12);
388
389 /* Chroma */
390 cx25840_write4(client, 0x420, 0x3d008282);
391
Sri Deevi149783b2009-03-03 06:07:42 -0300392 /* ADC2 input select */
393 cx25840_write(client, 0x102, 0x10);
394
395 /* VIN1 & VIN5 */
396 cx25840_write(client, 0x103, 0x11);
397
398 /* Enable format auto detect */
399 cx25840_write(client, 0x400, 0);
400 /* Fast subchroma lock */
401 /* White crush, Chroma AGC & Chroma Killer enabled */
402 cx25840_write(client, 0x401, 0xe8);
403
Sri Deevi149783b2009-03-03 06:07:42 -0300404 /* Do the firmware load in a work handler to prevent.
405 Otherwise the kernel is blocked waiting for the
406 bit-banging i2c interface to finish uploading the
407 firmware. */
408 INIT_WORK(&state->fw_work, cx25840_work_handler);
409 init_waitqueue_head(&state->fw_wait);
410 q = create_singlethread_workqueue("cx25840_fw");
411 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
412 queue_work(q, &state->fw_work);
413 schedule();
414 finish_wait(&state->fw_wait, &wait);
415 destroy_workqueue(q);
416
417 cx25840_std_setup(client);
418
419 /* (re)set input */
420 set_input(client, state->vid_input, state->aud_input);
421
422 /* start microcontroller */
423 cx25840_and_or(client, 0x803, ~0x10, 0x10);
424}
425
426/* ----------------------------------------------------------------------- */
427
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300428void cx25840_std_setup(struct i2c_client *client)
429{
Hans Verkuil9357b312008-11-29 12:50:06 -0300430 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300431 v4l2_std_id std = state->std;
432 int hblank, hactive, burst, vblank, vactive, sc;
433 int vblank656, src_decimation;
434 int luma_lpf, uv_lpf, comb;
435 u32 pll_int, pll_frac, pll_post;
436
437 /* datasheet startup, step 8d */
438 if (std & ~V4L2_STD_NTSC)
439 cx25840_write(client, 0x49f, 0x11);
440 else
441 cx25840_write(client, 0x49f, 0x14);
442
443 if (std & V4L2_STD_625_50) {
444 hblank = 132;
445 hactive = 720;
446 burst = 93;
447 vblank = 36;
448 vactive = 580;
449 vblank656 = 40;
450 src_decimation = 0x21f;
451 luma_lpf = 2;
452
453 if (std & V4L2_STD_SECAM) {
454 uv_lpf = 0;
455 comb = 0;
456 sc = 0x0a425f;
457 } else if (std == V4L2_STD_PAL_Nc) {
458 uv_lpf = 1;
459 comb = 0x20;
460 sc = 556453;
461 } else {
462 uv_lpf = 1;
463 comb = 0x20;
464 sc = 688739;
465 }
466 } else {
467 hactive = 720;
468 hblank = 122;
469 vactive = 487;
470 luma_lpf = 1;
471 uv_lpf = 1;
472
473 src_decimation = 0x21f;
474 if (std == V4L2_STD_PAL_60) {
475 vblank = 26;
476 vblank656 = 26;
477 burst = 0x5b;
478 luma_lpf = 2;
479 comb = 0x20;
480 sc = 688739;
481 } else if (std == V4L2_STD_PAL_M) {
482 vblank = 20;
483 vblank656 = 24;
484 burst = 0x61;
485 comb = 0x20;
486 sc = 555452;
487 } else {
488 vblank = 26;
489 vblank656 = 26;
490 burst = 0x5b;
491 comb = 0x66;
492 sc = 556063;
493 }
494 }
495
496 /* DEBUG: Displays configured PLL frequency */
Andy Walls2a03f032009-09-26 23:47:21 -0300497 if (!is_cx231xx(state)) {
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300498 pll_int = cx25840_read(client, 0x108);
499 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
500 pll_post = cx25840_read(client, 0x109);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300501 v4l_dbg(1, cx25840_debug, client,
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300502 "PLL regs = int: %u, frac: %u, post: %u\n",
503 pll_int, pll_frac, pll_post);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300504
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300505 if (pll_post) {
506 int fin, fsc;
507 int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300508
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300509 pll /= pll_post;
510 v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
511 pll / 1000000, pll % 1000000);
512 v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
513 pll / 8000000, (pll / 8) % 1000000);
514
515 fin = ((u64)src_decimation * pll) >> 12;
516 v4l_dbg(1, cx25840_debug, client,
517 "ADC Sampling freq = %d.%06d MHz\n",
518 fin / 1000000, fin % 1000000);
519
520 fsc = (((u64)sc) * pll) >> 24L;
521 v4l_dbg(1, cx25840_debug, client,
522 "Chroma sub-carrier freq = %d.%06d MHz\n",
523 fsc / 1000000, fsc % 1000000);
524
525 v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
526 "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
527 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
528 "sc 0x%06x\n",
529 hblank, hactive, vblank, vactive, vblank656,
530 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
531 }
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300532 }
533
534 /* Sets horizontal blanking delay and active lines */
535 cx25840_write(client, 0x470, hblank);
536 cx25840_write(client, 0x471,
537 0xff & (((hblank >> 8) & 0x3) | (hactive << 4)));
538 cx25840_write(client, 0x472, hactive >> 4);
539
540 /* Sets burst gate delay */
541 cx25840_write(client, 0x473, burst);
542
543 /* Sets vertical blanking delay and active duration */
544 cx25840_write(client, 0x474, vblank);
545 cx25840_write(client, 0x475,
546 0xff & (((vblank >> 8) & 0x3) | (vactive << 4)));
547 cx25840_write(client, 0x476, vactive >> 4);
548 cx25840_write(client, 0x477, vblank656);
549
550 /* Sets src decimation rate */
551 cx25840_write(client, 0x478, 0xff & src_decimation);
552 cx25840_write(client, 0x479, 0xff & (src_decimation >> 8));
553
554 /* Sets Luma and UV Low pass filters */
555 cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
556
557 /* Enables comb filters */
558 cx25840_write(client, 0x47b, comb);
559
560 /* Sets SC Step*/
561 cx25840_write(client, 0x47c, sc);
562 cx25840_write(client, 0x47d, 0xff & sc >> 8);
563 cx25840_write(client, 0x47e, 0xff & sc >> 16);
564
565 /* Sets VBI parameters */
566 if (std & V4L2_STD_625_50) {
567 cx25840_write(client, 0x47f, 0x01);
568 state->vbi_line_offset = 5;
569 } else {
570 cx25840_write(client, 0x47f, 0x00);
571 state->vbi_line_offset = 8;
572 }
573}
574
575/* ----------------------------------------------------------------------- */
576
Hans Verkuilbd985162005-11-13 16:07:56 -0800577static void input_change(struct i2c_client *client)
578{
Hans Verkuil9357b312008-11-29 12:50:06 -0300579 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil081b4962008-04-22 14:45:51 -0300580 v4l2_std_id std = state->std;
Hans Verkuilbd985162005-11-13 16:07:56 -0800581
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300582 /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
583 if (std & V4L2_STD_SECAM) {
584 cx25840_write(client, 0x402, 0);
585 }
586 else {
587 cx25840_write(client, 0x402, 0x04);
588 cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
589 }
590 cx25840_and_or(client, 0x401, ~0x60, 0);
591 cx25840_and_or(client, 0x401, ~0x60, 0x60);
Hans Verkuil82677612007-08-07 07:16:07 -0300592 cx25840_and_or(client, 0x810, ~0x01, 1);
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300593
Hans Verkuil39c4ad62007-08-05 14:24:17 -0300594 if (state->radio) {
595 cx25840_write(client, 0x808, 0xf9);
596 cx25840_write(client, 0x80b, 0x00);
597 }
598 else if (std & V4L2_STD_525_60) {
Hans Verkuild97a11e2006-02-07 06:48:40 -0200599 /* Certain Hauppauge PVR150 models have a hardware bug
600 that causes audio to drop out. For these models the
601 audio standard must be set explicitly.
602 To be precise: it affects cards with tuner models
603 85, 99 and 112 (model numbers from tveeprom). */
604 int hw_fix = state->pvr150_workaround;
605
606 if (std == V4L2_STD_NTSC_M_JP) {
Hans Verkuilf95006f2005-12-01 00:51:42 -0800607 /* Japan uses EIAJ audio standard */
Hans Verkuild97a11e2006-02-07 06:48:40 -0200608 cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
609 } else if (std == V4L2_STD_NTSC_M_KR) {
610 /* South Korea uses A2 audio standard */
611 cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
Hans Verkuilf95006f2005-12-01 00:51:42 -0800612 } else {
613 /* Others use the BTSC audio standard */
Hans Verkuild97a11e2006-02-07 06:48:40 -0200614 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
Hans Verkuilf95006f2005-12-01 00:51:42 -0800615 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800616 cx25840_write(client, 0x80b, 0x00);
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300617 } else if (std & V4L2_STD_PAL) {
618 /* Follow tuner change procedure for PAL */
619 cx25840_write(client, 0x808, 0xff);
620 cx25840_write(client, 0x80b, 0x10);
621 } else if (std & V4L2_STD_SECAM) {
622 /* Select autodetect for SECAM */
623 cx25840_write(client, 0x808, 0xff);
624 cx25840_write(client, 0x80b, 0x10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800625 }
626
Hans Verkuil82677612007-08-07 07:16:07 -0300627 cx25840_and_or(client, 0x810, ~0x01, 0);
Hans Verkuilbd985162005-11-13 16:07:56 -0800628}
629
Hans Verkuila8bbf122006-01-09 15:25:42 -0200630static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
631 enum cx25840_audio_input aud_input)
Hans Verkuilbd985162005-11-13 16:07:56 -0800632{
Hans Verkuil9357b312008-11-29 12:50:06 -0300633 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuila8bbf122006-01-09 15:25:42 -0200634 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
635 vid_input <= CX25840_COMPOSITE8);
636 u8 reg;
Hans Verkuilbd985162005-11-13 16:07:56 -0800637
Steven Tothf2340812008-01-10 01:22:39 -0300638 v4l_dbg(1, cx25840_debug, client,
639 "decoder set video input %d, audio input %d\n",
640 vid_input, aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800641
Steven Tothf2340812008-01-10 01:22:39 -0300642 if (vid_input >= CX25840_VIN1_CH1) {
643 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
644 vid_input);
645 reg = vid_input & 0xff;
646 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
647 is_composite = 0;
648 else
649 is_composite = 1;
650
651 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
652 reg, is_composite);
653 } else
Hans Verkuila8bbf122006-01-09 15:25:42 -0200654 if (is_composite) {
655 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
656 } else {
657 int luma = vid_input & 0xf0;
658 int chroma = vid_input & 0xf00;
Hans Verkuilbd985162005-11-13 16:07:56 -0800659
Hans Verkuila8bbf122006-01-09 15:25:42 -0200660 if ((vid_input & ~0xff0) ||
Hans Verkuil45270a12008-06-07 11:18:17 -0300661 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
Hans Verkuila8bbf122006-01-09 15:25:42 -0200662 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
Steven Tothf2340812008-01-10 01:22:39 -0300663 v4l_err(client, "0x%04x is not a valid video input!\n",
664 vid_input);
Hans Verkuila8bbf122006-01-09 15:25:42 -0200665 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -0800666 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200667 reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
668 if (chroma >= CX25840_SVIDEO_CHROMA7) {
669 reg &= 0x3f;
670 reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
Hans Verkuilbd985162005-11-13 16:07:56 -0800671 } else {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200672 reg &= 0xcf;
673 reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
Hans Verkuilbd985162005-11-13 16:07:56 -0800674 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200675 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800676
Steven Tothf2340812008-01-10 01:22:39 -0300677 /* The caller has previously prepared the correct routing
678 * configuration in reg (for the cx23885) so we have no
679 * need to attempt to flip bits for earlier av decoders.
680 */
Andy Walls2a03f032009-09-26 23:47:21 -0300681 if (!is_cx2388x(state) && !is_cx231xx(state)) {
Steven Tothf2340812008-01-10 01:22:39 -0300682 switch (aud_input) {
683 case CX25840_AUDIO_SERIAL:
684 /* do nothing, use serial audio input */
685 break;
686 case CX25840_AUDIO4: reg &= ~0x30; break;
687 case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
688 case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
689 case CX25840_AUDIO7: reg &= ~0xc0; break;
690 case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
Hans Verkuilbd985162005-11-13 16:07:56 -0800691
Steven Tothf2340812008-01-10 01:22:39 -0300692 default:
693 v4l_err(client, "0x%04x is not a valid audio input!\n",
694 aud_input);
695 return -EINVAL;
696 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800697 }
698
Hans Verkuila8bbf122006-01-09 15:25:42 -0200699 cx25840_write(client, 0x103, reg);
Steven Tothf2340812008-01-10 01:22:39 -0300700
Hans Verkuila8bbf122006-01-09 15:25:42 -0200701 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
702 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
Steven Tothf2340812008-01-10 01:22:39 -0300703
Andy Walls2a03f032009-09-26 23:47:21 -0300704 if (!is_cx2388x(state) && !is_cx231xx(state)) {
Steven Tothf2340812008-01-10 01:22:39 -0300705 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
706 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
707 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
708 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
709 cx25840_and_or(client, 0x102, ~0x4, 4);
710 else
711 cx25840_and_or(client, 0x102, ~0x4, 0);
712 } else {
713 if (is_composite)
714 /* ADC2 input select channel 2 */
715 cx25840_and_or(client, 0x102, ~0x2, 0);
716 else
717 /* ADC2 input select channel 3 */
718 cx25840_and_or(client, 0x102, ~0x2, 2);
719 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200720
721 state->vid_input = vid_input;
722 state->aud_input = aud_input;
Andy Walls2a03f032009-09-26 23:47:21 -0300723 if (!is_cx2583x(state)) {
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300724 cx25840_audio_set_path(client);
725 input_change(client);
726 }
Steven Tothf2340812008-01-10 01:22:39 -0300727
Andy Walls2a03f032009-09-26 23:47:21 -0300728 if (is_cx2388x(state)) {
Steven Tothf2340812008-01-10 01:22:39 -0300729 /* Audio channel 1 src : Parallel 1 */
730 cx25840_write(client, 0x124, 0x03);
731
732 /* Select AFE clock pad output source */
733 cx25840_write(client, 0x144, 0x05);
734
735 /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
736 cx25840_write(client, 0x914, 0xa0);
737
738 /* I2S_OUT_CTL:
739 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
740 * I2S_OUT_MASTER_MODE = Master
741 */
742 cx25840_write(client, 0x918, 0xa0);
743 cx25840_write(client, 0x919, 0x01);
Andy Walls2a03f032009-09-26 23:47:21 -0300744 } else if (is_cx231xx(state)) {
Sri Deevi149783b2009-03-03 06:07:42 -0300745 /* Audio channel 1 src : Parallel 1 */
746 cx25840_write(client, 0x124, 0x03);
747
748 /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
749 cx25840_write(client, 0x914, 0xa0);
750
751 /* I2S_OUT_CTL:
752 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
753 * I2S_OUT_MASTER_MODE = Master
754 */
755 cx25840_write(client, 0x918, 0xa0);
756 cx25840_write(client, 0x919, 0x01);
Steven Tothf2340812008-01-10 01:22:39 -0300757 }
758
Hans Verkuilbd985162005-11-13 16:07:56 -0800759 return 0;
760}
761
762/* ----------------------------------------------------------------------- */
763
Hans Verkuil081b4962008-04-22 14:45:51 -0300764static int set_v4lstd(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800765{
Hans Verkuil9357b312008-11-29 12:50:06 -0300766 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil081b4962008-04-22 14:45:51 -0300767 u8 fmt = 0; /* zero is autodetect */
768 u8 pal_m = 0;
Hans Verkuilbd985162005-11-13 16:07:56 -0800769
Mauro Carvalho Chehab468a0a52005-12-19 08:54:11 -0200770 /* First tests should be against specific std */
Hans Verkuil081b4962008-04-22 14:45:51 -0300771 if (state->std == V4L2_STD_NTSC_M_JP) {
772 fmt = 0x2;
773 } else if (state->std == V4L2_STD_NTSC_443) {
774 fmt = 0x3;
775 } else if (state->std == V4L2_STD_PAL_M) {
776 pal_m = 1;
777 fmt = 0x5;
778 } else if (state->std == V4L2_STD_PAL_N) {
779 fmt = 0x6;
780 } else if (state->std == V4L2_STD_PAL_Nc) {
781 fmt = 0x7;
782 } else if (state->std == V4L2_STD_PAL_60) {
783 fmt = 0x8;
Mauro Carvalho Chehab468a0a52005-12-19 08:54:11 -0200784 } else {
785 /* Then, test against generic ones */
Hans Verkuil081b4962008-04-22 14:45:51 -0300786 if (state->std & V4L2_STD_NTSC)
787 fmt = 0x1;
788 else if (state->std & V4L2_STD_PAL)
789 fmt = 0x4;
790 else if (state->std & V4L2_STD_SECAM)
791 fmt = 0xc;
Hans Verkuilbd985162005-11-13 16:07:56 -0800792 }
793
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300794 v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
795
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300796 /* Follow step 9 of section 3.16 in the cx25840 datasheet.
797 Without this PAL may display a vertical ghosting effect.
798 This happens for example with the Yuan MPC622. */
799 if (fmt >= 4 && fmt < 8) {
800 /* Set format to NTSC-M */
801 cx25840_and_or(client, 0x400, ~0xf, 1);
802 /* Turn off LCOMB */
803 cx25840_and_or(client, 0x47b, ~6, 0);
804 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800805 cx25840_and_or(client, 0x400, ~0xf, fmt);
Hans Verkuil081b4962008-04-22 14:45:51 -0300806 cx25840_and_or(client, 0x403, ~0x3, pal_m);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300807 cx25840_std_setup(client);
Andy Walls2a03f032009-09-26 23:47:21 -0300808 if (!is_cx2583x(state))
Hans Verkuil081b4962008-04-22 14:45:51 -0300809 input_change(client);
Hans Verkuilbd985162005-11-13 16:07:56 -0800810 return 0;
811}
812
Hans Verkuilbd985162005-11-13 16:07:56 -0800813/* ----------------------------------------------------------------------- */
814
Hans Verkuil9357b312008-11-29 12:50:06 -0300815static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
Hans Verkuilbd985162005-11-13 16:07:56 -0800816{
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300817 struct cx25840_state *state = to_state(sd);
Hans Verkuil9357b312008-11-29 12:50:06 -0300818 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800819
820 switch (ctrl->id) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200821 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
822 state->pvr150_workaround = ctrl->value;
823 set_input(client, state->vid_input, state->aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800824 break;
825
826 case V4L2_CID_BRIGHTNESS:
827 if (ctrl->value < 0 || ctrl->value > 255) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200828 v4l_err(client, "invalid brightness setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800829 ctrl->value);
830 return -ERANGE;
831 }
832
833 cx25840_write(client, 0x414, ctrl->value - 128);
834 break;
835
836 case V4L2_CID_CONTRAST:
837 if (ctrl->value < 0 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200838 v4l_err(client, "invalid contrast setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800839 ctrl->value);
840 return -ERANGE;
841 }
842
843 cx25840_write(client, 0x415, ctrl->value << 1);
844 break;
845
846 case V4L2_CID_SATURATION:
847 if (ctrl->value < 0 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200848 v4l_err(client, "invalid saturation setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800849 ctrl->value);
850 return -ERANGE;
851 }
852
853 cx25840_write(client, 0x420, ctrl->value << 1);
854 cx25840_write(client, 0x421, ctrl->value << 1);
855 break;
856
857 case V4L2_CID_HUE:
Hans Verkuilde6476f52009-01-29 16:09:13 -0300858 if (ctrl->value < -128 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200859 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
Hans Verkuilbd985162005-11-13 16:07:56 -0800860 return -ERANGE;
861 }
862
863 cx25840_write(client, 0x422, ctrl->value);
864 break;
865
866 case V4L2_CID_AUDIO_VOLUME:
867 case V4L2_CID_AUDIO_BASS:
868 case V4L2_CID_AUDIO_TREBLE:
869 case V4L2_CID_AUDIO_BALANCE:
870 case V4L2_CID_AUDIO_MUTE:
Andy Walls2a03f032009-09-26 23:47:21 -0300871 if (is_cx2583x(state))
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300872 return -EINVAL;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300873 return cx25840_audio_s_ctrl(sd, ctrl);
Hans Verkuil3faeeae2006-01-09 15:25:44 -0200874
875 default:
876 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -0800877 }
878
879 return 0;
880}
881
Hans Verkuil9357b312008-11-29 12:50:06 -0300882static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
Hans Verkuilbd985162005-11-13 16:07:56 -0800883{
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300884 struct cx25840_state *state = to_state(sd);
Hans Verkuil9357b312008-11-29 12:50:06 -0300885 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800886
887 switch (ctrl->id) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200888 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
889 ctrl->value = state->pvr150_workaround;
Hans Verkuilbd985162005-11-13 16:07:56 -0800890 break;
891 case V4L2_CID_BRIGHTNESS:
Hans Verkuil0de71222006-01-09 15:32:44 -0200892 ctrl->value = (s8)cx25840_read(client, 0x414) + 128;
Hans Verkuilbd985162005-11-13 16:07:56 -0800893 break;
894 case V4L2_CID_CONTRAST:
895 ctrl->value = cx25840_read(client, 0x415) >> 1;
896 break;
897 case V4L2_CID_SATURATION:
898 ctrl->value = cx25840_read(client, 0x420) >> 1;
899 break;
900 case V4L2_CID_HUE:
Hans Verkuilc5099a62006-01-09 15:32:43 -0200901 ctrl->value = (s8)cx25840_read(client, 0x422);
Hans Verkuilbd985162005-11-13 16:07:56 -0800902 break;
903 case V4L2_CID_AUDIO_VOLUME:
904 case V4L2_CID_AUDIO_BASS:
905 case V4L2_CID_AUDIO_TREBLE:
906 case V4L2_CID_AUDIO_BALANCE:
907 case V4L2_CID_AUDIO_MUTE:
Andy Walls2a03f032009-09-26 23:47:21 -0300908 if (is_cx2583x(state))
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300909 return -EINVAL;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300910 return cx25840_audio_g_ctrl(sd, ctrl);
Hans Verkuilbd985162005-11-13 16:07:56 -0800911 default:
912 return -EINVAL;
913 }
914
915 return 0;
916}
917
918/* ----------------------------------------------------------------------- */
919
Hans Verkuil9357b312008-11-29 12:50:06 -0300920static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
Hans Verkuilbd985162005-11-13 16:07:56 -0800921{
922 switch (fmt->type) {
923 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300924 return cx25840_vbi_g_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -0800925 default:
926 return -EINVAL;
927 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800928 return 0;
929}
930
Hans Verkuil9357b312008-11-29 12:50:06 -0300931static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
Hans Verkuilbd985162005-11-13 16:07:56 -0800932{
Hans Verkuil9357b312008-11-29 12:50:06 -0300933 struct cx25840_state *state = to_state(sd);
934 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800935 struct v4l2_pix_format *pix;
936 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
Hans Verkuil081b4962008-04-22 14:45:51 -0300937 int is_50Hz = !(state->std & V4L2_STD_525_60);
Hans Verkuilbd985162005-11-13 16:07:56 -0800938
939 switch (fmt->type) {
940 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
941 pix = &(fmt->fmt.pix);
942
943 Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
944 Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
945
946 Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
947 Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
948
Servaas Vandenbergheba70d592007-04-29 16:27:30 -0300949 Vlines = pix->height + (is_50Hz ? 4 : 7);
Hans Verkuilbd985162005-11-13 16:07:56 -0800950
951 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
952 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200953 v4l_err(client, "%dx%d is not a valid size!\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800954 pix->width, pix->height);
955 return -ERANGE;
956 }
957
958 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
959 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
960 VSC &= 0x1fff;
961
962 if (pix->width >= 385)
963 filter = 0;
964 else if (pix->width > 192)
965 filter = 1;
966 else if (pix->width > 96)
967 filter = 2;
968 else
969 filter = 3;
970
Hans Verkuilb5fc7142006-01-11 22:41:36 -0200971 v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800972 pix->width, pix->height, HSC, VSC);
973
974 /* HSCALE=HSC */
975 cx25840_write(client, 0x418, HSC & 0xff);
976 cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
977 cx25840_write(client, 0x41a, HSC >> 16);
978 /* VSCALE=VSC */
979 cx25840_write(client, 0x41c, VSC & 0xff);
980 cx25840_write(client, 0x41d, VSC >> 8);
981 /* VS_INTRLACE=1 VFILT=filter */
982 cx25840_write(client, 0x41e, 0x8 | filter);
983 break;
984
985 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300986 return cx25840_vbi_s_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -0800987
988 case V4L2_BUF_TYPE_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300989 return cx25840_vbi_s_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -0800990
991 default:
992 return -EINVAL;
993 }
994
995 return 0;
996}
997
998/* ----------------------------------------------------------------------- */
999
Hans Verkuil1a392752007-09-13 11:44:47 -03001000static void log_video_status(struct i2c_client *client)
1001{
1002 static const char *const fmt_strs[] = {
1003 "0x0",
1004 "NTSC-M", "NTSC-J", "NTSC-4.43",
1005 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
1006 "0x9", "0xA", "0xB",
1007 "SECAM",
1008 "0xD", "0xE", "0xF"
1009 };
1010
Hans Verkuil9357b312008-11-29 12:50:06 -03001011 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil1a392752007-09-13 11:44:47 -03001012 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
1013 u8 gen_stat1 = cx25840_read(client, 0x40d);
1014 u8 gen_stat2 = cx25840_read(client, 0x40e);
1015 int vid_input = state->vid_input;
1016
1017 v4l_info(client, "Video signal: %spresent\n",
1018 (gen_stat2 & 0x20) ? "" : "not ");
1019 v4l_info(client, "Detected format: %s\n",
1020 fmt_strs[gen_stat1 & 0xf]);
1021
1022 v4l_info(client, "Specified standard: %s\n",
1023 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
1024
1025 if (vid_input >= CX25840_COMPOSITE1 &&
1026 vid_input <= CX25840_COMPOSITE8) {
1027 v4l_info(client, "Specified video input: Composite %d\n",
1028 vid_input - CX25840_COMPOSITE1 + 1);
1029 } else {
1030 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1031 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1032 }
1033
1034 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1035}
1036
1037/* ----------------------------------------------------------------------- */
1038
1039static void log_audio_status(struct i2c_client *client)
1040{
Hans Verkuil9357b312008-11-29 12:50:06 -03001041 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil1a392752007-09-13 11:44:47 -03001042 u8 download_ctl = cx25840_read(client, 0x803);
1043 u8 mod_det_stat0 = cx25840_read(client, 0x804);
1044 u8 mod_det_stat1 = cx25840_read(client, 0x805);
1045 u8 audio_config = cx25840_read(client, 0x808);
1046 u8 pref_mode = cx25840_read(client, 0x809);
1047 u8 afc0 = cx25840_read(client, 0x80b);
1048 u8 mute_ctl = cx25840_read(client, 0x8d3);
1049 int aud_input = state->aud_input;
1050 char *p;
1051
1052 switch (mod_det_stat0) {
1053 case 0x00: p = "mono"; break;
1054 case 0x01: p = "stereo"; break;
1055 case 0x02: p = "dual"; break;
1056 case 0x04: p = "tri"; break;
1057 case 0x10: p = "mono with SAP"; break;
1058 case 0x11: p = "stereo with SAP"; break;
1059 case 0x12: p = "dual with SAP"; break;
1060 case 0x14: p = "tri with SAP"; break;
1061 case 0xfe: p = "forced mode"; break;
1062 default: p = "not defined";
1063 }
1064 v4l_info(client, "Detected audio mode: %s\n", p);
1065
1066 switch (mod_det_stat1) {
1067 case 0x00: p = "not defined"; break;
1068 case 0x01: p = "EIAJ"; break;
1069 case 0x02: p = "A2-M"; break;
1070 case 0x03: p = "A2-BG"; break;
1071 case 0x04: p = "A2-DK1"; break;
1072 case 0x05: p = "A2-DK2"; break;
1073 case 0x06: p = "A2-DK3"; break;
1074 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
1075 case 0x08: p = "AM-L"; break;
1076 case 0x09: p = "NICAM-BG"; break;
1077 case 0x0a: p = "NICAM-DK"; break;
1078 case 0x0b: p = "NICAM-I"; break;
1079 case 0x0c: p = "NICAM-L"; break;
1080 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
1081 case 0x0e: p = "IF FM Radio"; break;
1082 case 0x0f: p = "BTSC"; break;
1083 case 0x10: p = "high-deviation FM"; break;
1084 case 0x11: p = "very high-deviation FM"; break;
1085 case 0xfd: p = "unknown audio standard"; break;
1086 case 0xfe: p = "forced audio standard"; break;
1087 case 0xff: p = "no detected audio standard"; break;
1088 default: p = "not defined";
1089 }
1090 v4l_info(client, "Detected audio standard: %s\n", p);
1091 v4l_info(client, "Audio muted: %s\n",
1092 (state->unmute_volume >= 0) ? "yes" : "no");
1093 v4l_info(client, "Audio microcontroller: %s\n",
1094 (download_ctl & 0x10) ?
1095 ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
1096
1097 switch (audio_config >> 4) {
1098 case 0x00: p = "undefined"; break;
1099 case 0x01: p = "BTSC"; break;
1100 case 0x02: p = "EIAJ"; break;
1101 case 0x03: p = "A2-M"; break;
1102 case 0x04: p = "A2-BG"; break;
1103 case 0x05: p = "A2-DK1"; break;
1104 case 0x06: p = "A2-DK2"; break;
1105 case 0x07: p = "A2-DK3"; break;
1106 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
1107 case 0x09: p = "AM-L"; break;
1108 case 0x0a: p = "NICAM-BG"; break;
1109 case 0x0b: p = "NICAM-DK"; break;
1110 case 0x0c: p = "NICAM-I"; break;
1111 case 0x0d: p = "NICAM-L"; break;
1112 case 0x0e: p = "FM radio"; break;
1113 case 0x0f: p = "automatic detection"; break;
1114 default: p = "undefined";
1115 }
1116 v4l_info(client, "Configured audio standard: %s\n", p);
1117
1118 if ((audio_config >> 4) < 0xF) {
1119 switch (audio_config & 0xF) {
1120 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
1121 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
1122 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
1123 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
1124 case 0x04: p = "STEREO"; break;
1125 case 0x05: p = "DUAL1 (AB)"; break;
1126 case 0x06: p = "DUAL2 (AC) (FM)"; break;
1127 case 0x07: p = "DUAL3 (BC) (FM)"; break;
1128 case 0x08: p = "DUAL4 (AC) (AM)"; break;
1129 case 0x09: p = "DUAL5 (BC) (AM)"; break;
1130 case 0x0a: p = "SAP"; break;
1131 default: p = "undefined";
1132 }
1133 v4l_info(client, "Configured audio mode: %s\n", p);
1134 } else {
1135 switch (audio_config & 0xF) {
1136 case 0x00: p = "BG"; break;
1137 case 0x01: p = "DK1"; break;
1138 case 0x02: p = "DK2"; break;
1139 case 0x03: p = "DK3"; break;
1140 case 0x04: p = "I"; break;
1141 case 0x05: p = "L"; break;
1142 case 0x06: p = "BTSC"; break;
1143 case 0x07: p = "EIAJ"; break;
1144 case 0x08: p = "A2-M"; break;
1145 case 0x09: p = "FM Radio"; break;
1146 case 0x0f: p = "automatic standard and mode detection"; break;
1147 default: p = "undefined";
1148 }
1149 v4l_info(client, "Configured audio system: %s\n", p);
1150 }
1151
1152 if (aud_input) {
1153 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
1154 } else {
1155 v4l_info(client, "Specified audio input: External\n");
1156 }
1157
1158 switch (pref_mode & 0xf) {
1159 case 0: p = "mono/language A"; break;
1160 case 1: p = "language B"; break;
1161 case 2: p = "language C"; break;
1162 case 3: p = "analog fallback"; break;
1163 case 4: p = "stereo"; break;
1164 case 5: p = "language AC"; break;
1165 case 6: p = "language BC"; break;
1166 case 7: p = "language AB"; break;
1167 default: p = "undefined";
1168 }
1169 v4l_info(client, "Preferred audio mode: %s\n", p);
1170
1171 if ((audio_config & 0xf) == 0xf) {
1172 switch ((afc0 >> 3) & 0x3) {
1173 case 0: p = "system DK"; break;
1174 case 1: p = "system L"; break;
1175 case 2: p = "autodetect"; break;
1176 default: p = "undefined";
1177 }
1178 v4l_info(client, "Selected 65 MHz format: %s\n", p);
1179
1180 switch (afc0 & 0x7) {
1181 case 0: p = "chroma"; break;
1182 case 1: p = "BTSC"; break;
1183 case 2: p = "EIAJ"; break;
1184 case 3: p = "A2-M"; break;
1185 case 4: p = "autodetect"; break;
1186 default: p = "undefined";
1187 }
1188 v4l_info(client, "Selected 45 MHz format: %s\n", p);
1189 }
1190}
1191
1192/* ----------------------------------------------------------------------- */
1193
Hans Verkuilcc26b072009-03-29 19:20:26 -03001194/* This load_fw operation must be called to load the driver's firmware.
Hans Verkuil6ca187a2009-01-15 05:53:18 -03001195 Without this the audio standard detection will fail and you will
1196 only get mono.
1197
1198 Since loading the firmware is often problematic when the driver is
1199 compiled into the kernel I recommend postponing calling this function
1200 until the first open of the video device. Another reason for
1201 postponing it is that loading this firmware takes a long time (seconds)
1202 due to the slow i2c bus speed. So it will speed up the boot process if
1203 you can avoid loading the fw as long as the video device isn't used. */
Hans Verkuilcc26b072009-03-29 19:20:26 -03001204static int cx25840_load_fw(struct v4l2_subdev *sd)
Hans Verkuilbd985162005-11-13 16:07:56 -08001205{
Hans Verkuil9357b312008-11-29 12:50:06 -03001206 struct cx25840_state *state = to_state(sd);
1207 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001208
1209 if (!state->is_initialized) {
Hans Verkuilcc26b072009-03-29 19:20:26 -03001210 /* initialize and load firmware */
Hans Verkuilc976bc82007-07-22 12:52:40 -03001211 state->is_initialized = 1;
Andy Walls2a03f032009-09-26 23:47:21 -03001212 if (is_cx2583x(state))
Hans Verkuilc976bc82007-07-22 12:52:40 -03001213 cx25836_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001214 else if (is_cx2388x(state))
Steven Tothf2340812008-01-10 01:22:39 -03001215 cx23885_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001216 else if (is_cx231xx(state))
Sri Deevi149783b2009-03-03 06:07:42 -03001217 cx231xx_initialize(client);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001218 else
Hans Verkuil89fc4eb2007-08-04 05:00:07 -03001219 cx25840_initialize(client);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001220 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001221 return 0;
1222}
Hans Verkuilc976bc82007-07-22 12:52:40 -03001223
Hans Verkuilbd985162005-11-13 16:07:56 -08001224#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001225static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9357b312008-11-29 12:50:06 -03001226{
1227 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001228
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001229 if (!v4l2_chip_match_i2c_client(client, &reg->match))
Hans Verkuil9357b312008-11-29 12:50:06 -03001230 return -EINVAL;
1231 if (!capable(CAP_SYS_ADMIN))
1232 return -EPERM;
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001233 reg->size = 1;
Hans Verkuil9357b312008-11-29 12:50:06 -03001234 reg->val = cx25840_read(client, reg->reg & 0x0fff);
1235 return 0;
1236}
Steven Tothf2340812008-01-10 01:22:39 -03001237
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001238static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9357b312008-11-29 12:50:06 -03001239{
1240 struct i2c_client *client = v4l2_get_subdevdata(sd);
1241
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001242 if (!v4l2_chip_match_i2c_client(client, &reg->match))
Hans Verkuil9357b312008-11-29 12:50:06 -03001243 return -EINVAL;
1244 if (!capable(CAP_SYS_ADMIN))
1245 return -EPERM;
1246 cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
1247 return 0;
1248}
Hans Verkuilbd985162005-11-13 16:07:56 -08001249#endif
1250
Hans Verkuil9357b312008-11-29 12:50:06 -03001251static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1252{
1253 struct cx25840_state *state = to_state(sd);
1254 struct i2c_client *client = v4l2_get_subdevdata(sd);
1255
1256 v4l_dbg(1, cx25840_debug, client, "%s output\n",
1257 enable ? "enable" : "disable");
1258 if (enable) {
Andy Walls2a03f032009-09-26 23:47:21 -03001259 if (is_cx2388x(state) || is_cx231xx(state)) {
Steven Tothf2340812008-01-10 01:22:39 -03001260 u8 v = (cx25840_read(client, 0x421) | 0x0b);
1261 cx25840_write(client, 0x421, v);
1262 } else {
1263 cx25840_write(client, 0x115,
Andy Walls2a03f032009-09-26 23:47:21 -03001264 is_cx2583x(state) ? 0x0c : 0x8c);
Steven Tothf2340812008-01-10 01:22:39 -03001265 cx25840_write(client, 0x116,
Andy Walls2a03f032009-09-26 23:47:21 -03001266 is_cx2583x(state) ? 0x04 : 0x07);
Steven Tothf2340812008-01-10 01:22:39 -03001267 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001268 } else {
Andy Walls2a03f032009-09-26 23:47:21 -03001269 if (is_cx2388x(state) || is_cx231xx(state)) {
Steven Tothf2340812008-01-10 01:22:39 -03001270 u8 v = cx25840_read(client, 0x421) & ~(0x0b);
1271 cx25840_write(client, 0x421, v);
1272 } else {
1273 cx25840_write(client, 0x115, 0x00);
1274 cx25840_write(client, 0x116, 0x00);
1275 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001276 }
1277 return 0;
1278}
1279
1280static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1281{
1282 struct cx25840_state *state = to_state(sd);
1283
1284 switch (qc->id) {
1285 case V4L2_CID_BRIGHTNESS:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001286 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
Hans Verkuil9357b312008-11-29 12:50:06 -03001287 case V4L2_CID_CONTRAST:
1288 case V4L2_CID_SATURATION:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001289 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
Hans Verkuil9357b312008-11-29 12:50:06 -03001290 case V4L2_CID_HUE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001291 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
Hans Verkuil9357b312008-11-29 12:50:06 -03001292 default:
Hans Verkuilbd985162005-11-13 16:07:56 -08001293 break;
Hans Verkuil9357b312008-11-29 12:50:06 -03001294 }
Andy Walls2a03f032009-09-26 23:47:21 -03001295 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001296 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -08001297
Hans Verkuil9357b312008-11-29 12:50:06 -03001298 switch (qc->id) {
1299 case V4L2_CID_AUDIO_VOLUME:
1300 return v4l2_ctrl_query_fill(qc, 0, 65535,
1301 65535 / 100, state->default_volume);
1302 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001303 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
Hans Verkuil9357b312008-11-29 12:50:06 -03001304 case V4L2_CID_AUDIO_BALANCE:
1305 case V4L2_CID_AUDIO_BASS:
1306 case V4L2_CID_AUDIO_TREBLE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001307 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
Hans Verkuil9357b312008-11-29 12:50:06 -03001308 default:
Hans Verkuild92c20e2006-01-09 15:32:41 -02001309 return -EINVAL;
1310 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001311 return -EINVAL;
1312}
Hans Verkuild92c20e2006-01-09 15:32:41 -02001313
Hans Verkuil9357b312008-11-29 12:50:06 -03001314static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1315{
1316 struct cx25840_state *state = to_state(sd);
1317 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001318
Hans Verkuil9357b312008-11-29 12:50:06 -03001319 if (state->radio == 0 && state->std == std)
1320 return 0;
1321 state->radio = 0;
1322 state->std = std;
1323 return set_v4lstd(client);
1324}
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001325
Hans Verkuil9357b312008-11-29 12:50:06 -03001326static int cx25840_s_radio(struct v4l2_subdev *sd)
1327{
1328 struct cx25840_state *state = to_state(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001329
Hans Verkuil9357b312008-11-29 12:50:06 -03001330 state->radio = 1;
1331 return 0;
1332}
Hans Verkuilbd985162005-11-13 16:07:56 -08001333
Hans Verkuil5325b422009-04-02 11:26:22 -03001334static int cx25840_s_video_routing(struct v4l2_subdev *sd,
1335 u32 input, u32 output, u32 config)
Hans Verkuil9357b312008-11-29 12:50:06 -03001336{
1337 struct cx25840_state *state = to_state(sd);
1338 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001339
Hans Verkuil5325b422009-04-02 11:26:22 -03001340 return set_input(client, input, state->aud_input);
Hans Verkuil9357b312008-11-29 12:50:06 -03001341}
Hans Verkuila8bbf122006-01-09 15:25:42 -02001342
Hans Verkuil5325b422009-04-02 11:26:22 -03001343static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
1344 u32 input, u32 output, u32 config)
Hans Verkuil9357b312008-11-29 12:50:06 -03001345{
1346 struct cx25840_state *state = to_state(sd);
1347 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuila8bbf122006-01-09 15:25:42 -02001348
Andy Walls2a03f032009-09-26 23:47:21 -03001349 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001350 return -EINVAL;
Hans Verkuil5325b422009-04-02 11:26:22 -03001351 return set_input(client, state->vid_input, input);
Hans Verkuil9357b312008-11-29 12:50:06 -03001352}
Hans Verkuilbd985162005-11-13 16:07:56 -08001353
Hans Verkuil9357b312008-11-29 12:50:06 -03001354static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
1355{
1356 struct cx25840_state *state = to_state(sd);
1357 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001358
Andy Walls2a03f032009-09-26 23:47:21 -03001359 if (!is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001360 input_change(client);
1361 return 0;
1362}
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001363
Hans Verkuil9357b312008-11-29 12:50:06 -03001364static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1365{
1366 struct cx25840_state *state = to_state(sd);
1367 struct i2c_client *client = v4l2_get_subdevdata(sd);
1368 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
1369 u8 mode;
1370 int val = 0;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001371
Hans Verkuil9357b312008-11-29 12:50:06 -03001372 if (state->radio)
1373 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001374
Hans Verkuil9357b312008-11-29 12:50:06 -03001375 vt->signal = vpres ? 0xffff : 0x0;
Andy Walls2a03f032009-09-26 23:47:21 -03001376 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001377 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001378
Hans Verkuil9357b312008-11-29 12:50:06 -03001379 vt->capability |=
1380 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
1381 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
Hans Verkuilbd985162005-11-13 16:07:56 -08001382
Hans Verkuil9357b312008-11-29 12:50:06 -03001383 mode = cx25840_read(client, 0x804);
Hans Verkuilbd985162005-11-13 16:07:56 -08001384
Hans Verkuil9357b312008-11-29 12:50:06 -03001385 /* get rxsubchans and audmode */
1386 if ((mode & 0xf) == 1)
1387 val |= V4L2_TUNER_SUB_STEREO;
1388 else
1389 val |= V4L2_TUNER_SUB_MONO;
Hans Verkuilbd985162005-11-13 16:07:56 -08001390
Hans Verkuil9357b312008-11-29 12:50:06 -03001391 if (mode == 2 || mode == 4)
1392 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
Hans Verkuilbd985162005-11-13 16:07:56 -08001393
Hans Verkuil9357b312008-11-29 12:50:06 -03001394 if (mode & 0x10)
1395 val |= V4L2_TUNER_SUB_SAP;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001396
Hans Verkuil9357b312008-11-29 12:50:06 -03001397 vt->rxsubchans = val;
1398 vt->audmode = state->audmode;
1399 return 0;
1400}
1401
1402static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1403{
1404 struct cx25840_state *state = to_state(sd);
1405 struct i2c_client *client = v4l2_get_subdevdata(sd);
1406
Andy Walls2a03f032009-09-26 23:47:21 -03001407 if (state->radio || is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001408 return 0;
1409
1410 switch (vt->audmode) {
Hans Verkuilbd985162005-11-13 16:07:56 -08001411 case V4L2_TUNER_MODE_MONO:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001412 /* mono -> mono
1413 stereo -> mono
1414 bilingual -> lang1 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001415 cx25840_and_or(client, 0x809, ~0xf, 0x00);
1416 break;
Hans Verkuil301e22d2006-03-18 17:15:00 -03001417 case V4L2_TUNER_MODE_STEREO:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001418 case V4L2_TUNER_MODE_LANG1:
1419 /* mono -> mono
1420 stereo -> stereo
1421 bilingual -> lang1 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001422 cx25840_and_or(client, 0x809, ~0xf, 0x04);
1423 break;
Hans Verkuil301e22d2006-03-18 17:15:00 -03001424 case V4L2_TUNER_MODE_LANG1_LANG2:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001425 /* mono -> mono
1426 stereo -> stereo
1427 bilingual -> lang1/lang2 */
1428 cx25840_and_or(client, 0x809, ~0xf, 0x07);
1429 break;
Hans Verkuilbd985162005-11-13 16:07:56 -08001430 case V4L2_TUNER_MODE_LANG2:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001431 /* mono -> mono
Hans Verkuil301e22d2006-03-18 17:15:00 -03001432 stereo -> stereo
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001433 bilingual -> lang2 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001434 cx25840_and_or(client, 0x809, ~0xf, 0x01);
1435 break;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001436 default:
1437 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -08001438 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001439 state->audmode = vt->audmode;
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001440 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001441}
1442
Hans Verkuil9357b312008-11-29 12:50:06 -03001443static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1444{
1445 struct cx25840_state *state = to_state(sd);
1446 struct i2c_client *client = v4l2_get_subdevdata(sd);
1447
Andy Walls2a03f032009-09-26 23:47:21 -03001448 if (is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001449 cx25836_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001450 else if (is_cx2388x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001451 cx23885_initialize(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001452 else if (is_cx231xx(state))
Sri Deevi149783b2009-03-03 06:07:42 -03001453 cx231xx_initialize(client);
Hans Verkuil9357b312008-11-29 12:50:06 -03001454 else
1455 cx25840_initialize(client);
1456 return 0;
1457}
1458
Hans Verkuilaecde8b2008-12-30 07:14:19 -03001459static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil9357b312008-11-29 12:50:06 -03001460{
1461 struct cx25840_state *state = to_state(sd);
1462 struct i2c_client *client = v4l2_get_subdevdata(sd);
1463
1464 return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
1465}
1466
1467static int cx25840_log_status(struct v4l2_subdev *sd)
1468{
1469 struct cx25840_state *state = to_state(sd);
1470 struct i2c_client *client = v4l2_get_subdevdata(sd);
1471
1472 log_video_status(client);
Andy Walls2a03f032009-09-26 23:47:21 -03001473 if (!is_cx2583x(state))
Hans Verkuil9357b312008-11-29 12:50:06 -03001474 log_audio_status(client);
1475 return 0;
1476}
1477
Hans Verkuil9357b312008-11-29 12:50:06 -03001478/* ----------------------------------------------------------------------- */
1479
1480static const struct v4l2_subdev_core_ops cx25840_core_ops = {
1481 .log_status = cx25840_log_status,
1482 .g_chip_ident = cx25840_g_chip_ident,
1483 .g_ctrl = cx25840_g_ctrl,
1484 .s_ctrl = cx25840_s_ctrl,
1485 .queryctrl = cx25840_queryctrl,
Hans Verkuilf41737e2009-04-01 03:52:39 -03001486 .s_std = cx25840_s_std,
Hans Verkuil9357b312008-11-29 12:50:06 -03001487 .reset = cx25840_reset,
Hans Verkuilcc26b072009-03-29 19:20:26 -03001488 .load_fw = cx25840_load_fw,
Hans Verkuil9357b312008-11-29 12:50:06 -03001489#ifdef CONFIG_VIDEO_ADV_DEBUG
1490 .g_register = cx25840_g_register,
1491 .s_register = cx25840_s_register,
1492#endif
1493};
1494
1495static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1496 .s_frequency = cx25840_s_frequency,
Hans Verkuil9357b312008-11-29 12:50:06 -03001497 .s_radio = cx25840_s_radio,
1498 .g_tuner = cx25840_g_tuner,
1499 .s_tuner = cx25840_s_tuner,
1500};
1501
1502static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1503 .s_clock_freq = cx25840_s_clock_freq,
1504 .s_routing = cx25840_s_audio_routing,
1505};
1506
1507static const struct v4l2_subdev_video_ops cx25840_video_ops = {
1508 .s_routing = cx25840_s_video_routing,
1509 .g_fmt = cx25840_g_fmt,
1510 .s_fmt = cx25840_s_fmt,
1511 .decode_vbi_line = cx25840_decode_vbi_line,
1512 .s_stream = cx25840_s_stream,
1513};
1514
1515static const struct v4l2_subdev_ops cx25840_ops = {
1516 .core = &cx25840_core_ops,
1517 .tuner = &cx25840_tuner_ops,
1518 .audio = &cx25840_audio_ops,
1519 .video = &cx25840_video_ops,
1520};
1521
Hans Verkuilbd985162005-11-13 16:07:56 -08001522/* ----------------------------------------------------------------------- */
1523
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001524static u32 get_cx2388x_ident(struct i2c_client *client)
1525{
1526 u32 ret;
1527
1528 /* Come out of digital power down */
1529 cx25840_write(client, 0x000, 0);
1530
1531 if (cx25840_read4(client, 0x204) & 0xffff) {
1532 /* IR Tx Clk Divider register exists; chip must be a CX23885 */
1533 ret = V4L2_IDENT_CX23885_AV;
1534 } else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
1535 /* DIF PLL Freq Word reg exists; chip must be a CX23888 */
1536 ret = V4L2_IDENT_CX23888_AV;
1537 } else {
1538 /* A CX23887 A/V core has neither IR nor DIF */
1539 ret = V4L2_IDENT_CX23887_AV;
1540 }
1541
1542 /* Back into digital power down */
1543 cx25840_write(client, 0x000, 2);
1544 return ret;
1545}
1546
Jean Delvared2653e92008-04-29 23:11:39 +02001547static int cx25840_probe(struct i2c_client *client,
1548 const struct i2c_device_id *did)
Hans Verkuilbd985162005-11-13 16:07:56 -08001549{
Hans Verkuilbd985162005-11-13 16:07:56 -08001550 struct cx25840_state *state;
Hans Verkuil9357b312008-11-29 12:50:06 -03001551 struct v4l2_subdev *sd;
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001552 u32 id = V4L2_IDENT_NONE;
Hans Verkuilbd985162005-11-13 16:07:56 -08001553 u16 device_id;
1554
Hans Verkuil188f3452007-09-16 10:47:15 -03001555 /* Check if the adapter supports the needed features */
1556 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1557 return -EIO;
1558
Hans Verkuil21340ae2007-08-26 10:53:16 -03001559 v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", client->addr << 1);
Hans Verkuilbd985162005-11-13 16:07:56 -08001560
1561 device_id = cx25840_read(client, 0x101) << 8;
1562 device_id |= cx25840_read(client, 0x100);
Steven Tothf2340812008-01-10 01:22:39 -03001563 v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id);
Hans Verkuilbd985162005-11-13 16:07:56 -08001564
1565 /* The high byte of the device ID should be
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001566 * 0x83 for the cx2583x and 0x84 for the cx2584x */
1567 if ((device_id & 0xff00) == 0x8300) {
1568 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001569 } else if ((device_id & 0xff00) == 0x8400) {
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001570 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
Hans Verkuil00ca7322009-03-13 13:36:00 -03001571 } else if (device_id == 0x0000) {
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001572 id = get_cx2388x_ident(client);
Sri Deevi149783b2009-03-03 06:07:42 -03001573 } else if ((device_id & 0xfff0) == 0x5A30) {
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001574 /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
1575 id = V4L2_IDENT_CX2310X_AV;
1576 } else if ((device_id & 0xff) == (device_id >> 8)) {
1577 v4l_err(client,
1578 "likely a confused/unresponsive cx2388[578] A/V decoder"
1579 " found @ 0x%x (%s)\n",
1580 client->addr << 1, client->adapter->name);
1581 v4l_err(client, "A method to reset it from the cx25840 driver"
1582 " software is not known at this time\n");
1583 return -ENODEV;
1584 } else {
Hans Verkuilb5fc7142006-01-11 22:41:36 -02001585 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
Hans Verkuil188f3452007-09-16 10:47:15 -03001586 return -ENODEV;
Hans Verkuilbd985162005-11-13 16:07:56 -08001587 }
1588
Hans Verkuil21340ae2007-08-26 10:53:16 -03001589 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
Hans Verkuil9357b312008-11-29 12:50:06 -03001590 if (state == NULL)
Hans Verkuil21340ae2007-08-26 10:53:16 -03001591 return -ENOMEM;
Hans Verkuil21340ae2007-08-26 10:53:16 -03001592
Hans Verkuil9357b312008-11-29 12:50:06 -03001593 sd = &state->sd;
1594 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001595 switch (id) {
1596 case V4L2_IDENT_CX23885_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001597 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
1598 client->addr << 1, client->adapter->name);
1599 break;
1600 case V4L2_IDENT_CX23887_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001601 v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
1602 client->addr << 1, client->adapter->name);
1603 break;
1604 case V4L2_IDENT_CX23888_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001605 v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
1606 client->addr << 1, client->adapter->name);
1607 break;
1608 case V4L2_IDENT_CX2310X_AV:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001609 v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
1610 device_id, client->addr << 1, client->adapter->name);
1611 break;
1612 case V4L2_IDENT_CX25840:
1613 case V4L2_IDENT_CX25841:
1614 case V4L2_IDENT_CX25842:
1615 case V4L2_IDENT_CX25843:
1616 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1617 marking skips from 0x1 == 22 to 0x3 == 23. */
1618 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
1619 (device_id & 0xfff0) >> 4,
1620 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
1621 : (device_id & 0x0f),
1622 client->addr << 1, client->adapter->name);
1623 break;
1624 case V4L2_IDENT_CX25836:
1625 case V4L2_IDENT_CX25837:
Andy Wallsc7dd1ec2009-09-26 23:32:54 -03001626 default:
1627 v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
1628 (device_id & 0xfff0) >> 4, device_id & 0x0f,
1629 client->addr << 1, client->adapter->name);
1630 break;
1631 }
Hans Verkuilbd985162005-11-13 16:07:56 -08001632
Hans Verkuil21340ae2007-08-26 10:53:16 -03001633 state->c = client;
Hans Verkuila8bbf122006-01-09 15:25:42 -02001634 state->vid_input = CX25840_COMPOSITE7;
1635 state->aud_input = CX25840_AUDIO8;
Hans Verkuil3578d3d2006-01-09 15:25:41 -02001636 state->audclk_freq = 48000;
Hans Verkuila8bbf122006-01-09 15:25:42 -02001637 state->pvr150_workaround = 0;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001638 state->audmode = V4L2_TUNER_MODE_LANG1;
Hans Verkuil87410da2007-08-05 08:00:36 -03001639 state->unmute_volume = -1;
Hans Verkuilca130ee2008-07-17 12:26:45 -03001640 state->default_volume = 228 - cx25840_read(client, 0x8d4);
1641 state->default_volume = ((state->default_volume / 2) + 23) << 9;
Christopher Neufeld3e3bf272006-05-24 10:16:45 -03001642 state->vbi_line_offset = 8;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001643 state->id = id;
Hans Verkuil3434eb72007-04-27 12:31:08 -03001644 state->rev = device_id;
Steven Tothf2340812008-01-10 01:22:39 -03001645
Hans Verkuilbd985162005-11-13 16:07:56 -08001646 return 0;
1647}
1648
Hans Verkuil1a392752007-09-13 11:44:47 -03001649static int cx25840_remove(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -08001650{
Hans Verkuil9357b312008-11-29 12:50:06 -03001651 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1652
1653 v4l2_device_unregister_subdev(sd);
1654 kfree(to_state(sd));
Hans Verkuilbd985162005-11-13 16:07:56 -08001655 return 0;
1656}
1657
Jean Delvareaf294862008-05-18 20:49:40 +02001658static const struct i2c_device_id cx25840_id[] = {
1659 { "cx25840", 0 },
1660 { }
1661};
1662MODULE_DEVICE_TABLE(i2c, cx25840_id);
1663
Hans Verkuil1a392752007-09-13 11:44:47 -03001664static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1665 .name = "cx25840",
Hans Verkuil1a392752007-09-13 11:44:47 -03001666 .probe = cx25840_probe,
1667 .remove = cx25840_remove,
Jean Delvareaf294862008-05-18 20:49:40 +02001668 .id_table = cx25840_id,
Hans Verkuilbd985162005-11-13 16:07:56 -08001669};