root/drivers/media/radio/si470x/radio-si470x-i2c.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. si470x_get_register
  2. si470x_set_register
  3. si470x_get_all_registers
  4. si470x_fops_open
  5. si470x_fops_release
  6. si470x_vidioc_querycap
  7. si470x_i2c_interrupt
  8. si470x_i2c_probe
  9. si470x_i2c_remove
  10. si470x_i2c_suspend
  11. si470x_i2c_resume

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * drivers/media/radio/si470x/radio-si470x-i2c.c
   4  *
   5  * I2C driver for radios with Silicon Labs Si470x FM Radio Receivers
   6  *
   7  * Copyright (c) 2009 Samsung Electronics Co.Ltd
   8  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
   9  */
  10 
  11 
  12 /* driver definitions */
  13 #define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
  14 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
  15 #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
  16 #define DRIVER_VERSION "1.0.2"
  17 
  18 /* kernel includes */
  19 #include <linux/i2c.h>
  20 #include <linux/slab.h>
  21 #include <linux/delay.h>
  22 #include <linux/gpio/consumer.h>
  23 #include <linux/interrupt.h>
  24 
  25 #include "radio-si470x.h"
  26 
  27 
  28 /* I2C Device ID List */
  29 static const struct i2c_device_id si470x_i2c_id[] = {
  30         /* Generic Entry */
  31         { "si470x", 0 },
  32         /* Terminating entry */
  33         { }
  34 };
  35 MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
  36 
  37 
  38 /**************************************************************************
  39  * Module Parameters
  40  **************************************************************************/
  41 
  42 /* Radio Nr */
  43 static int radio_nr = -1;
  44 module_param(radio_nr, int, 0444);
  45 MODULE_PARM_DESC(radio_nr, "Radio Nr");
  46 
  47 /* RDS buffer blocks */
  48 static unsigned int rds_buf = 100;
  49 module_param(rds_buf, uint, 0444);
  50 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
  51 
  52 /* RDS maximum block errors */
  53 static unsigned short max_rds_errors = 1;
  54 /* 0 means   0  errors requiring correction */
  55 /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
  56 /* 2 means 3-5  errors requiring correction */
  57 /* 3 means   6+ errors or errors in checkword, correction not possible */
  58 module_param(max_rds_errors, ushort, 0644);
  59 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
  60 
  61 
  62 
  63 /**************************************************************************
  64  * I2C Definitions
  65  **************************************************************************/
  66 
  67 /* Write starts with the upper byte of register 0x02 */
  68 #define WRITE_REG_NUM           8
  69 #define WRITE_INDEX(i)          (i + 0x02)
  70 
  71 /* Read starts with the upper byte of register 0x0a */
  72 #define READ_REG_NUM            RADIO_REGISTER_NUM
  73 #define READ_INDEX(i)           ((i + RADIO_REGISTER_NUM - 0x0a) % READ_REG_NUM)
  74 
  75 
  76 
  77 /**************************************************************************
  78  * General Driver Functions - REGISTERs
  79  **************************************************************************/
  80 
  81 /*
  82  * si470x_get_register - read register
  83  */
  84 static int si470x_get_register(struct si470x_device *radio, int regnr)
  85 {
  86         __be16 buf[READ_REG_NUM];
  87         struct i2c_msg msgs[1] = {
  88                 {
  89                         .addr = radio->client->addr,
  90                         .flags = I2C_M_RD,
  91                         .len = sizeof(u16) * READ_REG_NUM,
  92                         .buf = (void *)buf
  93                 },
  94         };
  95 
  96         if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
  97                 return -EIO;
  98 
  99         radio->registers[regnr] = __be16_to_cpu(buf[READ_INDEX(regnr)]);
 100 
 101         return 0;
 102 }
 103 
 104 
 105 /*
 106  * si470x_set_register - write register
 107  */
 108 static int si470x_set_register(struct si470x_device *radio, int regnr)
 109 {
 110         int i;
 111         __be16 buf[WRITE_REG_NUM];
 112         struct i2c_msg msgs[1] = {
 113                 {
 114                         .addr = radio->client->addr,
 115                         .len = sizeof(u16) * WRITE_REG_NUM,
 116                         .buf = (void *)buf
 117                 },
 118         };
 119 
 120         for (i = 0; i < WRITE_REG_NUM; i++)
 121                 buf[i] = __cpu_to_be16(radio->registers[WRITE_INDEX(i)]);
 122 
 123         if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
 124                 return -EIO;
 125 
 126         return 0;
 127 }
 128 
 129 
 130 
 131 /**************************************************************************
 132  * General Driver Functions - ENTIRE REGISTERS
 133  **************************************************************************/
 134 
 135 /*
 136  * si470x_get_all_registers - read entire registers
 137  */
 138 static int si470x_get_all_registers(struct si470x_device *radio)
 139 {
 140         int i;
 141         __be16 buf[READ_REG_NUM];
 142         struct i2c_msg msgs[1] = {
 143                 {
 144                         .addr = radio->client->addr,
 145                         .flags = I2C_M_RD,
 146                         .len = sizeof(u16) * READ_REG_NUM,
 147                         .buf = (void *)buf
 148                 },
 149         };
 150 
 151         if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
 152                 return -EIO;
 153 
 154         for (i = 0; i < READ_REG_NUM; i++)
 155                 radio->registers[i] = __be16_to_cpu(buf[READ_INDEX(i)]);
 156 
 157         return 0;
 158 }
 159 
 160 
 161 
 162 /**************************************************************************
 163  * File Operations Interface
 164  **************************************************************************/
 165 
 166 /*
 167  * si470x_fops_open - file open
 168  */
 169 static int si470x_fops_open(struct file *file)
 170 {
 171         struct si470x_device *radio = video_drvdata(file);
 172         int retval = v4l2_fh_open(file);
 173 
 174         if (retval)
 175                 return retval;
 176 
 177         if (v4l2_fh_is_singular_file(file)) {
 178                 /* start radio */
 179                 retval = si470x_start(radio);
 180                 if (retval < 0)
 181                         goto done;
 182 
 183                 /* enable RDS / STC interrupt */
 184                 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
 185                 radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
 186                 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
 187                 radio->registers[SYSCONFIG1] |= 0x1 << 2;
 188                 retval = si470x_set_register(radio, SYSCONFIG1);
 189         }
 190 
 191 done:
 192         if (retval)
 193                 v4l2_fh_release(file);
 194         return retval;
 195 }
 196 
 197 
 198 /*
 199  * si470x_fops_release - file release
 200  */
 201 static int si470x_fops_release(struct file *file)
 202 {
 203         struct si470x_device *radio = video_drvdata(file);
 204 
 205         if (v4l2_fh_is_singular_file(file))
 206                 /* stop radio */
 207                 si470x_stop(radio);
 208 
 209         return v4l2_fh_release(file);
 210 }
 211 
 212 
 213 
 214 /**************************************************************************
 215  * Video4Linux Interface
 216  **************************************************************************/
 217 
 218 /*
 219  * si470x_vidioc_querycap - query device capabilities
 220  */
 221 static int si470x_vidioc_querycap(struct file *file, void *priv,
 222                                   struct v4l2_capability *capability)
 223 {
 224         strscpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
 225         strscpy(capability->card, DRIVER_CARD, sizeof(capability->card));
 226         return 0;
 227 }
 228 
 229 
 230 
 231 /**************************************************************************
 232  * I2C Interface
 233  **************************************************************************/
 234 
 235 /*
 236  * si470x_i2c_interrupt - interrupt handler
 237  */
 238 static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
 239 {
 240         struct si470x_device *radio = dev_id;
 241         unsigned char regnr;
 242         unsigned char blocknum;
 243         unsigned short bler; /* rds block errors */
 244         unsigned short rds;
 245         unsigned char tmpbuf[3];
 246         int retval = 0;
 247 
 248         /* check Seek/Tune Complete */
 249         retval = si470x_get_register(radio, STATUSRSSI);
 250         if (retval < 0)
 251                 goto end;
 252 
 253         if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
 254                 complete(&radio->completion);
 255 
 256         /* safety checks */
 257         if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
 258                 goto end;
 259 
 260         /* Update RDS registers */
 261         for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
 262                 retval = si470x_get_register(radio, STATUSRSSI + regnr);
 263                 if (retval < 0)
 264                         goto end;
 265         }
 266 
 267         /* get rds blocks */
 268         if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
 269                 /* No RDS group ready, better luck next time */
 270                 goto end;
 271 
 272         for (blocknum = 0; blocknum < 4; blocknum++) {
 273                 switch (blocknum) {
 274                 default:
 275                         bler = (radio->registers[STATUSRSSI] &
 276                                         STATUSRSSI_BLERA) >> 9;
 277                         rds = radio->registers[RDSA];
 278                         break;
 279                 case 1:
 280                         bler = (radio->registers[READCHAN] &
 281                                         READCHAN_BLERB) >> 14;
 282                         rds = radio->registers[RDSB];
 283                         break;
 284                 case 2:
 285                         bler = (radio->registers[READCHAN] &
 286                                         READCHAN_BLERC) >> 12;
 287                         rds = radio->registers[RDSC];
 288                         break;
 289                 case 3:
 290                         bler = (radio->registers[READCHAN] &
 291                                         READCHAN_BLERD) >> 10;
 292                         rds = radio->registers[RDSD];
 293                         break;
 294                 }
 295 
 296                 /* Fill the V4L2 RDS buffer */
 297                 put_unaligned_le16(rds, &tmpbuf);
 298                 tmpbuf[2] = blocknum;           /* offset name */
 299                 tmpbuf[2] |= blocknum << 3;     /* received offset */
 300                 if (bler > max_rds_errors)
 301                         tmpbuf[2] |= 0x80;      /* uncorrectable errors */
 302                 else if (bler > 0)
 303                         tmpbuf[2] |= 0x40;      /* corrected error(s) */
 304 
 305                 /* copy RDS block to internal buffer */
 306                 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
 307                 radio->wr_index += 3;
 308 
 309                 /* wrap write pointer */
 310                 if (radio->wr_index >= radio->buf_size)
 311                         radio->wr_index = 0;
 312 
 313                 /* check for overflow */
 314                 if (radio->wr_index == radio->rd_index) {
 315                         /* increment and wrap read pointer */
 316                         radio->rd_index += 3;
 317                         if (radio->rd_index >= radio->buf_size)
 318                                 radio->rd_index = 0;
 319                 }
 320         }
 321 
 322         if (radio->wr_index != radio->rd_index)
 323                 wake_up_interruptible(&radio->read_queue);
 324 
 325 end:
 326         return IRQ_HANDLED;
 327 }
 328 
 329 
 330 /*
 331  * si470x_i2c_probe - probe for the device
 332  */
 333 static int si470x_i2c_probe(struct i2c_client *client)
 334 {
 335         struct si470x_device *radio;
 336         int retval = 0;
 337         unsigned char version_warning = 0;
 338 
 339         /* private data allocation and initialization */
 340         radio = devm_kzalloc(&client->dev, sizeof(*radio), GFP_KERNEL);
 341         if (!radio) {
 342                 retval = -ENOMEM;
 343                 goto err_initial;
 344         }
 345 
 346         radio->client = client;
 347         radio->band = 1; /* Default to 76 - 108 MHz */
 348         mutex_init(&radio->lock);
 349         init_completion(&radio->completion);
 350 
 351         radio->get_register = si470x_get_register;
 352         radio->set_register = si470x_set_register;
 353         radio->fops_open = si470x_fops_open;
 354         radio->fops_release = si470x_fops_release;
 355         radio->vidioc_querycap = si470x_vidioc_querycap;
 356 
 357         retval = v4l2_device_register(&client->dev, &radio->v4l2_dev);
 358         if (retval < 0) {
 359                 dev_err(&client->dev, "couldn't register v4l2_device\n");
 360                 goto err_initial;
 361         }
 362 
 363         v4l2_ctrl_handler_init(&radio->hdl, 2);
 364         v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
 365                         V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
 366         v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
 367                         V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15);
 368         if (radio->hdl.error) {
 369                 retval = radio->hdl.error;
 370                 dev_err(&client->dev, "couldn't register control\n");
 371                 goto err_dev;
 372         }
 373 
 374         /* video device initialization */
 375         radio->videodev = si470x_viddev_template;
 376         radio->videodev.ctrl_handler = &radio->hdl;
 377         radio->videodev.lock = &radio->lock;
 378         radio->videodev.v4l2_dev = &radio->v4l2_dev;
 379         radio->videodev.release = video_device_release_empty;
 380         radio->videodev.device_caps =
 381                 V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | V4L2_CAP_TUNER |
 382                 V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
 383         video_set_drvdata(&radio->videodev, radio);
 384 
 385         radio->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
 386                                                     GPIOD_OUT_LOW);
 387         if (IS_ERR(radio->gpio_reset)) {
 388                 retval = PTR_ERR(radio->gpio_reset);
 389                 dev_err(&client->dev, "Failed to request gpio: %d\n", retval);
 390                 goto err_all;
 391         }
 392 
 393         if (radio->gpio_reset)
 394                 gpiod_set_value(radio->gpio_reset, 1);
 395 
 396         /* power up : need 110ms */
 397         radio->registers[POWERCFG] = POWERCFG_ENABLE;
 398         if (si470x_set_register(radio, POWERCFG) < 0) {
 399                 retval = -EIO;
 400                 goto err_all;
 401         }
 402         msleep(110);
 403 
 404         /* get device and chip versions */
 405         if (si470x_get_all_registers(radio) < 0) {
 406                 retval = -EIO;
 407                 goto err_all;
 408         }
 409         dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
 410                         radio->registers[DEVICEID], radio->registers[SI_CHIPID]);
 411         if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
 412                 dev_warn(&client->dev,
 413                         "This driver is known to work with firmware version %hu,\n",
 414                         RADIO_FW_VERSION);
 415                 dev_warn(&client->dev,
 416                         "but the device has firmware version %hu.\n",
 417                         radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE);
 418                 version_warning = 1;
 419         }
 420 
 421         /* give out version warning */
 422         if (version_warning == 1) {
 423                 dev_warn(&client->dev,
 424                         "If you have some trouble using this driver,\n");
 425                 dev_warn(&client->dev,
 426                         "please report to V4L ML at linux-media@vger.kernel.org\n");
 427         }
 428 
 429         /* set initial frequency */
 430         si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
 431 
 432         /* rds buffer allocation */
 433         radio->buf_size = rds_buf * 3;
 434         radio->buffer = devm_kmalloc(&client->dev, radio->buf_size, GFP_KERNEL);
 435         if (!radio->buffer) {
 436                 retval = -EIO;
 437                 goto err_all;
 438         }
 439 
 440         /* rds buffer configuration */
 441         radio->wr_index = 0;
 442         radio->rd_index = 0;
 443         init_waitqueue_head(&radio->read_queue);
 444 
 445         retval = devm_request_threaded_irq(&client->dev, client->irq, NULL,
 446                                            si470x_i2c_interrupt,
 447                                            IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 448                                            DRIVER_NAME, radio);
 449         if (retval) {
 450                 dev_err(&client->dev, "Failed to register interrupt\n");
 451                 goto err_all;
 452         }
 453 
 454         /* register video device */
 455         retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
 456                         radio_nr);
 457         if (retval) {
 458                 dev_warn(&client->dev, "Could not register video device\n");
 459                 goto err_all;
 460         }
 461         i2c_set_clientdata(client, radio);
 462 
 463         return 0;
 464 err_all:
 465         v4l2_ctrl_handler_free(&radio->hdl);
 466 err_dev:
 467         v4l2_device_unregister(&radio->v4l2_dev);
 468 err_initial:
 469         return retval;
 470 }
 471 
 472 
 473 /*
 474  * si470x_i2c_remove - remove the device
 475  */
 476 static int si470x_i2c_remove(struct i2c_client *client)
 477 {
 478         struct si470x_device *radio = i2c_get_clientdata(client);
 479 
 480         video_unregister_device(&radio->videodev);
 481 
 482         if (radio->gpio_reset)
 483                 gpiod_set_value(radio->gpio_reset, 0);
 484 
 485         v4l2_ctrl_handler_free(&radio->hdl);
 486         v4l2_device_unregister(&radio->v4l2_dev);
 487         return 0;
 488 }
 489 
 490 
 491 #ifdef CONFIG_PM_SLEEP
 492 /*
 493  * si470x_i2c_suspend - suspend the device
 494  */
 495 static int si470x_i2c_suspend(struct device *dev)
 496 {
 497         struct i2c_client *client = to_i2c_client(dev);
 498         struct si470x_device *radio = i2c_get_clientdata(client);
 499 
 500         /* power down */
 501         radio->registers[POWERCFG] |= POWERCFG_DISABLE;
 502         if (si470x_set_register(radio, POWERCFG) < 0)
 503                 return -EIO;
 504 
 505         return 0;
 506 }
 507 
 508 
 509 /*
 510  * si470x_i2c_resume - resume the device
 511  */
 512 static int si470x_i2c_resume(struct device *dev)
 513 {
 514         struct i2c_client *client = to_i2c_client(dev);
 515         struct si470x_device *radio = i2c_get_clientdata(client);
 516 
 517         /* power up : need 110ms */
 518         radio->registers[POWERCFG] |= POWERCFG_ENABLE;
 519         if (si470x_set_register(radio, POWERCFG) < 0)
 520                 return -EIO;
 521         msleep(110);
 522 
 523         return 0;
 524 }
 525 
 526 static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
 527 #endif
 528 
 529 #if IS_ENABLED(CONFIG_OF)
 530 static const struct of_device_id si470x_of_match[] = {
 531         { .compatible = "silabs,si470x" },
 532         { },
 533 };
 534 MODULE_DEVICE_TABLE(of, si470x_of_match);
 535 #endif
 536 
 537 /*
 538  * si470x_i2c_driver - i2c driver interface
 539  */
 540 static struct i2c_driver si470x_i2c_driver = {
 541         .driver = {
 542                 .name           = "si470x",
 543                 .of_match_table = of_match_ptr(si470x_of_match),
 544 #ifdef CONFIG_PM_SLEEP
 545                 .pm             = &si470x_i2c_pm,
 546 #endif
 547         },
 548         .probe_new              = si470x_i2c_probe,
 549         .remove                 = si470x_i2c_remove,
 550         .id_table               = si470x_i2c_id,
 551 };
 552 
 553 module_i2c_driver(si470x_i2c_driver);
 554 
 555 MODULE_LICENSE("GPL");
 556 MODULE_AUTHOR(DRIVER_AUTHOR);
 557 MODULE_DESCRIPTION(DRIVER_DESC);
 558 MODULE_VERSION(DRIVER_VERSION);

/* [<][>][^][v][top][bottom][index][help] */