aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2011-03-11 01:54:46 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-05-20 08:27:43 -0400
commit0830be3fe107372b375256c5303cabd85d4be234 (patch)
tree4bfc253ded7b4d1020c336601255b223fb27f6a4 /drivers/media/radio
parentcc73b4b57c59141bb8a99f86a1af95f296262558 (diff)
[media] radio-si470x: support seek and tune interrupt enable
Currently we use busy waiting to seek and tune, it can replace to interrupt way. SI470X I2C driver supports interrupt way to week and tune via this patch. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c60
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c17
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h3
3 files changed, 60 insertions, 20 deletions
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 38ae6cd65790..0e740c98786c 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -174,15 +174,27 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
174 if (retval < 0) 174 if (retval < 0)
175 goto done; 175 goto done;
176 176
177 /* wait till tune operation has completed */ 177 /* currently I2C driver only uses interrupt way to tune */
178 timeout = jiffies + msecs_to_jiffies(tune_timeout); 178 if (radio->stci_enabled) {
179 do { 179 INIT_COMPLETION(radio->completion);
180 retval = si470x_get_register(radio, STATUSRSSI); 180
181 if (retval < 0) 181 /* wait till tune operation has completed */
182 goto stop; 182 retval = wait_for_completion_timeout(&radio->completion,
183 timed_out = time_after(jiffies, timeout); 183 msecs_to_jiffies(tune_timeout));
184 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && 184 if (!retval)
185 (!timed_out)); 185 timed_out = true;
186 } else {
187 /* wait till tune operation has completed */
188 timeout = jiffies + msecs_to_jiffies(tune_timeout);
189 do {
190 retval = si470x_get_register(radio, STATUSRSSI);
191 if (retval < 0)
192 goto stop;
193 timed_out = time_after(jiffies, timeout);
194 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
195 && (!timed_out));
196 }
197
186 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 198 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
187 dev_warn(&radio->videodev->dev, "tune does not complete\n"); 199 dev_warn(&radio->videodev->dev, "tune does not complete\n");
188 if (timed_out) 200 if (timed_out)
@@ -310,15 +322,27 @@ static int si470x_set_seek(struct si470x_device *radio,
310 if (retval < 0) 322 if (retval < 0)
311 goto done; 323 goto done;
312 324
313 /* wait till seek operation has completed */ 325 /* currently I2C driver only uses interrupt way to seek */
314 timeout = jiffies + msecs_to_jiffies(seek_timeout); 326 if (radio->stci_enabled) {
315 do { 327 INIT_COMPLETION(radio->completion);
316 retval = si470x_get_register(radio, STATUSRSSI); 328
317 if (retval < 0) 329 /* wait till seek operation has completed */
318 goto stop; 330 retval = wait_for_completion_timeout(&radio->completion,
319 timed_out = time_after(jiffies, timeout); 331 msecs_to_jiffies(seek_timeout));
320 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && 332 if (!retval)
321 (!timed_out)); 333 timed_out = true;
334 } else {
335 /* wait till seek operation has completed */
336 timeout = jiffies + msecs_to_jiffies(seek_timeout);
337 do {
338 retval = si470x_get_register(radio, STATUSRSSI);
339 if (retval < 0)
340 goto stop;
341 timed_out = time_after(jiffies, timeout);
342 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
343 && (!timed_out));
344 }
345
322 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 346 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
323 dev_warn(&radio->videodev->dev, "seek does not complete\n"); 347 dev_warn(&radio->videodev->dev, "seek does not complete\n");
324 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) 348 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 4ce541a5eb47..5a2975ded5d2 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -197,8 +197,9 @@ int si470x_fops_open(struct file *file)
197 if (retval < 0) 197 if (retval < 0)
198 goto done; 198 goto done;
199 199
200 /* enable RDS interrupt */ 200 /* enable RDS / STC interrupt */
201 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; 201 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
202 radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
202 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; 203 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
203 radio->registers[SYSCONFIG1] |= 0x1 << 2; 204 radio->registers[SYSCONFIG1] |= 0x1 << 2;
204 retval = si470x_set_register(radio, SYSCONFIG1); 205 retval = si470x_set_register(radio, SYSCONFIG1);
@@ -274,12 +275,20 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
274 unsigned char tmpbuf[3]; 275 unsigned char tmpbuf[3];
275 int retval = 0; 276 int retval = 0;
276 277
278 /* check Seek/Tune Complete */
279 retval = si470x_get_register(radio, STATUSRSSI);
280 if (retval < 0)
281 return;
282
283 if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
284 complete(&radio->completion);
285
277 /* safety checks */ 286 /* safety checks */
278 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 287 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
279 return; 288 return;
280 289
281 /* Update RDS registers */ 290 /* Update RDS registers */
282 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { 291 for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
283 retval = si470x_get_register(radio, STATUSRSSI + regnr); 292 retval = si470x_get_register(radio, STATUSRSSI + regnr);
284 if (retval < 0) 293 if (retval < 0)
285 return; 294 return;
@@ -441,6 +450,10 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
441 radio->rd_index = 0; 450 radio->rd_index = 0;
442 init_waitqueue_head(&radio->read_queue); 451 init_waitqueue_head(&radio->read_queue);
443 452
453 /* mark Seek/Tune Complete Interrupt enabled */
454 radio->stci_enabled = true;
455 init_completion(&radio->completion);
456
444 retval = request_irq(client->irq, si470x_i2c_interrupt, 457 retval = request_irq(client->irq, si470x_i2c_interrupt,
445 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); 458 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
446 if (retval) { 459 if (retval) {
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index 4a4e908db04c..9ef671657771 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -158,6 +158,9 @@ struct si470x_device {
158 unsigned int rd_index; 158 unsigned int rd_index;
159 unsigned int wr_index; 159 unsigned int wr_index;
160 160
161 struct completion completion;
162 bool stci_enabled; /* Seek/Tune Complete Interrupt */
163
161#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) 164#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
162 /* reference to USB and video device */ 165 /* reference to USB and video device */
163 struct usb_device *usbdev; 166 struct usb_device *usbdev;