GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / media / i2c / sony-btf-mpx.c
1 /*
2  * Copyright (C) 2005-2006 Micronas USA Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License (Version 2) as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/i2c.h>
17 #include <linux/videodev2.h>
18 #include <media/tuner.h>
19 #include <media/v4l2-common.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/v4l2-device.h>
22 #include <linux/slab.h>
23
24 MODULE_DESCRIPTION("sony-btf-mpx driver");
25 MODULE_LICENSE("GPL v2");
26
27 static int debug;
28 module_param(debug, int, 0644);
29 MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on");
30
31 /* #define MPX_DEBUG */
32
33 /*
34  * Note:
35  *
36  * AS(IF/MPX) pin:      LOW      HIGH/OPEN
37  * IF/MPX address:   0x42/0x40   0x43/0x44
38  */
39
40
41 static int force_mpx_mode = -1;
42 module_param(force_mpx_mode, int, 0644);
43
44 struct sony_btf_mpx {
45         struct v4l2_subdev sd;
46         int mpxmode;
47         u32 audmode;
48 };
49
50 static inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd)
51 {
52         return container_of(sd, struct sony_btf_mpx, sd);
53 }
54
55 static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
56 {
57         u8 buffer[5];
58         struct i2c_msg msg;
59
60         buffer[0] = dev;
61         buffer[1] = addr >> 8;
62         buffer[2] = addr & 0xff;
63         buffer[3] = val >> 8;
64         buffer[4] = val & 0xff;
65         msg.addr = client->addr;
66         msg.flags = 0;
67         msg.len = 5;
68         msg.buf = buffer;
69         i2c_transfer(client->adapter, &msg, 1);
70         return 0;
71 }
72
73 /*
74  * MPX register values for the BTF-PG472Z:
75  *
76  *                                 FM_     NICAM_  SCART_
77  *          MODUS  SOURCE    ACB   PRESCAL PRESCAL PRESCAL SYSTEM  VOLUME
78  *         10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
79  *         ---------------------------------------------------------------
80  * Auto     1003    0020    0100    2603    5000    XXXX    0001    7500
81  *
82  * B/G
83  *  Mono    1003    0020    0100    2603    5000    XXXX    0003    7500
84  *  A2      1003    0020    0100    2601    5000    XXXX    0003    7500
85  *  NICAM   1003    0120    0100    2603    5000    XXXX    0008    7500
86  *
87  * I
88  *  Mono    1003    0020    0100    2603    7900    XXXX    000A    7500
89  *  NICAM   1003    0120    0100    2603    7900    XXXX    000A    7500
90  *
91  * D/K
92  *  Mono    1003    0020    0100    2603    5000    XXXX    0004    7500
93  *  A2-1    1003    0020    0100    2601    5000    XXXX    0004    7500
94  *  A2-2    1003    0020    0100    2601    5000    XXXX    0005    7500
95  *  A2-3    1003    0020    0100    2601    5000    XXXX    0007    7500
96  *  NICAM   1003    0120    0100    2603    5000    XXXX    000B    7500
97  *
98  * L/L'
99  *  Mono    0003    0200    0100    7C03    5000    2200    0009    7500
100  *  NICAM   0003    0120    0100    7C03    5000    XXXX    0009    7500
101  *
102  * M
103  *  Mono    1003    0200    0100    2B03    5000    2B00    0002    7500
104  *
105  * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
106  *
107  * Bilingual selection in A2/NICAM:
108  *
109  *         High byte of SOURCE     Left chan   Right chan
110  *                 0x01              MAIN         SUB
111  *                 0x03              MAIN         MAIN
112  *                 0x04              SUB          SUB
113  *
114  * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
115  * 0x00 (all other bands).  Force mono in A2 with FMONO_A2:
116  *
117  *                      FMONO_A2
118  *                      10/0022
119  *                      --------
120  *     Forced mono ON     07F0
121  *     Forced mono OFF    0190
122  */
123
124 static const struct {
125         enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
126         u16 modus;
127         u16 source;
128         u16 acb;
129         u16 fm_prescale;
130         u16 nicam_prescale;
131         u16 scart_prescale;
132         u16 system;
133         u16 volume;
134 } mpx_audio_modes[] = {
135         /* Auto */      { AUD_MONO,     0x1003, 0x0020, 0x0100, 0x2603,
136                                         0x5000, 0x0000, 0x0001, 0x7500 },
137         /* B/G Mono */  { AUD_MONO,     0x1003, 0x0020, 0x0100, 0x2603,
138                                         0x5000, 0x0000, 0x0003, 0x7500 },
139         /* B/G A2 */    { AUD_A2,       0x1003, 0x0020, 0x0100, 0x2601,
140                                         0x5000, 0x0000, 0x0003, 0x7500 },
141         /* B/G NICAM */ { AUD_NICAM,    0x1003, 0x0120, 0x0100, 0x2603,
142                                         0x5000, 0x0000, 0x0008, 0x7500 },
143         /* I Mono */    { AUD_MONO,     0x1003, 0x0020, 0x0100, 0x2603,
144                                         0x7900, 0x0000, 0x000A, 0x7500 },
145         /* I NICAM */   { AUD_NICAM,    0x1003, 0x0120, 0x0100, 0x2603,
146                                         0x7900, 0x0000, 0x000A, 0x7500 },
147         /* D/K Mono */  { AUD_MONO,     0x1003, 0x0020, 0x0100, 0x2603,
148                                         0x5000, 0x0000, 0x0004, 0x7500 },
149         /* D/K A2-1 */  { AUD_A2,       0x1003, 0x0020, 0x0100, 0x2601,
150                                         0x5000, 0x0000, 0x0004, 0x7500 },
151         /* D/K A2-2 */  { AUD_A2,       0x1003, 0x0020, 0x0100, 0x2601,
152                                         0x5000, 0x0000, 0x0005, 0x7500 },
153         /* D/K A2-3 */  { AUD_A2,       0x1003, 0x0020, 0x0100, 0x2601,
154                                         0x5000, 0x0000, 0x0007, 0x7500 },
155         /* D/K NICAM */ { AUD_NICAM,    0x1003, 0x0120, 0x0100, 0x2603,
156                                         0x5000, 0x0000, 0x000B, 0x7500 },
157         /* L/L' Mono */ { AUD_MONO,     0x0003, 0x0200, 0x0100, 0x7C03,
158                                         0x5000, 0x2200, 0x0009, 0x7500 },
159         /* L/L' NICAM */{ AUD_NICAM_L,  0x0003, 0x0120, 0x0100, 0x7C03,
160                                         0x5000, 0x0000, 0x0009, 0x7500 },
161 };
162
163 #define MPX_NUM_MODES   ARRAY_SIZE(mpx_audio_modes)
164
165 static int mpx_setup(struct sony_btf_mpx *t)
166 {
167         struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
168         u16 source = 0;
169         u8 buffer[3];
170         struct i2c_msg msg;
171         int mode = t->mpxmode;
172
173         /* reset MPX */
174         buffer[0] = 0x00;
175         buffer[1] = 0x80;
176         buffer[2] = 0x00;
177         msg.addr = client->addr;
178         msg.flags = 0;
179         msg.len = 3;
180         msg.buf = buffer;
181         i2c_transfer(client->adapter, &msg, 1);
182         buffer[1] = 0x00;
183         i2c_transfer(client->adapter, &msg, 1);
184
185         if (t->audmode != V4L2_TUNER_MODE_MONO)
186                 mode++;
187
188         if (mpx_audio_modes[mode].audio_mode != AUD_MONO) {
189                 switch (t->audmode) {
190                 case V4L2_TUNER_MODE_MONO:
191                         switch (mpx_audio_modes[mode].audio_mode) {
192                         case AUD_A2:
193                                 source = mpx_audio_modes[mode].source;
194                                 break;
195                         case AUD_NICAM:
196                                 source = 0x0000;
197                                 break;
198                         case AUD_NICAM_L:
199                                 source = 0x0200;
200                                 break;
201                         default:
202                                 break;
203                         }
204                         break;
205                 case V4L2_TUNER_MODE_STEREO:
206                         source = mpx_audio_modes[mode].source;
207                         break;
208                 case V4L2_TUNER_MODE_LANG1:
209                         source = 0x0300;
210                         break;
211                 case V4L2_TUNER_MODE_LANG2:
212                         source = 0x0400;
213                         break;
214                 }
215                 source |= mpx_audio_modes[mode].source & 0x00ff;
216         } else
217                 source = mpx_audio_modes[mode].source;
218
219         mpx_write(client, 0x10, 0x0030, mpx_audio_modes[mode].modus);
220         mpx_write(client, 0x12, 0x0008, source);
221         mpx_write(client, 0x12, 0x0013, mpx_audio_modes[mode].acb);
222         mpx_write(client, 0x12, 0x000e,
223                         mpx_audio_modes[mode].fm_prescale);
224         mpx_write(client, 0x12, 0x0010,
225                         mpx_audio_modes[mode].nicam_prescale);
226         mpx_write(client, 0x12, 0x000d,
227                         mpx_audio_modes[mode].scart_prescale);
228         mpx_write(client, 0x10, 0x0020, mpx_audio_modes[mode].system);
229         mpx_write(client, 0x12, 0x0000, mpx_audio_modes[mode].volume);
230         if (mpx_audio_modes[mode].audio_mode == AUD_A2)
231                 mpx_write(client, 0x10, 0x0022,
232                         t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
233
234 #ifdef MPX_DEBUG
235         {
236                 u8 buf1[3], buf2[2];
237                 struct i2c_msg msgs[2];
238
239                 v4l2_info(client,
240                         "MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n",
241                         mpx_audio_modes[mode].modus,
242                         source,
243                         mpx_audio_modes[mode].acb,
244                         mpx_audio_modes[mode].fm_prescale,
245                         mpx_audio_modes[mode].nicam_prescale,
246                         mpx_audio_modes[mode].scart_prescale,
247                         mpx_audio_modes[mode].system,
248                         mpx_audio_modes[mode].volume);
249                 buf1[0] = 0x11;
250                 buf1[1] = 0x00;
251                 buf1[2] = 0x7e;
252                 msgs[0].addr = client->addr;
253                 msgs[0].flags = 0;
254                 msgs[0].len = 3;
255                 msgs[0].buf = buf1;
256                 msgs[1].addr = client->addr;
257                 msgs[1].flags = I2C_M_RD;
258                 msgs[1].len = 2;
259                 msgs[1].buf = buf2;
260                 i2c_transfer(client->adapter, msgs, 2);
261                 v4l2_info(client, "MPX system: %02x%02x\n",
262                                 buf2[0], buf2[1]);
263                 buf1[0] = 0x11;
264                 buf1[1] = 0x02;
265                 buf1[2] = 0x00;
266                 i2c_transfer(client->adapter, msgs, 2);
267                 v4l2_info(client, "MPX status: %02x%02x\n",
268                                 buf2[0], buf2[1]);
269         }
270 #endif
271         return 0;
272 }
273
274
275 static int sony_btf_mpx_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
276 {
277         struct sony_btf_mpx *t = to_state(sd);
278         int default_mpx_mode = 0;
279
280         if (std & V4L2_STD_PAL_BG)
281                 default_mpx_mode = 1;
282         else if (std & V4L2_STD_PAL_I)
283                 default_mpx_mode = 4;
284         else if (std & V4L2_STD_PAL_DK)
285                 default_mpx_mode = 6;
286         else if (std & V4L2_STD_SECAM_L)
287                 default_mpx_mode = 11;
288
289         if (default_mpx_mode != t->mpxmode) {
290                 t->mpxmode = default_mpx_mode;
291                 mpx_setup(t);
292         }
293         return 0;
294 }
295
296 static int sony_btf_mpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
297 {
298         struct sony_btf_mpx *t = to_state(sd);
299
300         vt->capability = V4L2_TUNER_CAP_NORM |
301                 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
302                 V4L2_TUNER_CAP_LANG2;
303         vt->rxsubchans = V4L2_TUNER_SUB_MONO |
304                 V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
305                 V4L2_TUNER_SUB_LANG2;
306         vt->audmode = t->audmode;
307         return 0;
308 }
309
310 static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
311 {
312         struct sony_btf_mpx *t = to_state(sd);
313
314         if (vt->type != V4L2_TUNER_ANALOG_TV)
315                 return -EINVAL;
316
317         if (vt->audmode != t->audmode) {
318                 t->audmode = vt->audmode;
319                 mpx_setup(t);
320         }
321         return 0;
322 }
323
324 /* --------------------------------------------------------------------------*/
325
326 static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
327         .s_tuner = sony_btf_mpx_s_tuner,
328         .g_tuner = sony_btf_mpx_g_tuner,
329 };
330
331 static const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = {
332         .s_std = sony_btf_mpx_s_std,
333 };
334
335 static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
336         .tuner = &sony_btf_mpx_tuner_ops,
337         .video = &sony_btf_mpx_video_ops,
338 };
339
340 /* --------------------------------------------------------------------------*/
341
342 static int sony_btf_mpx_probe(struct i2c_client *client,
343                                 const struct i2c_device_id *id)
344 {
345         struct sony_btf_mpx *t;
346         struct v4l2_subdev *sd;
347
348         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
349                 return -ENODEV;
350
351         v4l_info(client, "chip found @ 0x%x (%s)\n",
352                         client->addr << 1, client->adapter->name);
353
354         t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
355         if (t == NULL)
356                 return -ENOMEM;
357
358         sd = &t->sd;
359         v4l2_i2c_subdev_init(sd, client, &sony_btf_mpx_ops);
360
361         /* Initialize sony_btf_mpx */
362         t->mpxmode = 0;
363         t->audmode = V4L2_TUNER_MODE_STEREO;
364
365         return 0;
366 }
367
368 static int sony_btf_mpx_remove(struct i2c_client *client)
369 {
370         struct v4l2_subdev *sd = i2c_get_clientdata(client);
371
372         v4l2_device_unregister_subdev(sd);
373
374         return 0;
375 }
376
377 /* ----------------------------------------------------------------------- */
378
379 static const struct i2c_device_id sony_btf_mpx_id[] = {
380         { "sony-btf-mpx", 0 },
381         { }
382 };
383 MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
384
385 static struct i2c_driver sony_btf_mpx_driver = {
386         .driver = {
387                 .name   = "sony-btf-mpx",
388         },
389         .probe = sony_btf_mpx_probe,
390         .remove = sony_btf_mpx_remove,
391         .id_table = sony_btf_mpx_id,
392 };
393 module_i2c_driver(sony_btf_mpx_driver);