PRCM: 34XX: Fix wrong shift value used in dpll4_m4x2_ck enable bit
[linux-ginger.git] / drivers / media / radio / radio-tea5761.c
blobe8ccf29273f69c0d36257390eb8e3d704e23c029
1 /*
2 * drivers/media/radio/radio-tea5761.c
4 * Copyright (C) 2005 Nokia Corporation
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.
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.
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
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>
27 #define DRIVER_NAME "tea5761"
29 #define TEA5761_VERSION KERNEL_VERSION(0, 0, 1)
31 #define TEA5761_I2C_ADDR 0x10
33 #define TEA5761_MANID 0x002b
34 #define TEA5761_CHIPID 0x5761
36 #define TEA5761_INTREG_BLMSK 0x0001
37 #define TEA5761_INTREG_FRRMSK 0x0002
38 #define TEA5761_INTREG_LEVMSK 0x0008
39 #define TEA5761_INTREG_IFMSK 0x0010
40 #define TEA5761_INTREG_BLMFLAG 0x0100
41 #define TEA5761_INTREG_FRRFLAG 0x0200
42 #define TEA5761_INTREG_LEVFLAG 0x0800
43 #define TEA5761_INTREG_IFFLAG 0x1000
45 #define TEA5761_FRQSET_SUD 0x8000
46 #define TEA5761_FRQSET_SM 0x4000
48 #define TEA5761_TNCTRL_PUPD0 0x4000
49 #define TEA5761_TNCTRL_BLIM 0x2000
50 #define TEA5761_TNCTRL_SWPM 0x1000
51 #define TEA5761_TNCTRL_IFCTC 0x0800
52 #define TEA5761_TNCTRL_AFM 0x0400
53 #define TEA5761_TNCTRL_SMUTE 0x0200
54 #define TEA5761_TNCTRL_SNC 0x0100
55 #define TEA5761_TNCTRL_MU 0x0080
56 #define TEA5761_TNCTRL_SSL1 0x0040
57 #define TEA5761_TNCTRL_SSL0 0x0020
58 #define TEA5761_TNCTRL_HLSI 0x0010
59 #define TEA5761_TNCTRL_MST 0x0008
60 #define TEA5761_TNCTRL_SWP 0x0004
61 #define TEA5761_TNCTRL_DTC 0x0002
62 #define TEA5761_TNCTRL_AHLSI 0x0001
64 #define TEA5761_TUNCHK_LEVEL(x) (((x) & 0x00F0) >> 4)
65 #define TEA5761_TUNCHK_IFCNT(x) (((x) & 0xFE00) >> 9)
66 #define TEA5761_TUNCHK_TUNTO 0x0100
67 #define TEA5761_TUNCHK_LD 0x0008
68 #define TEA5761_TUNCHK_STEREO 0x0004
70 #define TEA5761_TESTREG_TRIGFR 0x0800
72 #define TEA5761_FREQ_LOW 87500
73 #define TEA5761_FREQ_HIGH 108000
75 struct tea5761_regs {
76 u16 intreg;
77 u16 frqset;
78 u16 tnctrl;
79 u16 frqchk;
80 u16 tunchk;
81 u16 testreg;
82 u16 manid;
83 u16 chipid;
84 } __attribute__ ((packed));
86 struct tea5761_write_regs {
87 u8 intreg;
88 u16 frqset;
89 u16 tnctrl;
90 u16 testreg;
91 } __attribute__ ((packed));
93 struct tea5761_device {
94 struct video_device *video_dev;
95 struct i2c_client *i2c_dev;
96 struct tea5761_regs regs;
97 struct mutex mutex;
98 int users;
101 static struct tea5761_device tea5761;
103 static struct i2c_driver tea5761_driver;
104 static int radio_nr = -1;
106 static int tea5761_read_regs(struct tea5761_device *tea)
108 int rc, i;
109 u16 *p = (u16 *) &tea->regs;
110 struct i2c_client *client = tea->i2c_dev;
112 rc = i2c_master_recv(client, (void*) &tea->regs, sizeof(tea->regs));
113 for (i = 0; i < 8; i++) {
114 p[i] = __be16_to_cpu(p[i]);
117 dev_dbg(&client->dev,
118 "chip state: %04x %04x %04x %04x %04x %04x %04x %04x\n",
119 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
121 if (rc < 0)
122 dev_err(&client->dev, "read\n");
124 return rc;
127 static void tea5761_write_regs(struct tea5761_device *tea)
129 struct tea5761_write_regs wr;
130 struct tea5761_regs *r = &tea->regs;
131 struct i2c_client *client = tea->i2c_dev;
132 u8 *p = (u8 *) r;
134 wr.intreg = r->intreg & 0xff;
135 wr.frqset = __cpu_to_be16(r->frqset);
136 wr.tnctrl = __cpu_to_be16(r->tnctrl);
137 wr.testreg = __cpu_to_be16(r->testreg);
139 dev_dbg(&client->dev,
140 "writing state: %02x %02x %02x %02x %02x %02x %02x\n",
141 p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
142 if (i2c_master_send(client, (void *) &wr, sizeof(wr)) < 0)
143 dev_err(&client->dev, "write\n");
146 static void tea5761_power_up(struct tea5761_device *tea)
148 struct tea5761_regs *r = &tea->regs;
150 if (!(r->tnctrl & TEA5761_TNCTRL_PUPD0)) {
151 r->tnctrl &= ~(TEA5761_TNCTRL_AFM | TEA5761_TNCTRL_MU |
152 TEA5761_TNCTRL_HLSI);
153 r->testreg |= TEA5761_TESTREG_TRIGFR;
154 r->tnctrl |= TEA5761_TNCTRL_PUPD0;
155 return tea5761_write_regs(tea);
159 static void tea5761_power_down(struct tea5761_device *tea)
161 struct tea5761_regs *r = &tea->regs;
163 if (r->tnctrl & TEA5761_TNCTRL_PUPD0) {
164 r->tnctrl &= ~TEA5761_TNCTRL_PUPD0;
165 return tea5761_write_regs(tea);
169 static void tea5761_set_freq(struct tea5761_device *tea, int freq)
171 struct tea5761_regs *r = &tea->regs;
173 if (r->tnctrl & TEA5761_TNCTRL_HLSI)
174 r->frqset = (freq + 225000) / 8192;
175 else
176 r->frqset = (freq - 225000) / 8192;
179 static int tea5761_get_freq(struct tea5761_device *tea)
181 struct tea5761_regs *r = &tea->regs;
183 if (r->tnctrl & TEA5761_TNCTRL_HLSI)
184 return (r->frqchk * 8192) - 225000;
185 else
186 return (r->frqchk * 8192) + 225000;
189 static void tea5761_tune(struct tea5761_device *tea, int freq)
191 tea5761_set_freq(tea, freq);
192 tea5761_write_regs(tea);
195 static void tea5761_set_audout_mode(struct tea5761_device *tea, int audmode)
197 struct tea5761_regs *r = &tea->regs;
198 int tnctrl = r->tnctrl;
200 if (audmode == V4L2_TUNER_MODE_MONO)
201 r->tnctrl |= TEA5761_TNCTRL_MST;
202 else
203 r->tnctrl &= ~TEA5761_TNCTRL_MST;
204 if (tnctrl != r->tnctrl)
205 tea5761_write_regs(tea);
208 static int tea5761_get_audout_mode(struct tea5761_device *tea)
210 struct tea5761_regs *r = &tea->regs;
212 if (r->tnctrl & TEA5761_TNCTRL_MST)
213 return V4L2_TUNER_MODE_MONO;
214 else
215 return V4L2_TUNER_MODE_STEREO;
218 static void tea5761_mute(struct tea5761_device *tea, int on)
220 struct tea5761_regs *r = &tea->regs;
221 int tnctrl = r->tnctrl;
223 if (on)
224 r->tnctrl |= TEA5761_TNCTRL_MU;
225 else
226 r->tnctrl &= ~TEA5761_TNCTRL_MU;
227 if (tnctrl != r->tnctrl)
228 tea5761_write_regs(tea);
231 static int tea5761_is_muted(struct tea5761_device *tea)
233 return tea->regs.tnctrl & TEA5761_TNCTRL_MU;
236 static int tea5761_do_ioctl(struct inode *inode, struct file *file,
237 unsigned int cmd, void *arg)
239 struct tea5761_device *tea = file->private_data;
240 struct video_device *dev = tea->video_dev;
241 struct i2c_client *client = tea->i2c_dev;
242 struct tea5761_regs *r = &tea->regs;
244 union {
245 struct v4l2_capability c;
246 struct v4l2_tuner t;
247 struct v4l2_frequency f;
248 struct v4l2_queryctrl qc;
249 struct v4l2_control ct;
250 } *u = arg;
252 tea5761_read_regs(tea);
254 switch (cmd) {
255 case VIDIOC_QUERYCAP:
256 dev_dbg(&client->dev, "VIDIOC_QUERYCAP\n");
257 memset(&u->c, 0, sizeof(u->c));
258 strlcpy(u->c.driver, dev->dev->driver->name,
259 sizeof(u->c.driver));
260 strlcpy(u->c.card, dev->name, sizeof(u->c.card));
261 snprintf(u->c.bus_info, sizeof(u->c.bus_info), "I2C:%s",
262 dev->dev->bus_id);
263 u->c.version = TEA5761_VERSION;
264 u->c.capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
265 break;
267 case VIDIOC_G_TUNER:
268 /* Only one tuner chip */
269 dev_dbg(&client->dev, "VIDIOC_G_TUNER\n");
270 if (u->t.index != 0)
271 return -EINVAL;
273 memset(&u->t, 0, sizeof(u->t));
274 u->t.type = V4L2_TUNER_RADIO;
275 strlcpy(u->t.name, "FM", sizeof(u->t.name));
276 /* Freq in 62.5Hz units */
277 u->t.rangelow = TEA5761_FREQ_LOW * 16;
278 u->t.rangehigh = TEA5761_FREQ_HIGH * 16;
279 u->t.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
280 if (r->tunchk & TEA5761_TUNCHK_STEREO)
281 u->t.rxsubchans = V4L2_TUNER_SUB_STEREO;
282 u->t.audmode = tea5761_get_audout_mode(tea);
283 u->t.signal = TEA5761_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf;
284 u->t.afc = TEA5761_TUNCHK_IFCNT(r->tunchk);
285 break;
287 case VIDIOC_S_TUNER:
288 /* Only tuner nro 0 can be selected. */
289 dev_dbg(&client->dev, "VIDIOC_S_TUNER\n");
290 if (u->t.index != 0)
291 return -EINVAL;
292 tea5761_set_audout_mode(tea, u->t.audmode);
293 break;
295 case VIDIOC_G_FREQUENCY:
296 dev_dbg(&client->dev, "VIDIOC_G_FREQUENCY\n");
297 memset(&u->f, 0, sizeof(u->f));
298 u->f.type = V4L2_TUNER_RADIO;
299 if (r->tnctrl & TEA5761_TNCTRL_PUPD0)
300 u->f.frequency = (tea5761_get_freq(tea) * 2) / 125;
301 else
302 u->f.frequency = 0;
303 break;
305 case VIDIOC_S_FREQUENCY:
306 dev_dbg(&client->dev, "VIDIOC_S_FREQUENCY %u\n",
307 u->f.frequency);
308 if (u->f.tuner != 0)
309 return -EINVAL;
310 if (u->f.frequency == 0) {
311 /* We special case this as a power down
312 * control. */
313 tea5761_power_down(tea);
314 break;
316 if (u->f.frequency < 16 * TEA5761_FREQ_LOW)
317 return -EINVAL;
318 if (u->f.frequency > 16 * TEA5761_FREQ_HIGH)
319 return -EINVAL;
321 tea5761_power_up(tea);
322 tea5761_tune(tea, (u->f.frequency * 125) / 2);
323 break;
325 case VIDIOC_QUERYCTRL:
326 dev_dbg(&client->dev, "VIDIOC_QUERYCTRL %d\n", u->qc.id);
327 if (u->qc.id != V4L2_CID_AUDIO_MUTE)
328 return -EINVAL;
329 strlcpy(u->qc.name, "Mute", sizeof(u->qc.name));
330 u->qc.minimum = 0;
331 u->qc.maximum = 1;
332 u->qc.step = 1;
333 u->qc.default_value = 0;
334 u->qc.type = V4L2_CTRL_TYPE_BOOLEAN;
335 break;
337 case VIDIOC_G_CTRL:
338 dev_dbg(&client->dev, "VIDIOC_G_CTRL %d\n", u->ct.id);
339 if (u->ct.id != V4L2_CID_AUDIO_MUTE)
340 return -EINVAL;
341 if (r->tnctrl & TEA5761_TNCTRL_PUPD0)
342 u->ct.value = tea5761_is_muted(tea) ? 1 : 0;
343 else
344 u->ct.value = 0;
345 break;
347 case VIDIOC_S_CTRL:
348 dev_dbg(&client->dev, "VIDIOC_S_CTRL %d\n", u->ct.id);
349 if (u->ct.id != V4L2_CID_AUDIO_MUTE)
350 return -EINVAL;
351 tea5761_mute(tea, u->ct.value);
352 break;
354 default:
355 return -ENOIOCTLCMD;
358 return 0;
361 static int tea5761_ioctl(struct inode *inode, struct file *file,
362 unsigned int cmd, unsigned long arg)
364 return video_usercopy(inode, file, cmd, arg, tea5761_do_ioctl);
367 static int tea5761_open(struct inode *inode, struct file *file)
369 int minor = iminor(file->f_dentry->d_inode);
370 /* Currently we support only one device */
371 struct tea5761_device *tea = &tea5761;
373 if (tea->video_dev->minor != minor)
374 return -ENODEV;
376 mutex_lock(&tea->mutex);
377 /* Only exclusive access */
378 if (tea->users) {
379 mutex_unlock(&tea->mutex);
380 return -EBUSY;
382 tea->users++;
383 mutex_unlock(&tea->mutex);
385 file->private_data = tea;
386 return 0;
389 static int tea5761_release(struct inode *inode, struct file *file)
391 struct tea5761_device *tea = file->private_data;
393 mutex_lock(&tea->mutex);
394 tea->users--;
395 mutex_unlock(&tea->mutex);
397 return 0;
400 static struct file_operations tea5761_fops = {
401 .owner = THIS_MODULE,
402 .open = tea5761_open,
403 .release = tea5761_release,
404 .ioctl = tea5761_ioctl,
405 .llseek = no_llseek,
408 static struct video_device tea5761_video_device = {
409 .owner = THIS_MODULE,
410 .name = "TEA5761 FM-Radio",
411 .type = VID_TYPE_TUNER,
412 .fops = &tea5761_fops,
413 .release = video_device_release
416 static int tea5761_i2c_driver_probe(struct i2c_client *client,
417 const struct i2c_device_id *id)
419 struct video_device *video_dev;
420 int err = 0;
421 struct tea5761_device *tea = &tea5761;
423 mutex_init(&tea->mutex);
425 tea->i2c_dev = client;
427 /* V4L initialization */
428 video_dev = video_device_alloc();
429 if (video_dev == NULL) {
430 dev_err(&client->dev, "couldn't allocate memory\n");
431 err = -ENOMEM;
432 goto exit;
434 tea->video_dev = video_dev;
436 *video_dev = tea5761_video_device;
437 video_dev->dev = &client->dev;
438 i2c_set_clientdata(client, video_dev);
440 /* initialize and power off the chip */
441 tea5761_read_regs(tea);
442 tea5761_set_audout_mode(tea, V4L2_TUNER_MODE_STEREO);
443 tea5761_mute(tea, 0);
444 tea5761_power_down(tea);
446 tea5761.video_dev = video_dev;
447 tea5761.i2c_dev = client;
449 err = video_register_device(video_dev, VFL_TYPE_RADIO, radio_nr);
450 if (err) {
451 dev_err(&client->dev, "couldn't register video device\n");
452 goto err_video_alloc;
455 dev_info(&client->dev, "tea5761 (version %d) detected\n",
456 (tea->regs.manid >> 12) & 0xf);
458 return 0;
460 err_video_alloc:
461 video_device_release(video_dev);
462 exit:
463 kfree(client);
464 return err;
467 static int tea5761_i2c_driver_remove(struct i2c_client *client)
469 struct video_device *vd = i2c_get_clientdata(client);
471 video_unregister_device(vd);
473 return 0;
476 static const struct i2c_device_id tea5761_id[] = {
477 { DRIVER_NAME, 0 },
478 { },
480 MODULE_DEVICE_TABLE(i2c, tea5761_id);
482 static struct i2c_driver tea5761_driver = {
483 .driver = {
484 .name = DRIVER_NAME,
486 .probe = tea5761_i2c_driver_probe,
487 .remove = __devexit_p(tea5761_i2c_driver_remove),
488 .id_table = tea5761_id,
491 static int __init tea5761_init(void)
493 int res;
495 if ((res = i2c_add_driver(&tea5761_driver))) {
496 printk(KERN_ERR DRIVER_NAME ": driver registration failed\n");
497 return res;
500 return 0;
503 static void __exit tea5761_exit(void)
505 i2c_del_driver(&tea5761_driver);
508 MODULE_AUTHOR("Timo Teräs");
509 MODULE_DESCRIPTION("I2C interface for TEA5761.");
510 MODULE_LICENSE("GPL");
512 module_param(radio_nr, int, 0);
513 MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
515 module_init(tea5761_init)
516 module_exit(tea5761_exit)