linux/drivers/media/radio/si470x/radio-si470x-i2c.c
<<
>>
Prefs
   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 */
  29static const struct i2c_device_id si470x_i2c_id[] = {
  30        /* Generic Entry */
  31        { "si470x", 0 },
  32        /* Terminating entry */
  33        { }
  34};
  35MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
  36
  37
  38/**************************************************************************
  39 * Module Parameters
  40 **************************************************************************/
  41
  42/* Radio Nr */
  43static int radio_nr = -1;
  44module_param(radio_nr, int, 0444);
  45MODULE_PARM_DESC(radio_nr, "Radio Nr");
  46
  47/* RDS buffer blocks */
  48static unsigned int rds_buf = 100;
  49module_param(rds_buf, uint, 0444);
  50MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
  51
  52/* RDS maximum block errors */
  53static 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 */
  58module_param(max_rds_errors, ushort, 0644);
  59MODULE_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 */
  84static 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 */
 108static 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 */
 138static 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 */
 169static 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
 191done:
 192        if (retval)
 193                v4l2_fh_release(file);
 194        return retval;
 195}
 196
 197
 198/*
 199 * si470x_fops_release - file release
 200 */
 201static 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 */
 221static 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 */
 238static 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
 325end:
 326        return IRQ_HANDLED;
 327}
 328
 329
 330/*
 331 * si470x_i2c_probe - probe for the device
 332 */
 333static int si470x_i2c_probe(struct i2c_client *client,
 334                            const struct i2c_device_id *id)
 335{
 336        struct si470x_device *radio;
 337        int retval = 0;
 338        unsigned char version_warning = 0;
 339
 340        /* private data allocation and initialization */
 341        radio = devm_kzalloc(&client->dev, sizeof(*radio), GFP_KERNEL);
 342        if (!radio) {
 343                retval = -ENOMEM;
 344                goto err_initial;
 345        }
 346
 347        radio->client = client;
 348        radio->band = 1; /* Default to 76 - 108 MHz */
 349        mutex_init(&radio->lock);
 350        init_completion(&radio->completion);
 351
 352        radio->get_register = si470x_get_register;
 353        radio->set_register = si470x_set_register;
 354        radio->fops_open = si470x_fops_open;
 355        radio->fops_release = si470x_fops_release;
 356        radio->vidioc_querycap = si470x_vidioc_querycap;
 357
 358        retval = v4l2_device_register(&client->dev, &radio->v4l2_dev);
 359        if (retval < 0) {
 360                dev_err(&client->dev, "couldn't register v4l2_device\n");
 361                goto err_initial;
 362        }
 363
 364        v4l2_ctrl_handler_init(&radio->hdl, 2);
 365        v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
 366                        V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
 367        v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
 368                        V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15);
 369        if (radio->hdl.error) {
 370                retval = radio->hdl.error;
 371                dev_err(&client->dev, "couldn't register control\n");
 372                goto err_dev;
 373        }
 374
 375        /* video device initialization */
 376        radio->videodev = si470x_viddev_template;
 377        radio->videodev.ctrl_handler = &radio->hdl;
 378        radio->videodev.lock = &radio->lock;
 379        radio->videodev.v4l2_dev = &radio->v4l2_dev;
 380        radio->videodev.release = video_device_release_empty;
 381        radio->videodev.device_caps =
 382                V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | V4L2_CAP_TUNER |
 383                V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
 384        video_set_drvdata(&radio->videodev, radio);
 385
 386        radio->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
 387                                                    GPIOD_OUT_LOW);
 388        if (IS_ERR(radio->gpio_reset)) {
 389                retval = PTR_ERR(radio->gpio_reset);
 390                dev_err(&client->dev, "Failed to request gpio: %d\n", retval);
 391                goto err_all;
 392        }
 393
 394        if (radio->gpio_reset)
 395                gpiod_set_value(radio->gpio_reset, 1);
 396
 397        /* power up : need 110ms */
 398        radio->registers[POWERCFG] = POWERCFG_ENABLE;
 399        if (si470x_set_register(radio, POWERCFG) < 0) {
 400                retval = -EIO;
 401                goto err_all;
 402        }
 403        msleep(110);
 404
 405        /* get device and chip versions */
 406        if (si470x_get_all_registers(radio) < 0) {
 407                retval = -EIO;
 408                goto err_all;
 409        }
 410        dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
 411                        radio->registers[DEVICEID], radio->registers[SI_CHIPID]);
 412        if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
 413                dev_warn(&client->dev,
 414                        "This driver is known to work with firmware version %hu,\n",
 415                        RADIO_FW_VERSION);
 416                dev_warn(&client->dev,
 417                        "but the device has firmware version %hu.\n",
 418                        radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE);
 419                version_warning = 1;
 420        }
 421
 422        /* give out version warning */
 423        if (version_warning == 1) {
 424                dev_warn(&client->dev,
 425                        "If you have some trouble using this driver,\n");
 426                dev_warn(&client->dev,
 427                        "please report to V4L ML at linux-media@vger.kernel.org\n");
 428        }
 429
 430        /* set initial frequency */
 431        si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
 432
 433        /* rds buffer allocation */
 434        radio->buf_size = rds_buf * 3;
 435        radio->buffer = devm_kmalloc(&client->dev, radio->buf_size, GFP_KERNEL);
 436        if (!radio->buffer) {
 437                retval = -EIO;
 438                goto err_all;
 439        }
 440
 441        /* rds buffer configuration */
 442        radio->wr_index = 0;
 443        radio->rd_index = 0;
 444        init_waitqueue_head(&radio->read_queue);
 445
 446        retval = devm_request_threaded_irq(&client->dev, client->irq, NULL,
 447                                           si470x_i2c_interrupt,
 448                                           IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 449                                           DRIVER_NAME, radio);
 450        if (retval) {
 451                dev_err(&client->dev, "Failed to register interrupt\n");
 452                goto err_all;
 453        }
 454
 455        /* register video device */
 456        retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
 457                        radio_nr);
 458        if (retval) {
 459                dev_warn(&client->dev, "Could not register video device\n");
 460                goto err_all;
 461        }
 462        i2c_set_clientdata(client, radio);
 463
 464        return 0;
 465err_all:
 466        v4l2_ctrl_handler_free(&radio->hdl);
 467err_dev:
 468        v4l2_device_unregister(&radio->v4l2_dev);
 469err_initial:
 470        return retval;
 471}
 472
 473
 474/*
 475 * si470x_i2c_remove - remove the device
 476 */
 477static int si470x_i2c_remove(struct i2c_client *client)
 478{
 479        struct si470x_device *radio = i2c_get_clientdata(client);
 480
 481        video_unregister_device(&radio->videodev);
 482
 483        if (radio->gpio_reset)
 484                gpiod_set_value(radio->gpio_reset, 0);
 485
 486        return 0;
 487}
 488
 489
 490#ifdef CONFIG_PM_SLEEP
 491/*
 492 * si470x_i2c_suspend - suspend the device
 493 */
 494static int si470x_i2c_suspend(struct device *dev)
 495{
 496        struct i2c_client *client = to_i2c_client(dev);
 497        struct si470x_device *radio = i2c_get_clientdata(client);
 498
 499        /* power down */
 500        radio->registers[POWERCFG] |= POWERCFG_DISABLE;
 501        if (si470x_set_register(radio, POWERCFG) < 0)
 502                return -EIO;
 503
 504        return 0;
 505}
 506
 507
 508/*
 509 * si470x_i2c_resume - resume the device
 510 */
 511static int si470x_i2c_resume(struct device *dev)
 512{
 513        struct i2c_client *client = to_i2c_client(dev);
 514        struct si470x_device *radio = i2c_get_clientdata(client);
 515
 516        /* power up : need 110ms */
 517        radio->registers[POWERCFG] |= POWERCFG_ENABLE;
 518        if (si470x_set_register(radio, POWERCFG) < 0)
 519                return -EIO;
 520        msleep(110);
 521
 522        return 0;
 523}
 524
 525static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
 526#endif
 527
 528#if IS_ENABLED(CONFIG_OF)
 529static const struct of_device_id si470x_of_match[] = {
 530        { .compatible = "silabs,si470x" },
 531        { },
 532};
 533MODULE_DEVICE_TABLE(of, si470x_of_match);
 534#endif
 535
 536/*
 537 * si470x_i2c_driver - i2c driver interface
 538 */
 539static struct i2c_driver si470x_i2c_driver = {
 540        .driver = {
 541                .name           = "si470x",
 542                .of_match_table = of_match_ptr(si470x_of_match),
 543#ifdef CONFIG_PM_SLEEP
 544                .pm             = &si470x_i2c_pm,
 545#endif
 546        },
 547        .probe                  = si470x_i2c_probe,
 548        .remove                 = si470x_i2c_remove,
 549        .id_table               = si470x_i2c_id,
 550};
 551
 552module_i2c_driver(si470x_i2c_driver);
 553
 554MODULE_LICENSE("GPL");
 555MODULE_AUTHOR(DRIVER_AUTHOR);
 556MODULE_DESCRIPTION(DRIVER_DESC);
 557MODULE_VERSION(DRIVER_VERSION);
 558