]> git.karo-electronics.de Git - rdstmc.git/blob - driver-n900/radio-bcm2048-2.6.28.diff
Add radio tuning test app
[rdstmc.git] / driver-n900 / radio-bcm2048-2.6.28.diff
1 --- ../linux-2.6.28/drivers/media/radio/radio-bcm2048.c 2010-02-18 00:59:33.000000000 +0100
2 +++ kernel-2.6.28/drivers/media/radio/radio-bcm2048.c   2010-05-24 22:59:54.000000000 +0200
3 @@ -6,6 +6,8 @@
4   * Copyright (C) Nokia Corporation
5   * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
6   *
7 + * Copyright (C) Nils Faerber <nils.faerber@kernelconcepts.de>
8 + *
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.
12 @@ -21,6 +23,16 @@
13   * 02110-1301 USA
14   */
15  
16 +/*
17 + * History:
18 + *             Eero Nurkkala <ext-eero.nurkkala@nokia.com>
19 + *             Version 0.0.1
20 + *             - Initial implementation
21 + * 2010-02-21  Nils Faerber <nils.faerber@kernelconcepts.de>
22 + *             Version 0.0.2
23 + *             - Add support for interrupt driven rds data reading
24 + */
25 +
26  #include <linux/kernel.h>
27  #include <linux/module.h>
28  #include <linux/init.h>
29 @@ -283,6 +295,12 @@
30         u8 fifo_size;
31         u8 scan_state;
32         u8 mute_state;
33 +
34 +       /* for rds data device read */
35 +       wait_queue_head_t read_queue;
36 +       unsigned int users;
37 +       unsigned char rds_data_available;
38 +       unsigned int rd_index;
39  };
40  
41  static int radio_nr = -1;      /* radio device minor (-1 ==> auto assign) */
42 @@ -1756,6 +1774,8 @@
43         bcm2048_parse_rds_ps(bdev);
44  
45         mutex_unlock(&bdev->mutex);
46 +
47 +       wake_up_interruptible(&bdev->read_queue);
48  }
49  
50  static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data)
51 @@ -1869,6 +1889,11 @@
52  
53         err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
54  
55 +       init_waitqueue_head(&bdev->read_queue);
56 +       bdev->rds_data_available = 0;
57 +       bdev->rd_index = 0;
58 +       bdev->users = 0;
59 +
60  unlock:
61         return err;
62  }
63 @@ -1903,7 +1928,8 @@
64                         bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
65                                                 flags);
66                 }
67 -
68 +               bdev->rds_data_available = 1;
69 +               bdev->rd_index = 0; /* new data, new start */
70         }
71  }
72  
73 @@ -2139,6 +2165,100 @@
74         return err;
75  }
76  
77 +
78 +static int bcm2048_fops_open(struct inode *inode, struct file *file)
79 +{
80 +       struct bcm2048_device *bdev = video_drvdata(file);
81 +
82 +       bdev->users++;
83 +       bdev->rd_index = 0;
84 +       bdev->rds_data_available = 0;
85 +
86 +return 0;
87 +}
88 +
89 +static int bcm2048_fops_release(struct inode *inode, struct file *file)
90 +{
91 +       struct bcm2048_device *bdev = video_drvdata(file);
92 +
93 +       bdev->users--;
94 +
95 +return 0;
96 +}
97 +
98 +static unsigned int bcm2048_fops_poll(struct file *file,
99 +               struct poll_table_struct *pts)
100 +{
101 +       struct bcm2048_device *bdev = video_drvdata(file);
102 +       int retval = 0;
103 +
104 +       poll_wait(file, &bdev->read_queue, pts);
105 +
106 +       if (bdev->rds_data_available) {
107 +               retval = POLLIN | POLLRDNORM;
108 +       }
109 +
110 +       return retval;
111 +}
112 +
113 +static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
114 +       size_t count, loff_t *ppos)
115 +{
116 +       struct bcm2048_device *bdev = video_drvdata(file);
117 +       int i;
118 +       int retval = 0;
119 +
120 +       /* we return at least 3 bytes, one block */
121 +       count = (count / 3) * 3; /* only multiples of 3 */
122 +       if (count < 3)
123 +               return -ENOBUFS;
124 +
125 +       while (!bdev->rds_data_available) {
126 +               if (file->f_flags & O_NONBLOCK) {
127 +                       retval = -EWOULDBLOCK;
128 +                       goto done;
129 +               }
130 +               //interruptible_sleep_on(&bdev->read_queue);
131 +               if (wait_event_interruptible(bdev->read_queue,
132 +                       bdev->rds_data_available) < 0) {
133 +                       retval = -EINTR;
134 +                       goto done;
135 +               }
136 +       }
137 +
138 +       mutex_lock(&bdev->mutex);
139 +       /* copy data to userspace */
140 +       i = bdev->fifo_size - bdev->rd_index;
141 +       if (count > i)
142 +               count = (i / 3) * 3;
143 +
144 +       i = 0;
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)) {
153 +                       retval = -EFAULT;
154 +                       break;
155 +               };
156 +               i += 3;
157 +       }
158 +
159 +       bdev->rd_index += i;
160 +       if (bdev->rd_index >= bdev->fifo_size)
161 +               bdev->rds_data_available = 0;
162 +
163 +       mutex_unlock(&bdev->mutex);
164 +       if (retval == 0)
165 +               retval = i;
166 +
167 +done:
168 +       return retval;
169 +}
170 +
171  /*
172   *     bcm2048_fops - file operations interface
173   */
174 @@ -2147,6 +2267,11 @@
175         .llseek         = no_llseek,
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
183  };
184  
185  /*
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");