Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Joonyoung Shim and committed by
Mauro Carvalho Chehab
0830be3f cc73b4b5

+60 -20
+42 -18
drivers/media/radio/si470x/radio-si470x-common.c
··· 174 174 if (retval < 0) 175 175 goto done; 176 176 177 - /* wait till tune operation has completed */ 178 - timeout = jiffies + msecs_to_jiffies(tune_timeout); 179 - do { 180 - retval = si470x_get_register(radio, STATUSRSSI); 181 - if (retval < 0) 182 - goto stop; 183 - timed_out = time_after(jiffies, timeout); 184 - } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && 185 - (!timed_out)); 177 + /* currently I2C driver only uses interrupt way to tune */ 178 + if (radio->stci_enabled) { 179 + INIT_COMPLETION(radio->completion); 180 + 181 + /* wait till tune operation has completed */ 182 + retval = wait_for_completion_timeout(&radio->completion, 183 + msecs_to_jiffies(tune_timeout)); 184 + if (!retval) 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 198 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 187 199 dev_warn(&radio->videodev->dev, "tune does not complete\n"); 188 200 if (timed_out) ··· 322 310 if (retval < 0) 323 311 goto done; 324 312 325 - /* wait till seek operation has completed */ 326 - timeout = jiffies + msecs_to_jiffies(seek_timeout); 327 - do { 328 - retval = si470x_get_register(radio, STATUSRSSI); 329 - if (retval < 0) 330 - goto stop; 331 - timed_out = time_after(jiffies, timeout); 332 - } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && 333 - (!timed_out)); 313 + /* currently I2C driver only uses interrupt way to seek */ 314 + if (radio->stci_enabled) { 315 + INIT_COMPLETION(radio->completion); 316 + 317 + /* wait till seek operation has completed */ 318 + retval = wait_for_completion_timeout(&radio->completion, 319 + msecs_to_jiffies(seek_timeout)); 320 + if (!retval) 321 + timed_out = true; 322 + } else { 323 + /* wait till seek operation has completed */ 324 + timeout = jiffies + msecs_to_jiffies(seek_timeout); 325 + do { 326 + retval = si470x_get_register(radio, STATUSRSSI); 327 + if (retval < 0) 328 + goto stop; 329 + timed_out = time_after(jiffies, timeout); 330 + } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 331 + && (!timed_out)); 332 + } 333 + 334 334 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 335 335 dev_warn(&radio->videodev->dev, "seek does not complete\n"); 336 336 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
+15 -2
drivers/media/radio/si470x/radio-si470x-i2c.c
··· 197 197 if (retval < 0) 198 198 goto done; 199 199 200 - /* enable RDS interrupt */ 200 + /* enable RDS / STC interrupt */ 201 201 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; 202 + radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN; 202 203 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; 203 204 radio->registers[SYSCONFIG1] |= 0x1 << 2; 204 205 retval = si470x_set_register(radio, SYSCONFIG1); ··· 275 274 unsigned char tmpbuf[3]; 276 275 int retval = 0; 277 276 277 + /* check Seek/Tune Complete */ 278 + retval = si470x_get_register(radio, STATUSRSSI); 279 + if (retval < 0) 280 + return; 281 + 282 + if (radio->registers[STATUSRSSI] & STATUSRSSI_STC) 283 + complete(&radio->completion); 284 + 278 285 /* safety checks */ 279 286 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 280 287 return; 281 288 282 289 /* Update RDS registers */ 283 - for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { 290 + for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) { 284 291 retval = si470x_get_register(radio, STATUSRSSI + regnr); 285 292 if (retval < 0) 286 293 return; ··· 449 440 radio->wr_index = 0; 450 441 radio->rd_index = 0; 451 442 init_waitqueue_head(&radio->read_queue); 443 + 444 + /* mark Seek/Tune Complete Interrupt enabled */ 445 + radio->stci_enabled = true; 446 + init_completion(&radio->completion); 452 447 453 448 retval = request_irq(client->irq, si470x_i2c_interrupt, 454 449 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
+3
drivers/media/radio/si470x/radio-si470x.h
··· 158 158 unsigned int rd_index; 159 159 unsigned int wr_index; 160 160 161 + struct completion completion; 162 + bool stci_enabled; /* Seek/Tune Complete Interrupt */ 163 + 161 164 #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) 162 165 /* reference to USB and video device */ 163 166 struct usb_device *usbdev;