]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/radio/radio-tea5761.c
Merge omap-drivers
[linux-2.6-omap-h63xx.git] / drivers / media / radio / radio-tea5761.c
1 /*
2  * drivers/media/radio/radio-tea5761.c
3  *
4  * Copyright (C) 2005 Nokia Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  */
20 #include <linux/module.h>
21 #include <linux/version.h>
22 #include <linux/init.h>
23 #include <linux/i2c.h>
24 #include <linux/delay.h>
25 #include <media/v4l2-common.h>
26 #include <asm/arch/gpio.h>
27 #include <asm/arch/board.h>
28
29 #define DRIVER_NAME "tea5761"
30
31 #define TEA5761_VERSION         KERNEL_VERSION(0, 0, 1)
32
33 #define TEA5761_I2C_ADDR        0x10
34
35 #define TEA5761_MANID           0x002b
36 #define TEA5761_CHIPID          0x5761
37
38 #define TEA5761_INTREG_BLMSK    0x0001
39 #define TEA5761_INTREG_FRRMSK   0x0002
40 #define TEA5761_INTREG_LEVMSK   0x0008
41 #define TEA5761_INTREG_IFMSK    0x0010
42 #define TEA5761_INTREG_BLMFLAG  0x0100
43 #define TEA5761_INTREG_FRRFLAG  0x0200
44 #define TEA5761_INTREG_LEVFLAG  0x0800
45 #define TEA5761_INTREG_IFFLAG   0x1000
46
47 #define TEA5761_FRQSET_SUD      0x8000
48 #define TEA5761_FRQSET_SM       0x4000
49
50 #define TEA5761_TNCTRL_PUPD0    0x4000
51 #define TEA5761_TNCTRL_BLIM     0x2000
52 #define TEA5761_TNCTRL_SWPM     0x1000
53 #define TEA5761_TNCTRL_IFCTC    0x0800
54 #define TEA5761_TNCTRL_AFM      0x0400
55 #define TEA5761_TNCTRL_SMUTE    0x0200
56 #define TEA5761_TNCTRL_SNC      0x0100
57 #define TEA5761_TNCTRL_MU       0x0080
58 #define TEA5761_TNCTRL_SSL1     0x0040
59 #define TEA5761_TNCTRL_SSL0     0x0020
60 #define TEA5761_TNCTRL_HLSI     0x0010
61 #define TEA5761_TNCTRL_MST      0x0008
62 #define TEA5761_TNCTRL_SWP      0x0004
63 #define TEA5761_TNCTRL_DTC      0x0002
64 #define TEA5761_TNCTRL_AHLSI    0x0001
65
66 #define TEA5761_TUNCHK_LEVEL(x) (((x) & 0x00F0) >> 4)
67 #define TEA5761_TUNCHK_IFCNT(x) (((x) & 0xFE00) >> 9)
68 #define TEA5761_TUNCHK_TUNTO    0x0100
69 #define TEA5761_TUNCHK_LD       0x0008
70 #define TEA5761_TUNCHK_STEREO   0x0004
71
72 #define TEA5761_TESTREG_TRIGFR  0x0800
73
74 #define TEA5761_FREQ_LOW        87500
75 #define TEA5761_FREQ_HIGH       108000
76
77 /* Probe for TEA5761 twice since the version N4B seems to be
78  * broken and needs two probes to be found */
79 static unsigned short normal_i2c[] = {
80         TEA5761_I2C_ADDR, TEA5761_I2C_ADDR, I2C_CLIENT_END
81 };
82
83 I2C_CLIENT_INSMOD;
84
85 struct tea5761_regs {
86         u16 intreg;
87         u16 frqset;
88         u16 tnctrl;
89         u16 frqchk;
90         u16 tunchk;
91         u16 testreg;
92         u16 manid;
93         u16 chipid;
94 } __attribute__ ((packed));
95
96 struct tea5761_write_regs {
97         u8 intreg;
98         u16 frqset;
99         u16 tnctrl;
100         u16 testreg;
101 } __attribute__ ((packed));
102
103 struct tea5761_device {
104         struct video_device     *video_dev;
105         struct i2c_client       *i2c_dev;
106         struct tea5761_regs     regs;
107         struct mutex            mutex;
108         int                     users;
109 };
110
111 static struct tea5761_device tea5761;
112
113 static struct i2c_driver        tea5761_driver;
114 static int radio_nr = -1;
115
116 static int tea5761_read_regs(struct tea5761_device *tea)
117 {
118         int rc, i;
119         u16 *p = (u16 *) &tea->regs;
120         struct i2c_client *client = tea->i2c_dev;
121
122         rc = i2c_master_recv(client, (void*) &tea->regs, sizeof(tea->regs));
123         for (i = 0; i < 8; i++) {
124                 p[i] = __be16_to_cpu(p[i]);
125         }
126
127         dev_dbg(&client->dev,
128                 "chip state: %04x %04x %04x %04x %04x %04x %04x %04x\n",
129                 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
130
131         if (rc < 0)
132                 dev_err(&client->dev, "read\n");
133
134         return rc;
135 }
136
137 static void tea5761_write_regs(struct tea5761_device *tea)
138 {
139         struct tea5761_write_regs wr;
140         struct tea5761_regs *r = &tea->regs;
141         struct i2c_client *client = tea->i2c_dev;
142 #ifdef DEBUG
143         u8 *p = (u8 *) r;
144 #endif
145
146         wr.intreg = r->intreg & 0xff;
147         wr.frqset = __cpu_to_be16(r->frqset);
148         wr.tnctrl = __cpu_to_be16(r->tnctrl);
149         wr.testreg = __cpu_to_be16(r->testreg);
150
151         dev_dbg(&client->dev,
152                 "writing state: %02x %02x %02x %02x %02x %02x %02x\n",
153                 p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
154         if (i2c_master_send(client, (void *) &wr, sizeof(wr)) < 0)
155                 dev_err(&client->dev, "write\n");
156 }
157
158 static void tea5761_power_up(struct tea5761_device *tea)
159 {
160         struct tea5761_regs *r = &tea->regs;
161
162         if (!(r->tnctrl & TEA5761_TNCTRL_PUPD0)) {
163                 r->tnctrl &= ~(TEA5761_TNCTRL_AFM | TEA5761_TNCTRL_MU |
164                                TEA5761_TNCTRL_HLSI);
165                 r->testreg |= TEA5761_TESTREG_TRIGFR;
166                 r->tnctrl |= TEA5761_TNCTRL_PUPD0;
167                 return tea5761_write_regs(tea);
168         }
169 }
170
171 static void tea5761_power_down(struct tea5761_device *tea)
172 {
173         struct tea5761_regs *r = &tea->regs;
174
175         if (r->tnctrl & TEA5761_TNCTRL_PUPD0) {
176                 r->tnctrl &= ~TEA5761_TNCTRL_PUPD0;
177                 return tea5761_write_regs(tea);
178         }
179 }
180
181 static void tea5761_set_freq(struct tea5761_device *tea, int freq)
182 {
183         struct tea5761_regs *r = &tea->regs;
184
185         if (r->tnctrl & TEA5761_TNCTRL_HLSI)
186                 r->frqset = (freq + 225000) / 8192;
187         else
188                 r->frqset = (freq - 225000) / 8192;
189 }
190
191 static int tea5761_get_freq(struct tea5761_device *tea)
192 {
193         struct tea5761_regs *r = &tea->regs;
194
195         if (r->tnctrl & TEA5761_TNCTRL_HLSI)
196                 return (r->frqchk * 8192) - 225000;
197         else
198                 return (r->frqchk * 8192) + 225000;
199 }
200
201 static void tea5761_tune(struct tea5761_device *tea, int freq)
202 {
203         tea5761_set_freq(tea, freq);
204         tea5761_write_regs(tea);
205 }
206
207 static void tea5761_set_audout_mode(struct tea5761_device *tea, int audmode)
208 {
209         struct tea5761_regs *r = &tea->regs;
210         int tnctrl = r->tnctrl;
211
212         if (audmode == V4L2_TUNER_MODE_MONO)
213                 r->tnctrl |= TEA5761_TNCTRL_MST;
214         else
215                 r->tnctrl &= ~TEA5761_TNCTRL_MST;
216         if (tnctrl != r->tnctrl)
217                 tea5761_write_regs(tea);
218 }
219
220 static int tea5761_get_audout_mode(struct tea5761_device *tea)
221 {
222         struct tea5761_regs *r = &tea->regs;
223
224         if (r->tnctrl & TEA5761_TNCTRL_MST)
225                 return V4L2_TUNER_MODE_MONO;
226         else
227                 return V4L2_TUNER_MODE_STEREO;
228 }
229
230 static void tea5761_mute(struct tea5761_device *tea, int on)
231 {
232         struct tea5761_regs *r = &tea->regs;
233         int tnctrl = r->tnctrl;
234
235         if (on)
236                 r->tnctrl |= TEA5761_TNCTRL_MU;
237         else
238                 r->tnctrl &= ~TEA5761_TNCTRL_MU;
239         if (tnctrl != r->tnctrl)
240                 tea5761_write_regs(tea);
241 }
242
243 static int tea5761_is_muted(struct tea5761_device *tea)
244 {
245         return tea->regs.tnctrl & TEA5761_TNCTRL_MU;
246 }
247
248 static int tea5761_do_ioctl(struct inode *inode, struct file *file,
249                             unsigned int cmd, void *arg)
250 {
251         struct tea5761_device *tea = file->private_data;
252         struct video_device *dev = tea->video_dev;
253         struct i2c_client *client = tea->i2c_dev;
254         struct tea5761_regs *r = &tea->regs;
255
256         union {
257                 struct v4l2_capability c;
258                 struct v4l2_tuner t;
259                 struct v4l2_frequency f;
260                 struct v4l2_queryctrl qc;
261                 struct v4l2_control ct;
262         } *u = arg;
263
264         tea5761_read_regs(tea);
265
266         switch (cmd) {
267         case VIDIOC_QUERYCAP:
268                 dev_dbg(&client->dev, "VIDIOC_QUERYCAP\n");
269                 memset(&u->c, 0, sizeof(u->c));
270                 strlcpy(u->c.driver, dev->dev->driver->name,
271                         sizeof(u->c.driver));
272                 strlcpy(u->c.card, dev->name, sizeof(u->c.card));
273                 snprintf(u->c.bus_info, sizeof(u->c.bus_info), "I2C:%s",
274                          dev->dev->bus_id);
275                 u->c.version = TEA5761_VERSION;
276                 u->c.capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
277                 break;
278
279         case VIDIOC_G_TUNER:
280                 /* Only one tuner chip */
281                 dev_dbg(&client->dev, "VIDIOC_G_TUNER\n");
282                 if (u->t.index != 0)
283                         return -EINVAL;
284
285                 memset(&u->t, 0, sizeof(u->t));
286                 u->t.type = V4L2_TUNER_RADIO;
287                 strlcpy(u->t.name, "FM", sizeof(u->t.name));
288                 /* Freq in 62.5Hz units */
289                 u->t.rangelow = TEA5761_FREQ_LOW * 16;
290                 u->t.rangehigh = TEA5761_FREQ_HIGH * 16;
291                 u->t.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
292                 if (r->tunchk & TEA5761_TUNCHK_STEREO)
293                         u->t.rxsubchans = V4L2_TUNER_SUB_STEREO;
294                 u->t.audmode = tea5761_get_audout_mode(tea);
295                 u->t.signal = TEA5761_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf;
296                 u->t.afc = TEA5761_TUNCHK_IFCNT(r->tunchk);
297                 break;
298
299         case VIDIOC_S_TUNER:
300                 /* Only tuner nro 0 can be selected. */
301                 dev_dbg(&client->dev, "VIDIOC_S_TUNER\n");
302                 if (u->t.index != 0)
303                         return -EINVAL;
304                 tea5761_set_audout_mode(tea, u->t.audmode);
305                 break;
306
307         case VIDIOC_G_FREQUENCY:
308                 dev_dbg(&client->dev, "VIDIOC_G_FREQUENCY\n");
309                 memset(&u->f, 0, sizeof(u->f));
310                 u->f.type = V4L2_TUNER_RADIO;
311                 if (r->tnctrl & TEA5761_TNCTRL_PUPD0)
312                         u->f.frequency = (tea5761_get_freq(tea) * 2) / 125;
313                 else
314                         u->f.frequency = 0;
315                 break;
316
317         case VIDIOC_S_FREQUENCY:
318                 dev_dbg(&client->dev, "VIDIOC_S_FREQUENCY %u\n",
319                         u->f.frequency);
320                 if (u->f.tuner != 0)
321                         return -EINVAL;
322                 if (u->f.frequency == 0) {
323                         /* We special case this as a power down
324                          * control. */
325                         tea5761_power_down(tea);
326                         break;
327                 }
328                 if (u->f.frequency < 16 * TEA5761_FREQ_LOW)
329                         return -EINVAL;
330                 if (u->f.frequency > 16 * TEA5761_FREQ_HIGH)
331                         return -EINVAL;
332
333                 tea5761_power_up(tea);
334                 tea5761_tune(tea, (u->f.frequency * 125) / 2);
335                 break;
336
337         case VIDIOC_QUERYCTRL:
338                 dev_dbg(&client->dev, "VIDIOC_QUERYCTRL %d\n", u->qc.id);
339                 if (u->qc.id != V4L2_CID_AUDIO_MUTE)
340                         return -EINVAL;
341                 strlcpy(u->qc.name, "Mute", sizeof(u->qc.name));
342                 u->qc.minimum = 0;
343                 u->qc.maximum = 1;
344                 u->qc.step = 1;
345                 u->qc.default_value = 0;
346                 u->qc.type = V4L2_CTRL_TYPE_BOOLEAN;
347                 break;
348
349         case VIDIOC_G_CTRL:
350                 dev_dbg(&client->dev, "VIDIOC_G_CTRL %d\n", u->ct.id);
351                 if (u->ct.id != V4L2_CID_AUDIO_MUTE)
352                         return -EINVAL;
353                 if (r->tnctrl & TEA5761_TNCTRL_PUPD0)
354                         u->ct.value = tea5761_is_muted(tea) ? 1 : 0;
355                 else
356                         u->ct.value = 0;
357                 break;
358
359         case VIDIOC_S_CTRL:
360                 dev_dbg(&client->dev, "VIDIOC_S_CTRL %d\n", u->ct.id);
361                 if (u->ct.id != V4L2_CID_AUDIO_MUTE)
362                         return -EINVAL;
363                 tea5761_mute(tea, u->ct.value);
364                 break;
365
366         default:
367                 return -ENOIOCTLCMD;
368         }
369
370         return 0;
371 }
372
373 static int tea5761_ioctl(struct inode *inode, struct file *file,
374                          unsigned int cmd, unsigned long arg)
375 {
376         return video_usercopy(inode, file, cmd, arg, tea5761_do_ioctl);
377 }
378
379 static int tea5761_open(struct inode *inode, struct file *file)
380 {
381         int minor = iminor(file->f_dentry->d_inode);
382         /* Currently we support only one device */
383         struct tea5761_device *tea = &tea5761;
384
385         if (tea->video_dev->minor != minor)
386                 return -ENODEV;
387
388         mutex_lock(&tea->mutex);
389         /* Only exclusive access */
390         if (tea->users) {
391                 mutex_unlock(&tea->mutex);
392                 return -EBUSY;
393         }
394         tea->users++;
395         mutex_unlock(&tea->mutex);
396
397         file->private_data = tea;
398         return 0;
399 }
400
401 static int tea5761_release(struct inode *inode, struct file *file)
402 {
403         struct tea5761_device *tea = file->private_data;
404
405         mutex_lock(&tea->mutex);
406         tea->users--;
407         mutex_unlock(&tea->mutex);
408
409         return 0;
410 }
411
412 static struct file_operations tea5761_fops = {
413         .owner          = THIS_MODULE,
414         .open           = tea5761_open,
415         .release        = tea5761_release,
416         .ioctl          = tea5761_ioctl,
417         .llseek         = no_llseek,
418 };
419
420 static struct video_device tea5761_video_device = {
421         .owner         = THIS_MODULE,
422         .name          = "TEA5761 FM-Radio",
423         .type          = VID_TYPE_TUNER,
424         .hardware      = 40 /* VID_HARDWARE_TEA5761UK */,
425         .fops          = &tea5761_fops,
426         .release       = video_device_release
427 };
428
429 static int tea5761_probe(struct i2c_adapter *adapter, int address,
430                           int kind)
431 {
432         struct i2c_client *client;
433         struct video_device *video_dev;
434         int err = 0;
435         static const char *client_name = "TEA5761 FM-Radio";
436         struct tea5761_device *tea = &tea5761;
437         struct tea5761_regs   *r = &tea->regs;
438
439         mutex_init(&tea->mutex);
440         /* I2C detection and initialization */
441         client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
442         if (client == NULL) {
443                 dev_err(&adapter->dev, DRIVER_NAME
444                         ": couldn't allocate memory\n");
445                 return -ENOMEM;
446         }
447         tea->i2c_dev = client;
448
449         client->addr = address;
450         client->adapter = adapter;
451         client->driver = &tea5761_driver;
452         client->dev.driver = &tea5761_driver.driver;
453         client->flags = 0;
454         strlcpy(client->name, client_name, I2C_NAME_SIZE);
455
456         if (kind < 0) {
457                 if (tea5761_read_regs(tea) < 0) {
458                         dev_info(&client->dev,
459                                  "chip read failed for %d-%04x\n",
460                                  adapter->nr, address);
461                         goto err_tea_dev;
462                 }
463                 if (r->chipid != TEA5761_CHIPID) {
464                         dev_info(&client->dev,
465                                  "bad chipid (0x%04x) at %d-%04x\n",
466                                  r->chipid, adapter->nr, address);
467                         goto err_tea_dev;
468                 }
469                 if ((r->manid & 0x0fff) != TEA5761_MANID) {
470                         dev_info(&client->dev,
471                                  "bad manid (0x%04x) at %d-%04x\n",
472                                  r->manid, adapter->nr, address);
473                         goto err_tea_dev;
474                 }
475         }
476
477         err = i2c_attach_client(client);
478         if (err) {
479                 dev_err(&client->dev, "couldn't attach to address %d-%04x\n",
480                         adapter->nr, address);
481                 goto err_tea_dev;
482         }
483
484         /* V4L initialization */
485         video_dev = video_device_alloc();
486         if (video_dev == NULL) {
487                 dev_err(&client->dev, "couldn't allocate memory\n");
488                 err = -ENOMEM;
489                 goto err_i2c_attach;
490         }
491         tea->video_dev = video_dev;
492
493         *video_dev = tea5761_video_device;
494         video_dev->dev = &client->dev;
495         i2c_set_clientdata(client, video_dev);
496
497         /* initialize and power off the chip */
498         tea5761_read_regs(tea);
499         tea5761_set_audout_mode(tea, V4L2_TUNER_MODE_STEREO);
500         tea5761_mute(tea, 0);
501         tea5761_power_down(tea);
502
503         tea5761.video_dev = video_dev;
504         tea5761.i2c_dev = client;
505
506         err = video_register_device(video_dev, VFL_TYPE_RADIO, radio_nr);
507         if (err) {
508                 dev_err(&client->dev, "couldn't register video device\n");
509                 goto err_video_alloc;
510         }
511
512         dev_info(&client->dev, "tea5761 (version %d) detected at %d-%04x\n",
513                 (tea->regs.manid >> 12) & 0xf, adapter->nr, address);
514
515         return 0;
516
517 err_video_alloc:
518         video_device_release(video_dev);
519 err_i2c_attach:
520         i2c_detach_client(client);
521 err_tea_dev:
522         kfree(client);
523         return err;
524 }
525
526 static int tea5761_attach_adapter(struct i2c_adapter *adapter)
527 {
528         if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
529                 return -EINVAL;
530
531         return i2c_probe(adapter, &addr_data, tea5761_probe);
532 }
533
534 static int tea5761_detach_client(struct i2c_client *client)
535 {
536         struct video_device *vd = i2c_get_clientdata(client);
537
538         i2c_detach_client(client);
539         video_unregister_device(vd);
540         kfree(client);
541
542         return 0;
543 }
544
545 static struct i2c_driver tea5761_driver = {
546         .id             = I2C_DRIVERID_TUNER,
547         .driver = {
548                 .name   = DRIVER_NAME,
549         },
550         .attach_adapter = tea5761_attach_adapter,
551         .detach_client  = tea5761_detach_client,
552 };
553
554 #if CONFIG_ARCH_OMAP
555 /* No way to pass platform device data. Enable here all the TEA5761
556  * devices, since I2C address scanning will need them to respond.
557  */
558 static int enable_gpio;
559
560 static int __init tea5761_dev_init(void)
561 {
562         const struct omap_tea5761_config *info;
563
564         info = omap_get_config(OMAP_TAG_TEA5761, struct omap_tea5761_config);
565         if (info) {
566                 enable_gpio = info->enable_gpio;
567         }
568
569         if (enable_gpio) {
570                 pr_debug(DRIVER_NAME ": enabling tea5761 at GPIO %d\n",
571                          enable_gpio);
572
573                 if (omap_request_gpio(enable_gpio) < 0) {
574                         printk(KERN_ERR DRIVER_NAME ": can't request GPIO %d\n",
575                                enable_gpio);
576                         return -ENODEV;
577                 }
578
579                 omap_set_gpio_direction(enable_gpio, 0);
580                 udelay(50);
581                 omap_set_gpio_dataout(enable_gpio, 1);
582         }
583
584         return 0;
585 }
586
587 static void __exit tea5761_dev_exit(void)
588 {
589         if (enable_gpio) {
590                 omap_set_gpio_dataout(enable_gpio, 0);
591                 omap_free_gpio(enable_gpio);
592         }
593 }
594 #else
595 static int __init tea5761_dev_init(void)
596 {
597 }
598
599 static void __exit tea5761_dev_exit(void)
600 {
601 }
602 #endif
603
604 static int __init tea5761_init(void)
605 {
606         int res;
607
608         if ((res = tea5761_dev_init()) < 0)
609                 return res;
610
611         if ((res = i2c_add_driver(&tea5761_driver))) {
612                 printk(KERN_ERR DRIVER_NAME ": driver registration failed\n");
613                 return res;
614         }
615
616         return 0;
617 }
618
619 static void __exit tea5761_exit(void)
620 {
621         int res;
622
623         if ((res = i2c_del_driver(&tea5761_driver)))
624                 printk(KERN_ERR DRIVER_NAME ": i2c driver removal failed\n");
625         tea5761_dev_exit();
626 }
627
628 MODULE_AUTHOR("Timo Teräs");
629 MODULE_DESCRIPTION("I2C interface for TEA5761.");
630 MODULE_LICENSE("GPL");
631
632 module_param(radio_nr, int, 0);
633 MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
634
635 module_init(tea5761_init)
636 module_exit(tea5761_exit)