1 --- kernel-power-2.6.28.orig/drivers/media/radio/radio-bcm2048.c
2 +++ kernel-power-2.6.28/drivers/media/radio/radio-bcm2048.c
4 * Copyright (C) Nokia Corporation
5 * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
7 + * Copyright (C) Nils Faerber <nils.faerber@kernelconcepts.de>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
18 + * Eero Nurkkala <ext-eero.nurkkala@nokia.com>
20 + * - Initial implementation
21 + * 2010-02-21 Nils Faerber <nils.faerber@kernelconcepts.de>
23 + * - Add support for interrupt driven rds data reading
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
34 + /* for rds data device read */
35 + wait_queue_head_t read_queue;
37 + unsigned char rds_data_available;
38 + unsigned int rd_index;
41 static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */
43 bcm2048_parse_rds_ps(bdev);
45 mutex_unlock(&bdev->mutex);
47 + wake_up_interruptible(&bdev->read_queue);
50 static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data)
51 @@ -1869,6 +1889,11 @@
53 err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
55 + init_waitqueue_head(&bdev->read_queue);
56 + bdev->rds_data_available = 0;
64 bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
68 + bdev->rds_data_available = 1;
69 + bdev->rd_index = 0; /* new data, new start */
73 @@ -2139,6 +2165,100 @@
78 +static int bcm2048_fops_open(struct inode *inode, struct file *file)
80 + struct bcm2048_device *bdev = video_drvdata(file);
84 + bdev->rds_data_available = 0;
89 +static int bcm2048_fops_release(struct inode *inode, struct file *file)
91 + struct bcm2048_device *bdev = video_drvdata(file);
98 +static unsigned int bcm2048_fops_poll(struct file *file,
99 + struct poll_table_struct *pts)
101 + struct bcm2048_device *bdev = video_drvdata(file);
104 + poll_wait(file, &bdev->read_queue, pts);
106 + if (bdev->rds_data_available) {
107 + retval = POLLIN | POLLRDNORM;
113 +static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
114 + size_t count, loff_t *ppos)
116 + struct bcm2048_device *bdev = video_drvdata(file);
120 + /* we return at least 3 bytes, one block */
121 + count = (count / 3) * 3; /* only multiples of 3 */
125 + while (!bdev->rds_data_available) {
126 + if (file->f_flags & O_NONBLOCK) {
127 + retval = -EWOULDBLOCK;
130 + //interruptible_sleep_on(&bdev->read_queue);
131 + if (wait_event_interruptible(bdev->read_queue,
132 + bdev->rds_data_available) < 0) {
138 + mutex_lock(&bdev->mutex);
139 + /* copy data to userspace */
140 + i = bdev->fifo_size - bdev->rd_index;
142 + count = (i / 3) * 3;
145 + while (i < count) {
146 + unsigned char tmpbuf[3];
147 + tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index+i+2];
148 + tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1];
149 + tmpbuf[i+2] = ((bdev->rds_info.radio_text[bdev->rd_index+i] & 0xf0) >> 4);
150 + if ((bdev->rds_info.radio_text[bdev->rd_index+i] & BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE)
151 + tmpbuf[i+2] |= 0x80;
152 + if (copy_to_user(buf+i, tmpbuf, 3)) {
159 + bdev->rd_index += i;
160 + if (bdev->rd_index >= bdev->fifo_size)
161 + bdev->rds_data_available = 0;
163 + mutex_unlock(&bdev->mutex);
172 * bcm2048_fops - file operations interface
174 @@ -2147,6 +2267,11 @@
176 .ioctl = video_ioctl2,
177 .compat_ioctl = v4l_compat_ioctl32,
178 + /* for RDS read support */
179 + .open = bcm2048_fops_open,
180 + .release = bcm2048_fops_release,
181 + .read = bcm2048_fops_read,
182 + .poll = bcm2048_fops_poll
186 @@ -2609,4 +2734,4 @@
187 MODULE_LICENSE("GPL");
188 MODULE_AUTHOR(BCM2048_DRIVER_AUTHOR);
189 MODULE_DESCRIPTION(BCM2048_DRIVER_DESC);
190 -MODULE_VERSION("0.0.1");
191 +MODULE_VERSION("0.0.2");