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{
 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;
 464err_all:
 465        v4l2_ctrl_handler_free(&radio->hdl);
 466err_dev:
 467        v4l2_device_unregister(&radio->v4l2_dev);
 468err_initial:
 469        return retval;
 470}
 471
 472
 473/*
 474 * si470x_i2c_remove - remove the device
 475 */
 476static 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 */
 495static 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 */
 512static 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
 526static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
 527#endif
 528
 529#if IS_ENABLED(CONFIG_OF)
 530static const struct of_device_id si470x_of_match[] = {
 531        { .compatible = "silabs,si470x" },
 532        { },
 533};
 534MODULE_DEVICE_TABLE(of, si470x_of_match);
 535#endif
 536
 537/*
 538 * si470x_i2c_driver - i2c driver interface
 539 */
 540static 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
 553module_i2c_driver(si470x_i2c_driver);
 554
 555MODULE_LICENSE("GPL");
 556MODULE_AUTHOR(DRIVER_AUTHOR);
 557MODULE_DESCRIPTION(DRIVER_DESC);
 558MODULE_VERSION(DRIVER_VERSION);
 559