aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Lorenz <tobias.lorenz@gmx.net>2009-08-10 17:44:14 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:18:43 -0400
commit9dcb79c2eedb5b3ec50f73bd531fb6dd52c94bfc (patch)
treed6aea422e271c26b06562fdddc84fc2d5210501e
parentcc35bbddfe10f77d949f0190764b252cd2b70c3c (diff)
V4L/DVB (12417): I2C cleanups and version checks
The structure and comments of the I2C part have been adopted to fit to the USB part. Some additional cleanups and precisements have been made to the version detection and checking functionality to clearly separate HW/SW/FW version. Signed-off-by: Tobias Lorenz <tobias.lorenz@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c245
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c43
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h45
3 files changed, 257 insertions, 76 deletions
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 218102184702..2d53b6a9409b 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -3,53 +3,88 @@
3 * 3 *
4 * I2C driver for radios with Silicon Labs Si470x FM Radio Receivers 4 * I2C driver for radios with Silicon Labs Si470x FM Radio Receivers
5 * 5 *
6 * Copyright (C) 2009 Samsung Electronics Co.Ltd 6 * Copyright (c) 2009 Samsung Electronics Co.Ltd
7 * Author: Joonyoung Shim <jy0922.shim@samsung.com> 7 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify
10 * under the terms of the GNU General Public License as published by the 10 * it under the terms of the GNU General Public License as published by
11 * Free Software Foundation; either version 2 of the License, or (at your 11 * the Free Software Foundation; either version 2 of the License, or
12 * option) any later version. 12 * (at your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
14 * 18 *
15 * TODO: 19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24
25/*
26 * ToDo:
16 * - RDS support 27 * - RDS support
17 *
18 */ 28 */
19 29
20#include <linux/module.h> 30
21#include <linux/init.h> 31/* driver definitions */
32#define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
33#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
34#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
35#define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
36#define DRIVER_VERSION "1.0.0"
37
38/* kernel includes */
22#include <linux/i2c.h> 39#include <linux/i2c.h>
23#include <linux/delay.h> 40#include <linux/delay.h>
24 41
25#include "radio-si470x.h" 42#include "radio-si470x.h"
26 43
27#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
28#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
29#define DRIVER_VERSION "1.0.0"
30 44
31/* starting with the upper byte of register 0x0a */ 45/* I2C Device ID List */
46static const struct i2c_device_id si470x_i2c_id[] = {
47 /* Generic Entry */
48 { "si470x", 0 },
49 /* Terminating entry */
50 { }
51};
52MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
53
54
55
56/**************************************************************************
57 * Module Parameters
58 **************************************************************************/
59
60/* Radio Nr */
61static int radio_nr = -1;
62module_param(radio_nr, int, 0444);
63MODULE_PARM_DESC(radio_nr, "Radio Nr");
64
65
66
67/**************************************************************************
68 * I2C Definitions
69 **************************************************************************/
70
71/* Write starts with the upper byte of register 0x02 */
72#define WRITE_REG_NUM 8
73#define WRITE_INDEX(i) (i + 0x02)
74
75/* Read starts with the upper byte of register 0x0a */
32#define READ_REG_NUM RADIO_REGISTER_NUM 76#define READ_REG_NUM RADIO_REGISTER_NUM
33#define READ_INDEX(i) ((i + RADIO_REGISTER_NUM - 0x0a) % READ_REG_NUM) 77#define READ_INDEX(i) ((i + RADIO_REGISTER_NUM - 0x0a) % READ_REG_NUM)
34 78
35static int si470x_get_all_registers(struct si470x_device *radio)
36{
37 int i;
38 u16 buf[READ_REG_NUM];
39 struct i2c_msg msgs[1] = {
40 { radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
41 (void *)buf },
42 };
43
44 if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
45 return -EIO;
46 79
47 for (i = 0; i < READ_REG_NUM; i++)
48 radio->registers[i] = __be16_to_cpu(buf[READ_INDEX(i)]);
49 80
50 return 0; 81/**************************************************************************
51} 82 * General Driver Functions - REGISTERs
83 **************************************************************************/
52 84
85/*
86 * si470x_get_register - read register
87 */
53int si470x_get_register(struct si470x_device *radio, int regnr) 88int si470x_get_register(struct si470x_device *radio, int regnr)
54{ 89{
55 u16 buf[READ_REG_NUM]; 90 u16 buf[READ_REG_NUM];
@@ -66,10 +101,10 @@ int si470x_get_register(struct si470x_device *radio, int regnr)
66 return 0; 101 return 0;
67} 102}
68 103
69/* starting with the upper byte of register 0x02h */
70#define WRITE_REG_NUM 8
71#define WRITE_INDEX(i) (i + 0x02)
72 104
105/*
106 * si470x_set_register - write register
107 */
73int si470x_set_register(struct si470x_device *radio, int regnr) 108int si470x_set_register(struct si470x_device *radio, int regnr)
74{ 109{
75 int i; 110 int i;
@@ -88,11 +123,56 @@ int si470x_set_register(struct si470x_device *radio, int regnr)
88 return 0; 123 return 0;
89} 124}
90 125
126
127
128/**************************************************************************
129 * General Driver Functions - ENTIRE REGISTERS
130 **************************************************************************/
131
132/*
133 * si470x_get_all_registers - read entire registers
134 */
135static int si470x_get_all_registers(struct si470x_device *radio)
136{
137 int i;
138 u16 buf[READ_REG_NUM];
139 struct i2c_msg msgs[1] = {
140 { radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
141 (void *)buf },
142 };
143
144 if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
145 return -EIO;
146
147 for (i = 0; i < READ_REG_NUM; i++)
148 radio->registers[i] = __be16_to_cpu(buf[READ_INDEX(i)]);
149
150 return 0;
151}
152
153
154
155/**************************************************************************
156 * General Driver Functions - DISCONNECT_CHECK
157 **************************************************************************/
158
159/*
160 * si470x_disconnect_check - check whether radio disconnects
161 */
91int si470x_disconnect_check(struct si470x_device *radio) 162int si470x_disconnect_check(struct si470x_device *radio)
92{ 163{
93 return 0; 164 return 0;
94} 165}
95 166
167
168
169/**************************************************************************
170 * File Operations Interface
171 **************************************************************************/
172
173/*
174 * si470x_fops_open - file open
175 */
96static int si470x_fops_open(struct file *file) 176static int si470x_fops_open(struct file *file)
97{ 177{
98 struct si470x_device *radio = video_drvdata(file); 178 struct si470x_device *radio = video_drvdata(file);
@@ -104,11 +184,16 @@ static int si470x_fops_open(struct file *file)
104 if (radio->users == 1) 184 if (radio->users == 1)
105 /* start radio */ 185 /* start radio */
106 retval = si470x_start(radio); 186 retval = si470x_start(radio);
187
107 mutex_unlock(&radio->lock); 188 mutex_unlock(&radio->lock);
108 189
109 return retval; 190 return retval;
110} 191}
111 192
193
194/*
195 * si470x_fops_release - file release
196 */
112static int si470x_fops_release(struct file *file) 197static int si470x_fops_release(struct file *file)
113{ 198{
114 struct si470x_device *radio = video_drvdata(file); 199 struct si470x_device *radio = video_drvdata(file);
@@ -123,11 +208,16 @@ static int si470x_fops_release(struct file *file)
123 if (radio->users == 0) 208 if (radio->users == 0)
124 /* stop radio */ 209 /* stop radio */
125 retval = si470x_stop(radio); 210 retval = si470x_stop(radio);
211
126 mutex_unlock(&radio->lock); 212 mutex_unlock(&radio->lock);
127 213
128 return retval; 214 return retval;
129} 215}
130 216
217
218/*
219 * si470x_fops - file operations interface
220 */
131const struct v4l2_file_operations si470x_fops = { 221const struct v4l2_file_operations si470x_fops = {
132 .owner = THIS_MODULE, 222 .owner = THIS_MODULE,
133 .ioctl = video_ioctl2, 223 .ioctl = video_ioctl2,
@@ -135,6 +225,15 @@ const struct v4l2_file_operations si470x_fops = {
135 .release = si470x_fops_release, 225 .release = si470x_fops_release,
136}; 226};
137 227
228
229
230/**************************************************************************
231 * Video4Linux Interface
232 **************************************************************************/
233
234/*
235 * si470x_vidioc_querycap - query device capabilities
236 */
138int si470x_vidioc_querycap(struct file *file, void *priv, 237int si470x_vidioc_querycap(struct file *file, void *priv,
139 struct v4l2_capability *capability) 238 struct v4l2_capability *capability)
140{ 239{
@@ -147,11 +246,21 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
147 return 0; 246 return 0;
148} 247}
149 248
249
250
251/**************************************************************************
252 * I2C Interface
253 **************************************************************************/
254
255/*
256 * si470x_i2c_probe - probe for the device
257 */
150static int __devinit si470x_i2c_probe(struct i2c_client *client, 258static int __devinit si470x_i2c_probe(struct i2c_client *client,
151 const struct i2c_device_id *id) 259 const struct i2c_device_id *id)
152{ 260{
153 struct si470x_device *radio; 261 struct si470x_device *radio;
154 int retval = 0; 262 int retval = 0;
263 unsigned char version_warning = 0;
155 264
156 /* private data allocation and initialization */ 265 /* private data allocation and initialization */
157 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); 266 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
@@ -159,8 +268,8 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
159 retval = -ENOMEM; 268 retval = -ENOMEM;
160 goto err_initial; 269 goto err_initial;
161 } 270 }
162 radio->client = client;
163 radio->users = 0; 271 radio->users = 0;
272 radio->client = client;
164 mutex_init(&radio->lock); 273 mutex_init(&radio->lock);
165 274
166 /* video device allocation and initialization */ 275 /* video device allocation and initialization */
@@ -181,28 +290,47 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
181 } 290 }
182 msleep(110); 291 msleep(110);
183 292
184 /* show some infos about the specific si470x device */ 293 /* get device and chip versions */
185 if (si470x_get_all_registers(radio) < 0) { 294 if (si470x_get_all_registers(radio) < 0) {
186 retval = -EIO; 295 retval = -EIO;
187 goto err_radio; 296 goto err_video;
188 } 297 }
189 dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", 298 dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
190 radio->registers[DEVICEID], radio->registers[CHIPID]); 299 radio->registers[DEVICEID], radio->registers[CHIPID]);
300 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
301 dev_warn(&client->dev,
302 "This driver is known to work with "
303 "firmware version %hu,\n", RADIO_FW_VERSION);
304 dev_warn(&client->dev,
305 "but the device has firmware version %hu.\n",
306 radio->registers[CHIPID] & CHIPID_FIRMWARE);
307 version_warning = 1;
308 }
309
310 /* give out version warning */
311 if (version_warning == 1) {
312 dev_warn(&client->dev,
313 "If you have some trouble using this driver,\n");
314 dev_warn(&client->dev,
315 "please report to V4L ML at "
316 "linux-media@vger.kernel.org\n");
317 }
191 318
192 /* set initial frequency */ 319 /* set initial frequency */
193 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ 320 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
194 321
195 /* register video device */ 322 /* register video device */
196 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, -1); 323 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
324 radio_nr);
197 if (retval) { 325 if (retval) {
198 dev_warn(&client->dev, "Could not register video device\n"); 326 dev_warn(&client->dev, "Could not register video device\n");
199 goto err_all; 327 goto err_all;
200 } 328 }
201
202 i2c_set_clientdata(client, radio); 329 i2c_set_clientdata(client, radio);
203 330
204 return 0; 331 return 0;
205err_all: 332err_all:
333err_video:
206 video_device_release(radio->videodev); 334 video_device_release(radio->videodev);
207err_radio: 335err_radio:
208 kfree(radio); 336 kfree(radio);
@@ -210,6 +338,10 @@ err_initial:
210 return retval; 338 return retval;
211} 339}
212 340
341
342/*
343 * si470x_i2c_remove - remove the device
344 */
213static __devexit int si470x_i2c_remove(struct i2c_client *client) 345static __devexit int si470x_i2c_remove(struct i2c_client *client)
214{ 346{
215 struct si470x_device *radio = i2c_get_clientdata(client); 347 struct si470x_device *radio = i2c_get_clientdata(client);
@@ -221,34 +353,49 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
221 return 0; 353 return 0;
222} 354}
223 355
224static const struct i2c_device_id si470x_i2c_id[] = {
225 { "si470x", 0 },
226 { }
227};
228MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
229 356
357/*
358 * si470x_i2c_driver - i2c driver interface
359 */
230static struct i2c_driver si470x_i2c_driver = { 360static struct i2c_driver si470x_i2c_driver = {
231 .driver = { 361 .driver = {
232 .name = "si470x", 362 .name = "si470x",
233 .owner = THIS_MODULE, 363 .owner = THIS_MODULE,
234 }, 364 },
235 .probe = si470x_i2c_probe, 365 .probe = si470x_i2c_probe,
236 .remove = __devexit_p(si470x_i2c_remove), 366 .remove = __devexit_p(si470x_i2c_remove),
237 .id_table = si470x_i2c_id, 367 .id_table = si470x_i2c_id,
238}; 368};
239 369
370
371
372/**************************************************************************
373 * Module Interface
374 **************************************************************************/
375
376/*
377 * si470x_i2c_init - module init
378 */
240static int __init si470x_i2c_init(void) 379static int __init si470x_i2c_init(void)
241{ 380{
381 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
242 return i2c_add_driver(&si470x_i2c_driver); 382 return i2c_add_driver(&si470x_i2c_driver);
243} 383}
244module_init(si470x_i2c_init);
245 384
385
386/*
387 * si470x_i2c_exit - module exit
388 */
246static void __exit si470x_i2c_exit(void) 389static void __exit si470x_i2c_exit(void)
247{ 390{
248 i2c_del_driver(&si470x_i2c_driver); 391 i2c_del_driver(&si470x_i2c_driver);
249} 392}
393
394
395module_init(si470x_i2c_init);
250module_exit(si470x_i2c_exit); 396module_exit(si470x_i2c_exit);
251 397
252MODULE_DESCRIPTION("i2c radio driver for si470x fm radio receivers");
253MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
254MODULE_LICENSE("GPL"); 398MODULE_LICENSE("GPL");
399MODULE_AUTHOR(DRIVER_AUTHOR);
400MODULE_DESCRIPTION(DRIVER_DESC);
401MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 2f5cf6c7234d..f2d0e1ddb301 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -138,16 +138,12 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
138 138
139 139
140/************************************************************************** 140/**************************************************************************
141 * Software/Hardware Versions 141 * Software/Hardware Versions from Scratch Page
142 **************************************************************************/ 142 **************************************************************************/
143#define RADIO_SW_VERSION_NOT_BOOTLOADABLE 6 143#define RADIO_SW_VERSION_NOT_BOOTLOADABLE 6
144#define RADIO_SW_VERSION 7 144#define RADIO_SW_VERSION 7
145#define RADIO_SW_VERSION_CURRENT 15
146#define RADIO_HW_VERSION 1 145#define RADIO_HW_VERSION 1
147 146
148#define SCRATCH_PAGE_SW_VERSION 1
149#define SCRATCH_PAGE_HW_VERSION 2
150
151 147
152 148
153/************************************************************************** 149/**************************************************************************
@@ -745,6 +741,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
745 struct usb_host_interface *iface_desc; 741 struct usb_host_interface *iface_desc;
746 struct usb_endpoint_descriptor *endpoint; 742 struct usb_endpoint_descriptor *endpoint;
747 int i, int_end_size, retval = 0; 743 int i, int_end_size, retval = 0;
744 unsigned char version_warning = 0;
748 745
749 /* private data allocation and initialization */ 746 /* private data allocation and initialization */
750 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); 747 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
@@ -801,13 +798,22 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
801 sizeof(si470x_viddev_template)); 798 sizeof(si470x_viddev_template));
802 video_set_drvdata(radio->videodev, radio); 799 video_set_drvdata(radio->videodev, radio);
803 800
804 /* show some infos about the specific si470x device */ 801 /* get device and chip versions */
805 if (si470x_get_all_registers(radio) < 0) { 802 if (si470x_get_all_registers(radio) < 0) {
806 retval = -EIO; 803 retval = -EIO;
807 goto err_video; 804 goto err_video;
808 } 805 }
809 dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", 806 dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
810 radio->registers[DEVICEID], radio->registers[CHIPID]); 807 radio->registers[DEVICEID], radio->registers[CHIPID]);
808 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
809 dev_warn(&intf->dev,
810 "This driver is known to work with "
811 "firmware version %hu,\n", RADIO_FW_VERSION);
812 dev_warn(&intf->dev,
813 "but the device has firmware version %hu.\n",
814 radio->registers[CHIPID] & CHIPID_FIRMWARE);
815 version_warning = 1;
816 }
811 817
812 /* get software and hardware versions */ 818 /* get software and hardware versions */
813 if (si470x_get_scratch_page_versions(radio) < 0) { 819 if (si470x_get_scratch_page_versions(radio) < 0) {
@@ -816,16 +822,27 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
816 } 822 }
817 dev_info(&intf->dev, "software version %d, hardware version %d\n", 823 dev_info(&intf->dev, "software version %d, hardware version %d\n",
818 radio->software_version, radio->hardware_version); 824 radio->software_version, radio->hardware_version);
819 825 if (radio->software_version < RADIO_SW_VERSION) {
820 /* check if device and firmware is current */
821 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
822 < RADIO_SW_VERSION_CURRENT) {
823 dev_warn(&intf->dev, 826 dev_warn(&intf->dev,
824 "This driver is known to work with " 827 "This driver is known to work with "
825 "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT); 828 "software version %hu,\n", RADIO_SW_VERSION);
826 dev_warn(&intf->dev, 829 dev_warn(&intf->dev,
827 "but the device has firmware version %hu.\n", 830 "but the device has software version %hu.\n",
828 radio->registers[CHIPID] & CHIPID_FIRMWARE); 831 radio->software_version);
832 version_warning = 1;
833 }
834 if (radio->hardware_version < RADIO_HW_VERSION) {
835 dev_warn(&intf->dev,
836 "This driver is known to work with "
837 "hardware version %hu,\n", RADIO_HW_VERSION);
838 dev_warn(&intf->dev,
839 "but the device has hardware version %hu.\n",
840 radio->hardware_version);
841 version_warning = 1;
842 }
843
844 /* give out version warning */
845 if (version_warning == 1) {
829 dev_warn(&intf->dev, 846 dev_warn(&intf->dev,
830 "If you have some trouble using this driver,\n"); 847 "If you have some trouble using this driver,\n");
831 dev_warn(&intf->dev, 848 dev_warn(&intf->dev,
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index 794112c759b8..d0af194d194c 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -41,6 +41,7 @@
41#include <asm/unaligned.h> 41#include <asm/unaligned.h>
42 42
43 43
44
44/************************************************************************** 45/**************************************************************************
45 * Register Definitions 46 * Register Definitions
46 **************************************************************************/ 47 **************************************************************************/
@@ -133,6 +134,7 @@
133#define RDSD_RDSD 0xffff /* bits 15..00: RDS Block D Data (Si4701 only) */ 134#define RDSD_RDSD 0xffff /* bits 15..00: RDS Block D Data (Si4701 only) */
134 135
135 136
137
136/************************************************************************** 138/**************************************************************************
137 * General Driver Definitions 139 * General Driver Definitions
138 **************************************************************************/ 140 **************************************************************************/
@@ -143,9 +145,19 @@
143struct si470x_device { 145struct si470x_device {
144 struct video_device *videodev; 146 struct video_device *videodev;
145 147
146#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) 148 /* driver management */
147 struct i2c_client *client; 149 unsigned int users;
148#endif 150
151 /* Silabs internal registers (0..15) */
152 unsigned short registers[RADIO_REGISTER_NUM];
153
154 /* RDS receive buffer */
155 wait_queue_head_t read_queue;
156 struct mutex lock; /* buffer locking */
157 unsigned char *buffer; /* size is always multiple of three */
158 unsigned int buf_size;
159 unsigned int rd_index;
160 unsigned int wr_index;
149 161
150#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) 162#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
151 /* reference to USB and video device */ 163 /* reference to USB and video device */
@@ -166,21 +178,26 @@ struct si470x_device {
166 unsigned char disconnected; 178 unsigned char disconnected;
167 struct mutex disconnect_lock; 179 struct mutex disconnect_lock;
168#endif 180#endif
169 unsigned int users;
170
171 /* Silabs internal registers (0..15) */
172 unsigned short registers[RADIO_REGISTER_NUM];
173 181
174 /* RDS receive buffer */ 182#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
175 wait_queue_head_t read_queue; 183 struct i2c_client *client;
176 struct mutex lock; /* buffer locking */ 184#endif
177 unsigned char *buffer; /* size is always multiple of three */
178 unsigned int buf_size;
179 unsigned int rd_index;
180 unsigned int wr_index;
181}; 185};
182 186
183 187
188
189/**************************************************************************
190 * Firmware Versions
191 **************************************************************************/
192
193#define RADIO_FW_VERSION 15
194
195
196
197/**************************************************************************
198 * Frequency Multiplicator
199 **************************************************************************/
200
184/* 201/*
185 * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW, 202 * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
186 * 62.5 kHz otherwise. 203 * 62.5 kHz otherwise.