blob: 9108f74c0f71ed12db3aea8dbc271a92484b94c5 [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 Verkuilb6198ade2009-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
324 /* Do the firmware load in a work handler to prevent.
325 Otherwise the kernel is blocked waiting for the
326 bit-banging i2c interface to finish uploading the
327 firmware. */
328 INIT_WORK(&state->fw_work, cx25840_work_handler);
329 init_waitqueue_head(&state->fw_wait);
330 q = create_singlethread_workqueue("cx25840_fw");
331 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
332 queue_work(q, &state->fw_work);
333 schedule();
334 finish_wait(&state->fw_wait, &wait);
335 destroy_workqueue(q);
336
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300337 cx25840_std_setup(client);
Steven Tothf2340812008-01-10 01:22:39 -0300338
339 /* (re)set input */
340 set_input(client, state->vid_input, state->aud_input);
341
342 /* start microcontroller */
343 cx25840_and_or(client, 0x803, ~0x10, 0x10);
344}
345
Hans Verkuilbd985162005-11-13 16:07:56 -0800346/* ----------------------------------------------------------------------- */
347
Sri Deevi149783b2009-03-03 06:07:42 -0300348static void cx231xx_initialize(struct i2c_client *client)
349{
350 DEFINE_WAIT(wait);
351 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
352 struct workqueue_struct *q;
353
354 /* Internal Reset */
355 cx25840_and_or(client, 0x102, ~0x01, 0x01);
356 cx25840_and_or(client, 0x102, ~0x01, 0x00);
357
358 /* Stop microcontroller */
359 cx25840_and_or(client, 0x803, ~0x10, 0x00);
360
361 /* DIF in reset? */
362 cx25840_write(client, 0x398, 0);
363
364 /* Trust the default xtal, no division */
365 /* This changes for the cx23888 products */
366 cx25840_write(client, 0x2, 0x76);
367
368 /* Bring down the regulator for AUX clk */
369 cx25840_write(client, 0x1, 0x40);
370
371 /* Disable DIF bypass */
372 cx25840_write4(client, 0x33c, 0x00000001);
373
374 /* DIF Src phase inc */
375 cx25840_write4(client, 0x340, 0x0df7df83);
376
377
378 /* Luma */
379 cx25840_write4(client, 0x414, 0x00107d12);
380
381 /* Chroma */
382 cx25840_write4(client, 0x420, 0x3d008282);
383
384
385
386 /* ADC2 input select */
387 cx25840_write(client, 0x102, 0x10);
388
389 /* VIN1 & VIN5 */
390 cx25840_write(client, 0x103, 0x11);
391
392 /* Enable format auto detect */
393 cx25840_write(client, 0x400, 0);
394 /* Fast subchroma lock */
395 /* White crush, Chroma AGC & Chroma Killer enabled */
396 cx25840_write(client, 0x401, 0xe8);
397
398
399 /* Do the firmware load in a work handler to prevent.
400 Otherwise the kernel is blocked waiting for the
401 bit-banging i2c interface to finish uploading the
402 firmware. */
403 INIT_WORK(&state->fw_work, cx25840_work_handler);
404 init_waitqueue_head(&state->fw_wait);
405 q = create_singlethread_workqueue("cx25840_fw");
406 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
407 queue_work(q, &state->fw_work);
408 schedule();
409 finish_wait(&state->fw_wait, &wait);
410 destroy_workqueue(q);
411
412 cx25840_std_setup(client);
413
414 /* (re)set input */
415 set_input(client, state->vid_input, state->aud_input);
416
417 /* start microcontroller */
418 cx25840_and_or(client, 0x803, ~0x10, 0x10);
419}
420
421/* ----------------------------------------------------------------------- */
422
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300423void cx25840_std_setup(struct i2c_client *client)
424{
Hans Verkuil9357b312008-11-29 12:50:06 -0300425 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300426 v4l2_std_id std = state->std;
427 int hblank, hactive, burst, vblank, vactive, sc;
428 int vblank656, src_decimation;
429 int luma_lpf, uv_lpf, comb;
430 u32 pll_int, pll_frac, pll_post;
431
432 /* datasheet startup, step 8d */
433 if (std & ~V4L2_STD_NTSC)
434 cx25840_write(client, 0x49f, 0x11);
435 else
436 cx25840_write(client, 0x49f, 0x14);
437
438 if (std & V4L2_STD_625_50) {
439 hblank = 132;
440 hactive = 720;
441 burst = 93;
442 vblank = 36;
443 vactive = 580;
444 vblank656 = 40;
445 src_decimation = 0x21f;
446 luma_lpf = 2;
447
448 if (std & V4L2_STD_SECAM) {
449 uv_lpf = 0;
450 comb = 0;
451 sc = 0x0a425f;
452 } else if (std == V4L2_STD_PAL_Nc) {
453 uv_lpf = 1;
454 comb = 0x20;
455 sc = 556453;
456 } else {
457 uv_lpf = 1;
458 comb = 0x20;
459 sc = 688739;
460 }
461 } else {
462 hactive = 720;
463 hblank = 122;
464 vactive = 487;
465 luma_lpf = 1;
466 uv_lpf = 1;
467
468 src_decimation = 0x21f;
469 if (std == V4L2_STD_PAL_60) {
470 vblank = 26;
471 vblank656 = 26;
472 burst = 0x5b;
473 luma_lpf = 2;
474 comb = 0x20;
475 sc = 688739;
476 } else if (std == V4L2_STD_PAL_M) {
477 vblank = 20;
478 vblank656 = 24;
479 burst = 0x61;
480 comb = 0x20;
481 sc = 555452;
482 } else {
483 vblank = 26;
484 vblank656 = 26;
485 burst = 0x5b;
486 comb = 0x66;
487 sc = 556063;
488 }
489 }
490
491 /* DEBUG: Displays configured PLL frequency */
Sri Deevi149783b2009-03-03 06:07:42 -0300492 if (!state->is_cx231xx) {
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300493 pll_int = cx25840_read(client, 0x108);
494 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
495 pll_post = cx25840_read(client, 0x109);
496 v4l_dbg(1, cx25840_debug, client,
497 "PLL regs = int: %u, frac: %u, post: %u\n",
498 pll_int, pll_frac, pll_post);
499
500 if (pll_post) {
501 int fin, fsc;
502 int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
503
504 pll /= pll_post;
505 v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
506 pll / 1000000, pll % 1000000);
507 v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
508 pll / 8000000, (pll / 8) % 1000000);
509
510 fin = ((u64)src_decimation * pll) >> 12;
511 v4l_dbg(1, cx25840_debug, client,
512 "ADC Sampling freq = %d.%06d MHz\n",
513 fin / 1000000, fin % 1000000);
514
515 fsc = (((u64)sc) * pll) >> 24L;
516 v4l_dbg(1, cx25840_debug, client,
517 "Chroma sub-carrier freq = %d.%06d MHz\n",
518 fsc / 1000000, fsc % 1000000);
519
520 v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
521 "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
522 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
523 "sc 0x%06x\n",
524 hblank, hactive, vblank, vactive, vblank656,
525 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
526 }
Sri Deevi149783b2009-03-03 06:07:42 -0300527 }
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300528
529 /* Sets horizontal blanking delay and active lines */
530 cx25840_write(client, 0x470, hblank);
531 cx25840_write(client, 0x471,
532 0xff & (((hblank >> 8) & 0x3) | (hactive << 4)));
533 cx25840_write(client, 0x472, hactive >> 4);
534
535 /* Sets burst gate delay */
536 cx25840_write(client, 0x473, burst);
537
538 /* Sets vertical blanking delay and active duration */
539 cx25840_write(client, 0x474, vblank);
540 cx25840_write(client, 0x475,
541 0xff & (((vblank >> 8) & 0x3) | (vactive << 4)));
542 cx25840_write(client, 0x476, vactive >> 4);
543 cx25840_write(client, 0x477, vblank656);
544
545 /* Sets src decimation rate */
546 cx25840_write(client, 0x478, 0xff & src_decimation);
547 cx25840_write(client, 0x479, 0xff & (src_decimation >> 8));
548
549 /* Sets Luma and UV Low pass filters */
550 cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
551
552 /* Enables comb filters */
553 cx25840_write(client, 0x47b, comb);
554
555 /* Sets SC Step*/
556 cx25840_write(client, 0x47c, sc);
557 cx25840_write(client, 0x47d, 0xff & sc >> 8);
558 cx25840_write(client, 0x47e, 0xff & sc >> 16);
559
560 /* Sets VBI parameters */
561 if (std & V4L2_STD_625_50) {
562 cx25840_write(client, 0x47f, 0x01);
563 state->vbi_line_offset = 5;
564 } else {
565 cx25840_write(client, 0x47f, 0x00);
566 state->vbi_line_offset = 8;
567 }
568}
569
570/* ----------------------------------------------------------------------- */
571
Hans Verkuilbd985162005-11-13 16:07:56 -0800572static void input_change(struct i2c_client *client)
573{
Hans Verkuil9357b312008-11-29 12:50:06 -0300574 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil081b4962008-04-22 14:45:51 -0300575 v4l2_std_id std = state->std;
Hans Verkuilbd985162005-11-13 16:07:56 -0800576
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300577 /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
578 if (std & V4L2_STD_SECAM) {
579 cx25840_write(client, 0x402, 0);
580 }
581 else {
582 cx25840_write(client, 0x402, 0x04);
583 cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
584 }
585 cx25840_and_or(client, 0x401, ~0x60, 0);
586 cx25840_and_or(client, 0x401, ~0x60, 0x60);
Hans Verkuil82677612007-08-07 07:16:07 -0300587 cx25840_and_or(client, 0x810, ~0x01, 1);
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300588
Hans Verkuil39c4ad62007-08-05 14:24:17 -0300589 if (state->radio) {
590 cx25840_write(client, 0x808, 0xf9);
591 cx25840_write(client, 0x80b, 0x00);
592 }
593 else if (std & V4L2_STD_525_60) {
Hans Verkuild97a11e2006-02-07 06:48:40 -0200594 /* Certain Hauppauge PVR150 models have a hardware bug
595 that causes audio to drop out. For these models the
596 audio standard must be set explicitly.
597 To be precise: it affects cards with tuner models
598 85, 99 and 112 (model numbers from tveeprom). */
599 int hw_fix = state->pvr150_workaround;
600
601 if (std == V4L2_STD_NTSC_M_JP) {
Hans Verkuilf95006f2005-12-01 00:51:42 -0800602 /* Japan uses EIAJ audio standard */
Hans Verkuild97a11e2006-02-07 06:48:40 -0200603 cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
604 } else if (std == V4L2_STD_NTSC_M_KR) {
605 /* South Korea uses A2 audio standard */
606 cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
Hans Verkuilf95006f2005-12-01 00:51:42 -0800607 } else {
608 /* Others use the BTSC audio standard */
Hans Verkuild97a11e2006-02-07 06:48:40 -0200609 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
Hans Verkuilf95006f2005-12-01 00:51:42 -0800610 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800611 cx25840_write(client, 0x80b, 0x00);
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300612 } else if (std & V4L2_STD_PAL) {
613 /* Follow tuner change procedure for PAL */
614 cx25840_write(client, 0x808, 0xff);
615 cx25840_write(client, 0x80b, 0x10);
616 } else if (std & V4L2_STD_SECAM) {
617 /* Select autodetect for SECAM */
618 cx25840_write(client, 0x808, 0xff);
619 cx25840_write(client, 0x80b, 0x10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800620 }
621
Hans Verkuil82677612007-08-07 07:16:07 -0300622 cx25840_and_or(client, 0x810, ~0x01, 0);
Hans Verkuilbd985162005-11-13 16:07:56 -0800623}
624
Hans Verkuila8bbf122006-01-09 15:25:42 -0200625static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
626 enum cx25840_audio_input aud_input)
Hans Verkuilbd985162005-11-13 16:07:56 -0800627{
Hans Verkuil9357b312008-11-29 12:50:06 -0300628 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuila8bbf122006-01-09 15:25:42 -0200629 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
630 vid_input <= CX25840_COMPOSITE8);
631 u8 reg;
Hans Verkuilbd985162005-11-13 16:07:56 -0800632
Steven Tothf2340812008-01-10 01:22:39 -0300633 v4l_dbg(1, cx25840_debug, client,
634 "decoder set video input %d, audio input %d\n",
635 vid_input, aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800636
Steven Tothf2340812008-01-10 01:22:39 -0300637 if (vid_input >= CX25840_VIN1_CH1) {
638 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
639 vid_input);
640 reg = vid_input & 0xff;
641 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
642 is_composite = 0;
643 else
644 is_composite = 1;
645
646 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
647 reg, is_composite);
648 } else
Hans Verkuila8bbf122006-01-09 15:25:42 -0200649 if (is_composite) {
650 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
651 } else {
652 int luma = vid_input & 0xf0;
653 int chroma = vid_input & 0xf00;
Hans Verkuilbd985162005-11-13 16:07:56 -0800654
Hans Verkuila8bbf122006-01-09 15:25:42 -0200655 if ((vid_input & ~0xff0) ||
Hans Verkuil45270a12008-06-07 11:18:17 -0300656 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
Hans Verkuila8bbf122006-01-09 15:25:42 -0200657 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
Steven Tothf2340812008-01-10 01:22:39 -0300658 v4l_err(client, "0x%04x is not a valid video input!\n",
659 vid_input);
Hans Verkuila8bbf122006-01-09 15:25:42 -0200660 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -0800661 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200662 reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
663 if (chroma >= CX25840_SVIDEO_CHROMA7) {
664 reg &= 0x3f;
665 reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
Hans Verkuilbd985162005-11-13 16:07:56 -0800666 } else {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200667 reg &= 0xcf;
668 reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
Hans Verkuilbd985162005-11-13 16:07:56 -0800669 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200670 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800671
Steven Tothf2340812008-01-10 01:22:39 -0300672 /* The caller has previously prepared the correct routing
673 * configuration in reg (for the cx23885) so we have no
674 * need to attempt to flip bits for earlier av decoders.
675 */
Sri Deevi149783b2009-03-03 06:07:42 -0300676 if (!state->is_cx23885 && !state->is_cx231xx) {
Steven Tothf2340812008-01-10 01:22:39 -0300677 switch (aud_input) {
678 case CX25840_AUDIO_SERIAL:
679 /* do nothing, use serial audio input */
680 break;
681 case CX25840_AUDIO4: reg &= ~0x30; break;
682 case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
683 case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
684 case CX25840_AUDIO7: reg &= ~0xc0; break;
685 case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
Hans Verkuilbd985162005-11-13 16:07:56 -0800686
Steven Tothf2340812008-01-10 01:22:39 -0300687 default:
688 v4l_err(client, "0x%04x is not a valid audio input!\n",
689 aud_input);
690 return -EINVAL;
691 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800692 }
693
Hans Verkuila8bbf122006-01-09 15:25:42 -0200694 cx25840_write(client, 0x103, reg);
Steven Tothf2340812008-01-10 01:22:39 -0300695
Hans Verkuila8bbf122006-01-09 15:25:42 -0200696 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
697 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
Steven Tothf2340812008-01-10 01:22:39 -0300698
Sri Deevi149783b2009-03-03 06:07:42 -0300699 if (!state->is_cx23885 && !state->is_cx231xx) {
Steven Tothf2340812008-01-10 01:22:39 -0300700 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
701 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
702 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
703 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
704 cx25840_and_or(client, 0x102, ~0x4, 4);
705 else
706 cx25840_and_or(client, 0x102, ~0x4, 0);
707 } else {
708 if (is_composite)
709 /* ADC2 input select channel 2 */
710 cx25840_and_or(client, 0x102, ~0x2, 0);
711 else
712 /* ADC2 input select channel 3 */
713 cx25840_and_or(client, 0x102, ~0x2, 2);
714 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200715
716 state->vid_input = vid_input;
717 state->aud_input = aud_input;
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300718 if (!state->is_cx25836) {
719 cx25840_audio_set_path(client);
720 input_change(client);
721 }
Steven Tothf2340812008-01-10 01:22:39 -0300722
723 if (state->is_cx23885) {
724 /* Audio channel 1 src : Parallel 1 */
725 cx25840_write(client, 0x124, 0x03);
726
727 /* Select AFE clock pad output source */
728 cx25840_write(client, 0x144, 0x05);
729
730 /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
731 cx25840_write(client, 0x914, 0xa0);
732
733 /* I2S_OUT_CTL:
734 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
735 * I2S_OUT_MASTER_MODE = Master
736 */
737 cx25840_write(client, 0x918, 0xa0);
738 cx25840_write(client, 0x919, 0x01);
Sri Deevi149783b2009-03-03 06:07:42 -0300739 } else if (state->is_cx231xx) {
740 /* Audio channel 1 src : Parallel 1 */
741 cx25840_write(client, 0x124, 0x03);
742
743 /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
744 cx25840_write(client, 0x914, 0xa0);
745
746 /* I2S_OUT_CTL:
747 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
748 * I2S_OUT_MASTER_MODE = Master
749 */
750 cx25840_write(client, 0x918, 0xa0);
751 cx25840_write(client, 0x919, 0x01);
Steven Tothf2340812008-01-10 01:22:39 -0300752 }
753
Hans Verkuilbd985162005-11-13 16:07:56 -0800754 return 0;
755}
756
757/* ----------------------------------------------------------------------- */
758
Hans Verkuil081b4962008-04-22 14:45:51 -0300759static int set_v4lstd(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800760{
Hans Verkuil9357b312008-11-29 12:50:06 -0300761 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil081b4962008-04-22 14:45:51 -0300762 u8 fmt = 0; /* zero is autodetect */
763 u8 pal_m = 0;
Hans Verkuilbd985162005-11-13 16:07:56 -0800764
Mauro Carvalho Chehab468a0a52005-12-19 08:54:11 -0200765 /* First tests should be against specific std */
Hans Verkuil081b4962008-04-22 14:45:51 -0300766 if (state->std == V4L2_STD_NTSC_M_JP) {
767 fmt = 0x2;
768 } else if (state->std == V4L2_STD_NTSC_443) {
769 fmt = 0x3;
770 } else if (state->std == V4L2_STD_PAL_M) {
771 pal_m = 1;
772 fmt = 0x5;
773 } else if (state->std == V4L2_STD_PAL_N) {
774 fmt = 0x6;
775 } else if (state->std == V4L2_STD_PAL_Nc) {
776 fmt = 0x7;
777 } else if (state->std == V4L2_STD_PAL_60) {
778 fmt = 0x8;
Mauro Carvalho Chehab468a0a52005-12-19 08:54:11 -0200779 } else {
780 /* Then, test against generic ones */
Hans Verkuil081b4962008-04-22 14:45:51 -0300781 if (state->std & V4L2_STD_NTSC)
782 fmt = 0x1;
783 else if (state->std & V4L2_STD_PAL)
784 fmt = 0x4;
785 else if (state->std & V4L2_STD_SECAM)
786 fmt = 0xc;
Hans Verkuilbd985162005-11-13 16:07:56 -0800787 }
788
Mauro Carvalho Chehab839e4a42006-06-04 12:15:55 -0300789 v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
790
Hans Verkuil73dcddc2006-03-16 20:23:47 -0300791 /* Follow step 9 of section 3.16 in the cx25840 datasheet.
792 Without this PAL may display a vertical ghosting effect.
793 This happens for example with the Yuan MPC622. */
794 if (fmt >= 4 && fmt < 8) {
795 /* Set format to NTSC-M */
796 cx25840_and_or(client, 0x400, ~0xf, 1);
797 /* Turn off LCOMB */
798 cx25840_and_or(client, 0x47b, ~6, 0);
799 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800800 cx25840_and_or(client, 0x400, ~0xf, fmt);
Hans Verkuil081b4962008-04-22 14:45:51 -0300801 cx25840_and_or(client, 0x403, ~0x3, pal_m);
Hans Verkuilcb5aa1c2008-07-17 11:08:40 -0300802 cx25840_std_setup(client);
Hans Verkuil081b4962008-04-22 14:45:51 -0300803 if (!state->is_cx25836)
804 input_change(client);
Hans Verkuilbd985162005-11-13 16:07:56 -0800805 return 0;
806}
807
Hans Verkuilbd985162005-11-13 16:07:56 -0800808/* ----------------------------------------------------------------------- */
809
Hans Verkuil9357b312008-11-29 12:50:06 -0300810static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
Hans Verkuilbd985162005-11-13 16:07:56 -0800811{
Sri Deevi149783b2009-03-03 06:07:42 -0300812 struct cx25840_state *state = to_state(sd);
Hans Verkuil9357b312008-11-29 12:50:06 -0300813 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800814
815 switch (ctrl->id) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200816 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
817 state->pvr150_workaround = ctrl->value;
818 set_input(client, state->vid_input, state->aud_input);
Hans Verkuilbd985162005-11-13 16:07:56 -0800819 break;
820
821 case V4L2_CID_BRIGHTNESS:
822 if (ctrl->value < 0 || ctrl->value > 255) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200823 v4l_err(client, "invalid brightness setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800824 ctrl->value);
825 return -ERANGE;
826 }
827
828 cx25840_write(client, 0x414, ctrl->value - 128);
829 break;
830
831 case V4L2_CID_CONTRAST:
832 if (ctrl->value < 0 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200833 v4l_err(client, "invalid contrast setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800834 ctrl->value);
835 return -ERANGE;
836 }
837
838 cx25840_write(client, 0x415, ctrl->value << 1);
839 break;
840
841 case V4L2_CID_SATURATION:
842 if (ctrl->value < 0 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200843 v4l_err(client, "invalid saturation setting %d\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800844 ctrl->value);
845 return -ERANGE;
846 }
847
848 cx25840_write(client, 0x420, ctrl->value << 1);
849 cx25840_write(client, 0x421, ctrl->value << 1);
850 break;
851
852 case V4L2_CID_HUE:
Hans Verkuilde6476f52009-01-29 16:09:13 -0300853 if (ctrl->value < -128 || ctrl->value > 127) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200854 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
Hans Verkuilbd985162005-11-13 16:07:56 -0800855 return -ERANGE;
856 }
857
858 cx25840_write(client, 0x422, ctrl->value);
859 break;
860
861 case V4L2_CID_AUDIO_VOLUME:
862 case V4L2_CID_AUDIO_BASS:
863 case V4L2_CID_AUDIO_TREBLE:
864 case V4L2_CID_AUDIO_BALANCE:
865 case V4L2_CID_AUDIO_MUTE:
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300866 if (state->is_cx25836)
867 return -EINVAL;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300868 return cx25840_audio_s_ctrl(sd, ctrl);
Hans Verkuil3faeeae2006-01-09 15:25:44 -0200869
870 default:
871 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -0800872 }
873
874 return 0;
875}
876
Hans Verkuil9357b312008-11-29 12:50:06 -0300877static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
Hans Verkuilbd985162005-11-13 16:07:56 -0800878{
Sri Deevi149783b2009-03-03 06:07:42 -0300879 struct cx25840_state *state = to_state(sd);
Hans Verkuil9357b312008-11-29 12:50:06 -0300880 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800881
882 switch (ctrl->id) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200883 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
884 ctrl->value = state->pvr150_workaround;
Hans Verkuilbd985162005-11-13 16:07:56 -0800885 break;
886 case V4L2_CID_BRIGHTNESS:
Hans Verkuil0de71222006-01-09 15:32:44 -0200887 ctrl->value = (s8)cx25840_read(client, 0x414) + 128;
Hans Verkuilbd985162005-11-13 16:07:56 -0800888 break;
889 case V4L2_CID_CONTRAST:
890 ctrl->value = cx25840_read(client, 0x415) >> 1;
891 break;
892 case V4L2_CID_SATURATION:
893 ctrl->value = cx25840_read(client, 0x420) >> 1;
894 break;
895 case V4L2_CID_HUE:
Hans Verkuilc5099a62006-01-09 15:32:43 -0200896 ctrl->value = (s8)cx25840_read(client, 0x422);
Hans Verkuilbd985162005-11-13 16:07:56 -0800897 break;
898 case V4L2_CID_AUDIO_VOLUME:
899 case V4L2_CID_AUDIO_BASS:
900 case V4L2_CID_AUDIO_TREBLE:
901 case V4L2_CID_AUDIO_BALANCE:
902 case V4L2_CID_AUDIO_MUTE:
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300903 if (state->is_cx25836)
904 return -EINVAL;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300905 return cx25840_audio_g_ctrl(sd, ctrl);
Hans Verkuilbd985162005-11-13 16:07:56 -0800906 default:
907 return -EINVAL;
908 }
909
910 return 0;
911}
912
913/* ----------------------------------------------------------------------- */
914
Hans Verkuil9357b312008-11-29 12:50:06 -0300915static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
Hans Verkuilbd985162005-11-13 16:07:56 -0800916{
917 switch (fmt->type) {
918 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300919 return cx25840_vbi_g_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -0800920 default:
921 return -EINVAL;
922 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800923 return 0;
924}
925
Hans Verkuil9357b312008-11-29 12:50:06 -0300926static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
Hans Verkuilbd985162005-11-13 16:07:56 -0800927{
Hans Verkuil9357b312008-11-29 12:50:06 -0300928 struct cx25840_state *state = to_state(sd);
929 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800930 struct v4l2_pix_format *pix;
931 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
Hans Verkuil081b4962008-04-22 14:45:51 -0300932 int is_50Hz = !(state->std & V4L2_STD_525_60);
Hans Verkuilbd985162005-11-13 16:07:56 -0800933
934 switch (fmt->type) {
935 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
936 pix = &(fmt->fmt.pix);
937
938 Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
939 Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
940
941 Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
942 Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
943
Servaas Vandenbergheba70d592007-04-29 16:27:30 -0300944 Vlines = pix->height + (is_50Hz ? 4 : 7);
Hans Verkuilbd985162005-11-13 16:07:56 -0800945
946 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
947 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
Hans Verkuilfac9e892006-01-09 15:32:40 -0200948 v4l_err(client, "%dx%d is not a valid size!\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800949 pix->width, pix->height);
950 return -ERANGE;
951 }
952
953 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
954 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
955 VSC &= 0x1fff;
956
957 if (pix->width >= 385)
958 filter = 0;
959 else if (pix->width > 192)
960 filter = 1;
961 else if (pix->width > 96)
962 filter = 2;
963 else
964 filter = 3;
965
Hans Verkuilb5fc7142006-01-11 22:41:36 -0200966 v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
Hans Verkuilbd985162005-11-13 16:07:56 -0800967 pix->width, pix->height, HSC, VSC);
968
969 /* HSCALE=HSC */
970 cx25840_write(client, 0x418, HSC & 0xff);
971 cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
972 cx25840_write(client, 0x41a, HSC >> 16);
973 /* VSCALE=VSC */
974 cx25840_write(client, 0x41c, VSC & 0xff);
975 cx25840_write(client, 0x41d, VSC >> 8);
976 /* VS_INTRLACE=1 VFILT=filter */
977 cx25840_write(client, 0x41e, 0x8 | filter);
978 break;
979
980 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300981 return cx25840_vbi_s_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -0800982
983 case V4L2_BUF_TYPE_VBI_CAPTURE:
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300984 return cx25840_vbi_s_fmt(sd, fmt);
Hans Verkuilbd985162005-11-13 16:07:56 -0800985
986 default:
987 return -EINVAL;
988 }
989
990 return 0;
991}
992
993/* ----------------------------------------------------------------------- */
994
Hans Verkuil1a392752007-09-13 11:44:47 -0300995static void log_video_status(struct i2c_client *client)
996{
997 static const char *const fmt_strs[] = {
998 "0x0",
999 "NTSC-M", "NTSC-J", "NTSC-4.43",
1000 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
1001 "0x9", "0xA", "0xB",
1002 "SECAM",
1003 "0xD", "0xE", "0xF"
1004 };
1005
Hans Verkuil9357b312008-11-29 12:50:06 -03001006 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil1a392752007-09-13 11:44:47 -03001007 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
1008 u8 gen_stat1 = cx25840_read(client, 0x40d);
1009 u8 gen_stat2 = cx25840_read(client, 0x40e);
1010 int vid_input = state->vid_input;
1011
1012 v4l_info(client, "Video signal: %spresent\n",
1013 (gen_stat2 & 0x20) ? "" : "not ");
1014 v4l_info(client, "Detected format: %s\n",
1015 fmt_strs[gen_stat1 & 0xf]);
1016
1017 v4l_info(client, "Specified standard: %s\n",
1018 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
1019
1020 if (vid_input >= CX25840_COMPOSITE1 &&
1021 vid_input <= CX25840_COMPOSITE8) {
1022 v4l_info(client, "Specified video input: Composite %d\n",
1023 vid_input - CX25840_COMPOSITE1 + 1);
1024 } else {
1025 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1026 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1027 }
1028
1029 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1030}
1031
1032/* ----------------------------------------------------------------------- */
1033
1034static void log_audio_status(struct i2c_client *client)
1035{
Hans Verkuil9357b312008-11-29 12:50:06 -03001036 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil1a392752007-09-13 11:44:47 -03001037 u8 download_ctl = cx25840_read(client, 0x803);
1038 u8 mod_det_stat0 = cx25840_read(client, 0x804);
1039 u8 mod_det_stat1 = cx25840_read(client, 0x805);
1040 u8 audio_config = cx25840_read(client, 0x808);
1041 u8 pref_mode = cx25840_read(client, 0x809);
1042 u8 afc0 = cx25840_read(client, 0x80b);
1043 u8 mute_ctl = cx25840_read(client, 0x8d3);
1044 int aud_input = state->aud_input;
1045 char *p;
1046
1047 switch (mod_det_stat0) {
1048 case 0x00: p = "mono"; break;
1049 case 0x01: p = "stereo"; break;
1050 case 0x02: p = "dual"; break;
1051 case 0x04: p = "tri"; break;
1052 case 0x10: p = "mono with SAP"; break;
1053 case 0x11: p = "stereo with SAP"; break;
1054 case 0x12: p = "dual with SAP"; break;
1055 case 0x14: p = "tri with SAP"; break;
1056 case 0xfe: p = "forced mode"; break;
1057 default: p = "not defined";
1058 }
1059 v4l_info(client, "Detected audio mode: %s\n", p);
1060
1061 switch (mod_det_stat1) {
1062 case 0x00: p = "not defined"; break;
1063 case 0x01: p = "EIAJ"; break;
1064 case 0x02: p = "A2-M"; break;
1065 case 0x03: p = "A2-BG"; break;
1066 case 0x04: p = "A2-DK1"; break;
1067 case 0x05: p = "A2-DK2"; break;
1068 case 0x06: p = "A2-DK3"; break;
1069 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
1070 case 0x08: p = "AM-L"; break;
1071 case 0x09: p = "NICAM-BG"; break;
1072 case 0x0a: p = "NICAM-DK"; break;
1073 case 0x0b: p = "NICAM-I"; break;
1074 case 0x0c: p = "NICAM-L"; break;
1075 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
1076 case 0x0e: p = "IF FM Radio"; break;
1077 case 0x0f: p = "BTSC"; break;
1078 case 0x10: p = "high-deviation FM"; break;
1079 case 0x11: p = "very high-deviation FM"; break;
1080 case 0xfd: p = "unknown audio standard"; break;
1081 case 0xfe: p = "forced audio standard"; break;
1082 case 0xff: p = "no detected audio standard"; break;
1083 default: p = "not defined";
1084 }
1085 v4l_info(client, "Detected audio standard: %s\n", p);
1086 v4l_info(client, "Audio muted: %s\n",
1087 (state->unmute_volume >= 0) ? "yes" : "no");
1088 v4l_info(client, "Audio microcontroller: %s\n",
1089 (download_ctl & 0x10) ?
1090 ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
1091
1092 switch (audio_config >> 4) {
1093 case 0x00: p = "undefined"; break;
1094 case 0x01: p = "BTSC"; break;
1095 case 0x02: p = "EIAJ"; break;
1096 case 0x03: p = "A2-M"; break;
1097 case 0x04: p = "A2-BG"; break;
1098 case 0x05: p = "A2-DK1"; break;
1099 case 0x06: p = "A2-DK2"; break;
1100 case 0x07: p = "A2-DK3"; break;
1101 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
1102 case 0x09: p = "AM-L"; break;
1103 case 0x0a: p = "NICAM-BG"; break;
1104 case 0x0b: p = "NICAM-DK"; break;
1105 case 0x0c: p = "NICAM-I"; break;
1106 case 0x0d: p = "NICAM-L"; break;
1107 case 0x0e: p = "FM radio"; break;
1108 case 0x0f: p = "automatic detection"; break;
1109 default: p = "undefined";
1110 }
1111 v4l_info(client, "Configured audio standard: %s\n", p);
1112
1113 if ((audio_config >> 4) < 0xF) {
1114 switch (audio_config & 0xF) {
1115 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
1116 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
1117 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
1118 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
1119 case 0x04: p = "STEREO"; break;
1120 case 0x05: p = "DUAL1 (AB)"; break;
1121 case 0x06: p = "DUAL2 (AC) (FM)"; break;
1122 case 0x07: p = "DUAL3 (BC) (FM)"; break;
1123 case 0x08: p = "DUAL4 (AC) (AM)"; break;
1124 case 0x09: p = "DUAL5 (BC) (AM)"; break;
1125 case 0x0a: p = "SAP"; break;
1126 default: p = "undefined";
1127 }
1128 v4l_info(client, "Configured audio mode: %s\n", p);
1129 } else {
1130 switch (audio_config & 0xF) {
1131 case 0x00: p = "BG"; break;
1132 case 0x01: p = "DK1"; break;
1133 case 0x02: p = "DK2"; break;
1134 case 0x03: p = "DK3"; break;
1135 case 0x04: p = "I"; break;
1136 case 0x05: p = "L"; break;
1137 case 0x06: p = "BTSC"; break;
1138 case 0x07: p = "EIAJ"; break;
1139 case 0x08: p = "A2-M"; break;
1140 case 0x09: p = "FM Radio"; break;
1141 case 0x0f: p = "automatic standard and mode detection"; break;
1142 default: p = "undefined";
1143 }
1144 v4l_info(client, "Configured audio system: %s\n", p);
1145 }
1146
1147 if (aud_input) {
1148 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
1149 } else {
1150 v4l_info(client, "Specified audio input: External\n");
1151 }
1152
1153 switch (pref_mode & 0xf) {
1154 case 0: p = "mono/language A"; break;
1155 case 1: p = "language B"; break;
1156 case 2: p = "language C"; break;
1157 case 3: p = "analog fallback"; break;
1158 case 4: p = "stereo"; break;
1159 case 5: p = "language AC"; break;
1160 case 6: p = "language BC"; break;
1161 case 7: p = "language AB"; break;
1162 default: p = "undefined";
1163 }
1164 v4l_info(client, "Preferred audio mode: %s\n", p);
1165
1166 if ((audio_config & 0xf) == 0xf) {
1167 switch ((afc0 >> 3) & 0x3) {
1168 case 0: p = "system DK"; break;
1169 case 1: p = "system L"; break;
1170 case 2: p = "autodetect"; break;
1171 default: p = "undefined";
1172 }
1173 v4l_info(client, "Selected 65 MHz format: %s\n", p);
1174
1175 switch (afc0 & 0x7) {
1176 case 0: p = "chroma"; break;
1177 case 1: p = "BTSC"; break;
1178 case 2: p = "EIAJ"; break;
1179 case 3: p = "A2-M"; break;
1180 case 4: p = "autodetect"; break;
1181 default: p = "undefined";
1182 }
1183 v4l_info(client, "Selected 45 MHz format: %s\n", p);
1184 }
1185}
1186
1187/* ----------------------------------------------------------------------- */
1188
Hans Verkuil6ca187a2009-01-15 05:53:18 -03001189/* This init operation must be called to load the driver's firmware.
1190 Without this the audio standard detection will fail and you will
1191 only get mono.
1192
1193 Since loading the firmware is often problematic when the driver is
1194 compiled into the kernel I recommend postponing calling this function
1195 until the first open of the video device. Another reason for
1196 postponing it is that loading this firmware takes a long time (seconds)
1197 due to the slow i2c bus speed. So it will speed up the boot process if
1198 you can avoid loading the fw as long as the video device isn't used. */
Hans Verkuil9357b312008-11-29 12:50:06 -03001199static int cx25840_init(struct v4l2_subdev *sd, u32 val)
Hans Verkuilbd985162005-11-13 16:07:56 -08001200{
Hans Verkuil9357b312008-11-29 12:50:06 -03001201 struct cx25840_state *state = to_state(sd);
1202 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001203
1204 if (!state->is_initialized) {
Hans Verkuilc976bc82007-07-22 12:52:40 -03001205 /* initialize on first use */
1206 state->is_initialized = 1;
1207 if (state->is_cx25836)
1208 cx25836_initialize(client);
Steven Tothf2340812008-01-10 01:22:39 -03001209 else if (state->is_cx23885)
1210 cx23885_initialize(client);
Sri Deevi149783b2009-03-03 06:07:42 -03001211 else if (state->is_cx231xx)
1212 cx231xx_initialize(client);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001213 else
Hans Verkuil89fc4eb2007-08-04 05:00:07 -03001214 cx25840_initialize(client);
Hans Verkuilc976bc82007-07-22 12:52:40 -03001215 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001216 return 0;
1217}
Hans Verkuilc976bc82007-07-22 12:52:40 -03001218
Hans Verkuilbd985162005-11-13 16:07:56 -08001219#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001220static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9357b312008-11-29 12:50:06 -03001221{
1222 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001223
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001224 if (!v4l2_chip_match_i2c_client(client, &reg->match))
Hans Verkuil9357b312008-11-29 12:50:06 -03001225 return -EINVAL;
1226 if (!capable(CAP_SYS_ADMIN))
1227 return -EPERM;
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001228 reg->size = 1;
Hans Verkuil9357b312008-11-29 12:50:06 -03001229 reg->val = cx25840_read(client, reg->reg & 0x0fff);
1230 return 0;
1231}
Steven Tothf2340812008-01-10 01:22:39 -03001232
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001233static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9357b312008-11-29 12:50:06 -03001234{
1235 struct i2c_client *client = v4l2_get_subdevdata(sd);
1236
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001237 if (!v4l2_chip_match_i2c_client(client, &reg->match))
Hans Verkuil9357b312008-11-29 12:50:06 -03001238 return -EINVAL;
1239 if (!capable(CAP_SYS_ADMIN))
1240 return -EPERM;
1241 cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
1242 return 0;
1243}
Hans Verkuilbd985162005-11-13 16:07:56 -08001244#endif
1245
Hans Verkuil9357b312008-11-29 12:50:06 -03001246static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1247{
1248 struct cx25840_state *state = to_state(sd);
1249 struct i2c_client *client = v4l2_get_subdevdata(sd);
1250
1251 v4l_dbg(1, cx25840_debug, client, "%s output\n",
1252 enable ? "enable" : "disable");
1253 if (enable) {
Sri Deevi149783b2009-03-03 06:07:42 -03001254 if (state->is_cx23885 || state->is_cx231xx) {
Steven Tothf2340812008-01-10 01:22:39 -03001255 u8 v = (cx25840_read(client, 0x421) | 0x0b);
1256 cx25840_write(client, 0x421, v);
1257 } else {
1258 cx25840_write(client, 0x115,
Hans Verkuil9357b312008-11-29 12:50:06 -03001259 state->is_cx25836 ? 0x0c : 0x8c);
Steven Tothf2340812008-01-10 01:22:39 -03001260 cx25840_write(client, 0x116,
Hans Verkuil9357b312008-11-29 12:50:06 -03001261 state->is_cx25836 ? 0x04 : 0x07);
Steven Tothf2340812008-01-10 01:22:39 -03001262 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001263 } else {
Sri Deevi149783b2009-03-03 06:07:42 -03001264 if (state->is_cx23885 || state->is_cx231xx) {
Steven Tothf2340812008-01-10 01:22:39 -03001265 u8 v = cx25840_read(client, 0x421) & ~(0x0b);
1266 cx25840_write(client, 0x421, v);
1267 } else {
1268 cx25840_write(client, 0x115, 0x00);
1269 cx25840_write(client, 0x116, 0x00);
1270 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001271 }
1272 return 0;
1273}
1274
1275static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1276{
1277 struct cx25840_state *state = to_state(sd);
1278
1279 switch (qc->id) {
1280 case V4L2_CID_BRIGHTNESS:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001281 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
Hans Verkuil9357b312008-11-29 12:50:06 -03001282 case V4L2_CID_CONTRAST:
1283 case V4L2_CID_SATURATION:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001284 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
Hans Verkuil9357b312008-11-29 12:50:06 -03001285 case V4L2_CID_HUE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001286 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
Hans Verkuil9357b312008-11-29 12:50:06 -03001287 default:
Hans Verkuilbd985162005-11-13 16:07:56 -08001288 break;
Hans Verkuil9357b312008-11-29 12:50:06 -03001289 }
1290 if (state->is_cx25836)
1291 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -08001292
Hans Verkuil9357b312008-11-29 12:50:06 -03001293 switch (qc->id) {
1294 case V4L2_CID_AUDIO_VOLUME:
1295 return v4l2_ctrl_query_fill(qc, 0, 65535,
1296 65535 / 100, state->default_volume);
1297 case V4L2_CID_AUDIO_MUTE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001298 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
Hans Verkuil9357b312008-11-29 12:50:06 -03001299 case V4L2_CID_AUDIO_BALANCE:
1300 case V4L2_CID_AUDIO_BASS:
1301 case V4L2_CID_AUDIO_TREBLE:
Hans Verkuil10afbef2009-02-21 18:47:24 -03001302 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
Hans Verkuil9357b312008-11-29 12:50:06 -03001303 default:
Hans Verkuild92c20e2006-01-09 15:32:41 -02001304 return -EINVAL;
1305 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001306 return -EINVAL;
1307}
Hans Verkuild92c20e2006-01-09 15:32:41 -02001308
Hans Verkuil9357b312008-11-29 12:50:06 -03001309static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1310{
1311 struct cx25840_state *state = to_state(sd);
1312 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001313
Hans Verkuil9357b312008-11-29 12:50:06 -03001314 if (state->radio == 0 && state->std == std)
1315 return 0;
1316 state->radio = 0;
1317 state->std = std;
1318 return set_v4lstd(client);
1319}
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001320
Hans Verkuil9357b312008-11-29 12:50:06 -03001321static int cx25840_s_radio(struct v4l2_subdev *sd)
1322{
1323 struct cx25840_state *state = to_state(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001324
Hans Verkuil9357b312008-11-29 12:50:06 -03001325 state->radio = 1;
1326 return 0;
1327}
Hans Verkuilbd985162005-11-13 16:07:56 -08001328
Hans Verkuil9357b312008-11-29 12:50:06 -03001329static int cx25840_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1330{
1331 struct cx25840_state *state = to_state(sd);
1332 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001333
Hans Verkuil9357b312008-11-29 12:50:06 -03001334 return set_input(client, route->input, state->aud_input);
1335}
Hans Verkuila8bbf122006-01-09 15:25:42 -02001336
Hans Verkuil9357b312008-11-29 12:50:06 -03001337static int cx25840_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1338{
1339 struct cx25840_state *state = to_state(sd);
1340 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuila8bbf122006-01-09 15:25:42 -02001341
Hans Verkuil9357b312008-11-29 12:50:06 -03001342 if (state->is_cx25836)
1343 return -EINVAL;
1344 return set_input(client, state->vid_input, route->input);
1345}
Hans Verkuilbd985162005-11-13 16:07:56 -08001346
Hans Verkuil9357b312008-11-29 12:50:06 -03001347static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
1348{
1349 struct cx25840_state *state = to_state(sd);
1350 struct i2c_client *client = v4l2_get_subdevdata(sd);
Hans Verkuilbd985162005-11-13 16:07:56 -08001351
Hans Verkuil9357b312008-11-29 12:50:06 -03001352 if (!state->is_cx25836)
1353 input_change(client);
1354 return 0;
1355}
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001356
Hans Verkuil9357b312008-11-29 12:50:06 -03001357static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1358{
1359 struct cx25840_state *state = to_state(sd);
1360 struct i2c_client *client = v4l2_get_subdevdata(sd);
1361 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
1362 u8 mode;
1363 int val = 0;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001364
Hans Verkuil9357b312008-11-29 12:50:06 -03001365 if (state->radio)
1366 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001367
Hans Verkuil9357b312008-11-29 12:50:06 -03001368 vt->signal = vpres ? 0xffff : 0x0;
1369 if (state->is_cx25836)
1370 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001371
Hans Verkuil9357b312008-11-29 12:50:06 -03001372 vt->capability |=
1373 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
1374 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
Hans Verkuilbd985162005-11-13 16:07:56 -08001375
Hans Verkuil9357b312008-11-29 12:50:06 -03001376 mode = cx25840_read(client, 0x804);
Hans Verkuilbd985162005-11-13 16:07:56 -08001377
Hans Verkuil9357b312008-11-29 12:50:06 -03001378 /* get rxsubchans and audmode */
1379 if ((mode & 0xf) == 1)
1380 val |= V4L2_TUNER_SUB_STEREO;
1381 else
1382 val |= V4L2_TUNER_SUB_MONO;
Hans Verkuilbd985162005-11-13 16:07:56 -08001383
Hans Verkuil9357b312008-11-29 12:50:06 -03001384 if (mode == 2 || mode == 4)
1385 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
Hans Verkuilbd985162005-11-13 16:07:56 -08001386
Hans Verkuil9357b312008-11-29 12:50:06 -03001387 if (mode & 0x10)
1388 val |= V4L2_TUNER_SUB_SAP;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001389
Hans Verkuil9357b312008-11-29 12:50:06 -03001390 vt->rxsubchans = val;
1391 vt->audmode = state->audmode;
1392 return 0;
1393}
1394
1395static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1396{
1397 struct cx25840_state *state = to_state(sd);
1398 struct i2c_client *client = v4l2_get_subdevdata(sd);
1399
1400 if (state->radio || state->is_cx25836)
1401 return 0;
1402
1403 switch (vt->audmode) {
Hans Verkuilbd985162005-11-13 16:07:56 -08001404 case V4L2_TUNER_MODE_MONO:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001405 /* mono -> mono
1406 stereo -> mono
1407 bilingual -> lang1 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001408 cx25840_and_or(client, 0x809, ~0xf, 0x00);
1409 break;
Hans Verkuil301e22d2006-03-18 17:15:00 -03001410 case V4L2_TUNER_MODE_STEREO:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001411 case V4L2_TUNER_MODE_LANG1:
1412 /* mono -> mono
1413 stereo -> stereo
1414 bilingual -> lang1 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001415 cx25840_and_or(client, 0x809, ~0xf, 0x04);
1416 break;
Hans Verkuil301e22d2006-03-18 17:15:00 -03001417 case V4L2_TUNER_MODE_LANG1_LANG2:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001418 /* mono -> mono
1419 stereo -> stereo
1420 bilingual -> lang1/lang2 */
1421 cx25840_and_or(client, 0x809, ~0xf, 0x07);
1422 break;
Hans Verkuilbd985162005-11-13 16:07:56 -08001423 case V4L2_TUNER_MODE_LANG2:
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001424 /* mono -> mono
Hans Verkuil301e22d2006-03-18 17:15:00 -03001425 stereo -> stereo
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001426 bilingual -> lang2 */
Hans Verkuilbd985162005-11-13 16:07:56 -08001427 cx25840_and_or(client, 0x809, ~0xf, 0x01);
1428 break;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001429 default:
1430 return -EINVAL;
Hans Verkuilbd985162005-11-13 16:07:56 -08001431 }
Hans Verkuil9357b312008-11-29 12:50:06 -03001432 state->audmode = vt->audmode;
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001433 return 0;
Hans Verkuilbd985162005-11-13 16:07:56 -08001434}
1435
Hans Verkuil9357b312008-11-29 12:50:06 -03001436static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1437{
1438 struct cx25840_state *state = to_state(sd);
1439 struct i2c_client *client = v4l2_get_subdevdata(sd);
1440
1441 if (state->is_cx25836)
1442 cx25836_initialize(client);
1443 else if (state->is_cx23885)
1444 cx23885_initialize(client);
Sri Deevi149783b2009-03-03 06:07:42 -03001445 else if (state->is_cx231xx)
1446 cx231xx_initialize(client);
Hans Verkuil9357b312008-11-29 12:50:06 -03001447 else
1448 cx25840_initialize(client);
1449 return 0;
1450}
1451
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001452static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil9357b312008-11-29 12:50:06 -03001453{
1454 struct cx25840_state *state = to_state(sd);
1455 struct i2c_client *client = v4l2_get_subdevdata(sd);
1456
1457 return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
1458}
1459
1460static int cx25840_log_status(struct v4l2_subdev *sd)
1461{
1462 struct cx25840_state *state = to_state(sd);
1463 struct i2c_client *client = v4l2_get_subdevdata(sd);
1464
1465 log_video_status(client);
1466 if (!state->is_cx25836)
1467 log_audio_status(client);
1468 return 0;
1469}
1470
Hans Verkuil9357b312008-11-29 12:50:06 -03001471/* ----------------------------------------------------------------------- */
1472
1473static const struct v4l2_subdev_core_ops cx25840_core_ops = {
1474 .log_status = cx25840_log_status,
1475 .g_chip_ident = cx25840_g_chip_ident,
1476 .g_ctrl = cx25840_g_ctrl,
1477 .s_ctrl = cx25840_s_ctrl,
1478 .queryctrl = cx25840_queryctrl,
1479 .reset = cx25840_reset,
1480 .init = cx25840_init,
1481#ifdef CONFIG_VIDEO_ADV_DEBUG
1482 .g_register = cx25840_g_register,
1483 .s_register = cx25840_s_register,
1484#endif
1485};
1486
1487static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1488 .s_frequency = cx25840_s_frequency,
1489 .s_std = cx25840_s_std,
1490 .s_radio = cx25840_s_radio,
1491 .g_tuner = cx25840_g_tuner,
1492 .s_tuner = cx25840_s_tuner,
1493};
1494
1495static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1496 .s_clock_freq = cx25840_s_clock_freq,
1497 .s_routing = cx25840_s_audio_routing,
1498};
1499
1500static const struct v4l2_subdev_video_ops cx25840_video_ops = {
1501 .s_routing = cx25840_s_video_routing,
1502 .g_fmt = cx25840_g_fmt,
1503 .s_fmt = cx25840_s_fmt,
1504 .decode_vbi_line = cx25840_decode_vbi_line,
1505 .s_stream = cx25840_s_stream,
1506};
1507
1508static const struct v4l2_subdev_ops cx25840_ops = {
1509 .core = &cx25840_core_ops,
1510 .tuner = &cx25840_tuner_ops,
1511 .audio = &cx25840_audio_ops,
1512 .video = &cx25840_video_ops,
1513};
1514
Hans Verkuilbd985162005-11-13 16:07:56 -08001515/* ----------------------------------------------------------------------- */
1516
Jean Delvared2653e92008-04-29 23:11:39 +02001517static int cx25840_probe(struct i2c_client *client,
1518 const struct i2c_device_id *did)
Hans Verkuilbd985162005-11-13 16:07:56 -08001519{
Hans Verkuilbd985162005-11-13 16:07:56 -08001520 struct cx25840_state *state;
Hans Verkuil9357b312008-11-29 12:50:06 -03001521 struct v4l2_subdev *sd;
Hans Verkuil3434eb72007-04-27 12:31:08 -03001522 u32 id;
Hans Verkuilbd985162005-11-13 16:07:56 -08001523 u16 device_id;
1524
Hans Verkuil188f3452007-09-16 10:47:15 -03001525 /* Check if the adapter supports the needed features */
1526 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1527 return -EIO;
1528
Hans Verkuil21340ae2007-08-26 10:53:16 -03001529 v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", client->addr << 1);
Hans Verkuilbd985162005-11-13 16:07:56 -08001530
1531 device_id = cx25840_read(client, 0x101) << 8;
1532 device_id |= cx25840_read(client, 0x100);
Steven Tothf2340812008-01-10 01:22:39 -03001533 v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id);
Hans Verkuilbd985162005-11-13 16:07:56 -08001534
1535 /* The high byte of the device ID should be
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001536 * 0x83 for the cx2583x and 0x84 for the cx2584x */
1537 if ((device_id & 0xff00) == 0x8300) {
1538 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001539 }
1540 else if ((device_id & 0xff00) == 0x8400) {
1541 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
Sri Deevi149783b2009-03-03 06:07:42 -03001542 } /* else if (device_id == 0x0000) {
Steven Tothf2340812008-01-10 01:22:39 -03001543 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
Sri Deevi149783b2009-03-03 06:07:42 -03001544 } */ else if (device_id == 0x1313) {
Steven Tothf2340812008-01-10 01:22:39 -03001545 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
Sri Deevi149783b2009-03-03 06:07:42 -03001546 } else if ((device_id & 0xfff0) == 0x5A30) {
1547 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001548 }
1549 else {
Hans Verkuilb5fc7142006-01-11 22:41:36 -02001550 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
Hans Verkuil188f3452007-09-16 10:47:15 -03001551 return -ENODEV;
Hans Verkuilbd985162005-11-13 16:07:56 -08001552 }
1553
Hans Verkuil21340ae2007-08-26 10:53:16 -03001554 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
Hans Verkuil9357b312008-11-29 12:50:06 -03001555 if (state == NULL)
Hans Verkuil21340ae2007-08-26 10:53:16 -03001556 return -ENOMEM;
Hans Verkuil21340ae2007-08-26 10:53:16 -03001557
Hans Verkuil9357b312008-11-29 12:50:06 -03001558 sd = &state->sd;
1559 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
Hans Verkuilb7a01e72007-02-02 20:49:54 -03001560 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1561 marking skips from 0x1 == 22 to 0x3 == 23. */
Hans Verkuilfac9e892006-01-09 15:32:40 -02001562 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
Hans Verkuilbd985162005-11-13 16:07:56 -08001563 (device_id & 0xfff0) >> 4,
Hans Verkuilb7a01e72007-02-02 20:49:54 -03001564 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f),
Hans Verkuil21340ae2007-08-26 10:53:16 -03001565 client->addr << 1, client->adapter->name);
Hans Verkuilbd985162005-11-13 16:07:56 -08001566
Hans Verkuil21340ae2007-08-26 10:53:16 -03001567 state->c = client;
1568 state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
Steven Tothf2340812008-01-10 01:22:39 -03001569 state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
Sri Deevi149783b2009-03-03 06:07:42 -03001570 state->is_cx231xx = (device_id == 0x5A3E);
Hans Verkuila8bbf122006-01-09 15:25:42 -02001571 state->vid_input = CX25840_COMPOSITE7;
1572 state->aud_input = CX25840_AUDIO8;
Hans Verkuil3578d3d2006-01-09 15:25:41 -02001573 state->audclk_freq = 48000;
Hans Verkuila8bbf122006-01-09 15:25:42 -02001574 state->pvr150_workaround = 0;
Hans Verkuil8a4b2752006-01-23 17:11:09 -02001575 state->audmode = V4L2_TUNER_MODE_LANG1;
Hans Verkuil87410da2007-08-05 08:00:36 -03001576 state->unmute_volume = -1;
Hans Verkuilca130ee2008-07-17 12:26:45 -03001577 state->default_volume = 228 - cx25840_read(client, 0x8d4);
1578 state->default_volume = ((state->default_volume / 2) + 23) << 9;
Christopher Neufeld3e3bf272006-05-24 10:16:45 -03001579 state->vbi_line_offset = 8;
Hans Verkuile2b8cf42006-04-22 10:22:46 -03001580 state->id = id;
Hans Verkuil3434eb72007-04-27 12:31:08 -03001581 state->rev = device_id;
Steven Tothf2340812008-01-10 01:22:39 -03001582
Steven Toth2770b7d2008-04-19 01:18:47 -03001583 if (state->is_cx23885) {
1584 /* Drive GPIO2 direction and values */
1585 cx25840_write(client, 0x160, 0x1d);
1586 cx25840_write(client, 0x164, 0x00);
1587 }
1588
Hans Verkuilbd985162005-11-13 16:07:56 -08001589 return 0;
1590}
1591
Hans Verkuil1a392752007-09-13 11:44:47 -03001592static int cx25840_remove(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -08001593{
Hans Verkuil9357b312008-11-29 12:50:06 -03001594 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1595
1596 v4l2_device_unregister_subdev(sd);
1597 kfree(to_state(sd));
Hans Verkuilbd985162005-11-13 16:07:56 -08001598 return 0;
1599}
1600
Jean Delvareaf294862008-05-18 20:49:40 +02001601static const struct i2c_device_id cx25840_id[] = {
1602 { "cx25840", 0 },
1603 { }
1604};
1605MODULE_DEVICE_TABLE(i2c, cx25840_id);
1606
Hans Verkuil1a392752007-09-13 11:44:47 -03001607static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1608 .name = "cx25840",
Hans Verkuil1a392752007-09-13 11:44:47 -03001609 .probe = cx25840_probe,
1610 .remove = cx25840_remove,
Jean Delvareaf294862008-05-18 20:49:40 +02001611 .id_table = cx25840_id,
Hans Verkuilbd985162005-11-13 16:07:56 -08001612};