Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * drivers/media/radio/si470x/radio-si470x-i2c.c
0004  *
0005  * I2C driver for radios with Silicon Labs Si470x FM Radio Receivers
0006  *
0007  * Copyright (c) 2009 Samsung Electronics Co.Ltd
0008  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
0009  */
0010 
0011 
0012 /* driver definitions */
0013 #define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
0014 #define DRIVER_CARD "Silicon Labs Si470x FM Radio"
0015 #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
0016 #define DRIVER_VERSION "1.0.2"
0017 
0018 /* kernel includes */
0019 #include <linux/i2c.h>
0020 #include <linux/slab.h>
0021 #include <linux/delay.h>
0022 #include <linux/gpio/consumer.h>
0023 #include <linux/interrupt.h>
0024 
0025 #include "radio-si470x.h"
0026 
0027 
0028 /* I2C Device ID List */
0029 static const struct i2c_device_id si470x_i2c_id[] = {
0030     /* Generic Entry */
0031     { "si470x", 0 },
0032     /* Terminating entry */
0033     { }
0034 };
0035 MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
0036 
0037 
0038 /**************************************************************************
0039  * Module Parameters
0040  **************************************************************************/
0041 
0042 /* Radio Nr */
0043 static int radio_nr = -1;
0044 module_param(radio_nr, int, 0444);
0045 MODULE_PARM_DESC(radio_nr, "Radio Nr");
0046 
0047 /* RDS buffer blocks */
0048 static unsigned int rds_buf = 100;
0049 module_param(rds_buf, uint, 0444);
0050 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
0051 
0052 /* RDS maximum block errors */
0053 static unsigned short max_rds_errors = 1;
0054 /* 0 means   0  errors requiring correction */
0055 /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
0056 /* 2 means 3-5  errors requiring correction */
0057 /* 3 means   6+ errors or errors in checkword, correction not possible */
0058 module_param(max_rds_errors, ushort, 0644);
0059 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
0060 
0061 
0062 
0063 /**************************************************************************
0064  * I2C Definitions
0065  **************************************************************************/
0066 
0067 /* Write starts with the upper byte of register 0x02 */
0068 #define WRITE_REG_NUM       8
0069 #define WRITE_INDEX(i)      (i + 0x02)
0070 
0071 /* Read starts with the upper byte of register 0x0a */
0072 #define READ_REG_NUM        RADIO_REGISTER_NUM
0073 #define READ_INDEX(i)       ((i + RADIO_REGISTER_NUM - 0x0a) % READ_REG_NUM)
0074 
0075 
0076 
0077 /**************************************************************************
0078  * General Driver Functions - REGISTERs
0079  **************************************************************************/
0080 
0081 /*
0082  * si470x_get_register - read register
0083  */
0084 static int si470x_get_register(struct si470x_device *radio, int regnr)
0085 {
0086     __be16 buf[READ_REG_NUM];
0087     struct i2c_msg msgs[1] = {
0088         {
0089             .addr = radio->client->addr,
0090             .flags = I2C_M_RD,
0091             .len = sizeof(u16) * READ_REG_NUM,
0092             .buf = (void *)buf
0093         },
0094     };
0095 
0096     if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
0097         return -EIO;
0098 
0099     radio->registers[regnr] = __be16_to_cpu(buf[READ_INDEX(regnr)]);
0100 
0101     return 0;
0102 }
0103 
0104 
0105 /*
0106  * si470x_set_register - write register
0107  */
0108 static int si470x_set_register(struct si470x_device *radio, int regnr)
0109 {
0110     int i;
0111     __be16 buf[WRITE_REG_NUM];
0112     struct i2c_msg msgs[1] = {
0113         {
0114             .addr = radio->client->addr,
0115             .len = sizeof(u16) * WRITE_REG_NUM,
0116             .buf = (void *)buf
0117         },
0118     };
0119 
0120     for (i = 0; i < WRITE_REG_NUM; i++)
0121         buf[i] = __cpu_to_be16(radio->registers[WRITE_INDEX(i)]);
0122 
0123     if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
0124         return -EIO;
0125 
0126     return 0;
0127 }
0128 
0129 
0130 
0131 /**************************************************************************
0132  * General Driver Functions - ENTIRE REGISTERS
0133  **************************************************************************/
0134 
0135 /*
0136  * si470x_get_all_registers - read entire registers
0137  */
0138 static int si470x_get_all_registers(struct si470x_device *radio)
0139 {
0140     int i;
0141     __be16 buf[READ_REG_NUM];
0142     struct i2c_msg msgs[1] = {
0143         {
0144             .addr = radio->client->addr,
0145             .flags = I2C_M_RD,
0146             .len = sizeof(u16) * READ_REG_NUM,
0147             .buf = (void *)buf
0148         },
0149     };
0150 
0151     if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
0152         return -EIO;
0153 
0154     for (i = 0; i < READ_REG_NUM; i++)
0155         radio->registers[i] = __be16_to_cpu(buf[READ_INDEX(i)]);
0156 
0157     return 0;
0158 }
0159 
0160 
0161 
0162 /**************************************************************************
0163  * File Operations Interface
0164  **************************************************************************/
0165 
0166 /*
0167  * si470x_fops_open - file open
0168  */
0169 static int si470x_fops_open(struct file *file)
0170 {
0171     struct si470x_device *radio = video_drvdata(file);
0172     int retval = v4l2_fh_open(file);
0173 
0174     if (retval)
0175         return retval;
0176 
0177     if (v4l2_fh_is_singular_file(file)) {
0178         /* start radio */
0179         retval = si470x_start(radio);
0180         if (retval < 0)
0181             goto done;
0182 
0183         /* enable RDS / STC interrupt */
0184         radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
0185         radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
0186         radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
0187         radio->registers[SYSCONFIG1] |= 0x1 << 2;
0188         retval = si470x_set_register(radio, SYSCONFIG1);
0189     }
0190 
0191 done:
0192     if (retval)
0193         v4l2_fh_release(file);
0194     return retval;
0195 }
0196 
0197 
0198 /*
0199  * si470x_fops_release - file release
0200  */
0201 static int si470x_fops_release(struct file *file)
0202 {
0203     struct si470x_device *radio = video_drvdata(file);
0204 
0205     if (v4l2_fh_is_singular_file(file))
0206         /* stop radio */
0207         si470x_stop(radio);
0208 
0209     return v4l2_fh_release(file);
0210 }
0211 
0212 
0213 
0214 /**************************************************************************
0215  * Video4Linux Interface
0216  **************************************************************************/
0217 
0218 /*
0219  * si470x_vidioc_querycap - query device capabilities
0220  */
0221 static int si470x_vidioc_querycap(struct file *file, void *priv,
0222                   struct v4l2_capability *capability)
0223 {
0224     strscpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
0225     strscpy(capability->card, DRIVER_CARD, sizeof(capability->card));
0226     return 0;
0227 }
0228 
0229 
0230 
0231 /**************************************************************************
0232  * I2C Interface
0233  **************************************************************************/
0234 
0235 /*
0236  * si470x_i2c_interrupt - interrupt handler
0237  */
0238 static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
0239 {
0240     struct si470x_device *radio = dev_id;
0241     unsigned char regnr;
0242     unsigned char blocknum;
0243     unsigned short bler; /* rds block errors */
0244     unsigned short rds;
0245     unsigned char tmpbuf[3];
0246     int retval = 0;
0247 
0248     /* check Seek/Tune Complete */
0249     retval = si470x_get_register(radio, STATUSRSSI);
0250     if (retval < 0)
0251         goto end;
0252 
0253     if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
0254         complete(&radio->completion);
0255 
0256     /* safety checks */
0257     if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
0258         goto end;
0259 
0260     /* Update RDS registers */
0261     for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
0262         retval = si470x_get_register(radio, STATUSRSSI + regnr);
0263         if (retval < 0)
0264             goto end;
0265     }
0266 
0267     /* get rds blocks */
0268     if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
0269         /* No RDS group ready, better luck next time */
0270         goto end;
0271 
0272     for (blocknum = 0; blocknum < 4; blocknum++) {
0273         switch (blocknum) {
0274         default:
0275             bler = (radio->registers[STATUSRSSI] &
0276                     STATUSRSSI_BLERA) >> 9;
0277             rds = radio->registers[RDSA];
0278             break;
0279         case 1:
0280             bler = (radio->registers[READCHAN] &
0281                     READCHAN_BLERB) >> 14;
0282             rds = radio->registers[RDSB];
0283             break;
0284         case 2:
0285             bler = (radio->registers[READCHAN] &
0286                     READCHAN_BLERC) >> 12;
0287             rds = radio->registers[RDSC];
0288             break;
0289         case 3:
0290             bler = (radio->registers[READCHAN] &
0291                     READCHAN_BLERD) >> 10;
0292             rds = radio->registers[RDSD];
0293             break;
0294         }
0295 
0296         /* Fill the V4L2 RDS buffer */
0297         put_unaligned_le16(rds, &tmpbuf);
0298         tmpbuf[2] = blocknum;       /* offset name */
0299         tmpbuf[2] |= blocknum << 3; /* received offset */
0300         if (bler > max_rds_errors)
0301             tmpbuf[2] |= 0x80;  /* uncorrectable errors */
0302         else if (bler > 0)
0303             tmpbuf[2] |= 0x40;  /* corrected error(s) */
0304 
0305         /* copy RDS block to internal buffer */
0306         memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
0307         radio->wr_index += 3;
0308 
0309         /* wrap write pointer */
0310         if (radio->wr_index >= radio->buf_size)
0311             radio->wr_index = 0;
0312 
0313         /* check for overflow */
0314         if (radio->wr_index == radio->rd_index) {
0315             /* increment and wrap read pointer */
0316             radio->rd_index += 3;
0317             if (radio->rd_index >= radio->buf_size)
0318                 radio->rd_index = 0;
0319         }
0320     }
0321 
0322     if (radio->wr_index != radio->rd_index)
0323         wake_up_interruptible(&radio->read_queue);
0324 
0325 end:
0326     return IRQ_HANDLED;
0327 }
0328 
0329 
0330 /*
0331  * si470x_i2c_probe - probe for the device
0332  */
0333 static int si470x_i2c_probe(struct i2c_client *client)
0334 {
0335     struct si470x_device *radio;
0336     int retval = 0;
0337 
0338     /* private data allocation and initialization */
0339     radio = devm_kzalloc(&client->dev, sizeof(*radio), GFP_KERNEL);
0340     if (!radio) {
0341         retval = -ENOMEM;
0342         goto err_initial;
0343     }
0344 
0345     radio->client = client;
0346     radio->band = 1; /* Default to 76 - 108 MHz */
0347     mutex_init(&radio->lock);
0348     init_completion(&radio->completion);
0349 
0350     radio->get_register = si470x_get_register;
0351     radio->set_register = si470x_set_register;
0352     radio->fops_open = si470x_fops_open;
0353     radio->fops_release = si470x_fops_release;
0354     radio->vidioc_querycap = si470x_vidioc_querycap;
0355 
0356     retval = v4l2_device_register(&client->dev, &radio->v4l2_dev);
0357     if (retval < 0) {
0358         dev_err(&client->dev, "couldn't register v4l2_device\n");
0359         goto err_initial;
0360     }
0361 
0362     v4l2_ctrl_handler_init(&radio->hdl, 2);
0363     v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
0364             V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
0365     v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
0366             V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15);
0367     if (radio->hdl.error) {
0368         retval = radio->hdl.error;
0369         dev_err(&client->dev, "couldn't register control\n");
0370         goto err_all;
0371     }
0372 
0373     /* video device initialization */
0374     radio->videodev = si470x_viddev_template;
0375     radio->videodev.ctrl_handler = &radio->hdl;
0376     radio->videodev.lock = &radio->lock;
0377     radio->videodev.v4l2_dev = &radio->v4l2_dev;
0378     radio->videodev.release = video_device_release_empty;
0379     radio->videodev.device_caps =
0380         V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | V4L2_CAP_TUNER |
0381         V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
0382     video_set_drvdata(&radio->videodev, radio);
0383 
0384     radio->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
0385                             GPIOD_OUT_LOW);
0386     if (IS_ERR(radio->gpio_reset)) {
0387         retval = PTR_ERR(radio->gpio_reset);
0388         dev_err(&client->dev, "Failed to request gpio: %d\n", retval);
0389         goto err_all;
0390     }
0391 
0392     if (radio->gpio_reset)
0393         gpiod_set_value(radio->gpio_reset, 1);
0394 
0395     /* power up : need 110ms */
0396     radio->registers[POWERCFG] = POWERCFG_ENABLE;
0397     if (si470x_set_register(radio, POWERCFG) < 0) {
0398         retval = -EIO;
0399         goto err_all;
0400     }
0401     msleep(110);
0402 
0403     /* get device and chip versions */
0404     if (si470x_get_all_registers(radio) < 0) {
0405         retval = -EIO;
0406         goto err_all;
0407     }
0408     dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
0409             radio->registers[DEVICEID], radio->registers[SI_CHIPID]);
0410     if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
0411         dev_warn(&client->dev,
0412             "This driver is known to work with firmware version %u, but the device has firmware version %u.\n"
0413             "If you have some trouble using this driver, please report to V4L ML at linux-media@vger.kernel.org\n",
0414             RADIO_FW_VERSION,
0415             radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE);
0416     }
0417 
0418     /* set initial frequency */
0419     si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
0420 
0421     /* rds buffer allocation */
0422     radio->buf_size = rds_buf * 3;
0423     radio->buffer = devm_kmalloc(&client->dev, radio->buf_size, GFP_KERNEL);
0424     if (!radio->buffer) {
0425         retval = -EIO;
0426         goto err_all;
0427     }
0428 
0429     /* rds buffer configuration */
0430     radio->wr_index = 0;
0431     radio->rd_index = 0;
0432     init_waitqueue_head(&radio->read_queue);
0433 
0434     retval = devm_request_threaded_irq(&client->dev, client->irq, NULL,
0435                        si470x_i2c_interrupt,
0436                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0437                        DRIVER_NAME, radio);
0438     if (retval) {
0439         dev_err(&client->dev, "Failed to register interrupt\n");
0440         goto err_all;
0441     }
0442 
0443     /* register video device */
0444     retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
0445             radio_nr);
0446     if (retval) {
0447         dev_warn(&client->dev, "Could not register video device\n");
0448         goto err_all;
0449     }
0450     i2c_set_clientdata(client, radio);
0451 
0452     return 0;
0453 err_all:
0454     v4l2_ctrl_handler_free(&radio->hdl);
0455     v4l2_device_unregister(&radio->v4l2_dev);
0456 err_initial:
0457     return retval;
0458 }
0459 
0460 
0461 /*
0462  * si470x_i2c_remove - remove the device
0463  */
0464 static int si470x_i2c_remove(struct i2c_client *client)
0465 {
0466     struct si470x_device *radio = i2c_get_clientdata(client);
0467 
0468     video_unregister_device(&radio->videodev);
0469 
0470     if (radio->gpio_reset)
0471         gpiod_set_value(radio->gpio_reset, 0);
0472 
0473     v4l2_ctrl_handler_free(&radio->hdl);
0474     v4l2_device_unregister(&radio->v4l2_dev);
0475     return 0;
0476 }
0477 
0478 
0479 #ifdef CONFIG_PM_SLEEP
0480 /*
0481  * si470x_i2c_suspend - suspend the device
0482  */
0483 static int si470x_i2c_suspend(struct device *dev)
0484 {
0485     struct i2c_client *client = to_i2c_client(dev);
0486     struct si470x_device *radio = i2c_get_clientdata(client);
0487 
0488     /* power down */
0489     radio->registers[POWERCFG] |= POWERCFG_DISABLE;
0490     if (si470x_set_register(radio, POWERCFG) < 0)
0491         return -EIO;
0492 
0493     return 0;
0494 }
0495 
0496 
0497 /*
0498  * si470x_i2c_resume - resume the device
0499  */
0500 static int si470x_i2c_resume(struct device *dev)
0501 {
0502     struct i2c_client *client = to_i2c_client(dev);
0503     struct si470x_device *radio = i2c_get_clientdata(client);
0504 
0505     /* power up : need 110ms */
0506     radio->registers[POWERCFG] |= POWERCFG_ENABLE;
0507     if (si470x_set_register(radio, POWERCFG) < 0)
0508         return -EIO;
0509     msleep(110);
0510 
0511     return 0;
0512 }
0513 
0514 static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
0515 #endif
0516 
0517 #if IS_ENABLED(CONFIG_OF)
0518 static const struct of_device_id si470x_of_match[] = {
0519     { .compatible = "silabs,si470x" },
0520     { },
0521 };
0522 MODULE_DEVICE_TABLE(of, si470x_of_match);
0523 #endif
0524 
0525 /*
0526  * si470x_i2c_driver - i2c driver interface
0527  */
0528 static struct i2c_driver si470x_i2c_driver = {
0529     .driver = {
0530         .name       = "si470x",
0531         .of_match_table = of_match_ptr(si470x_of_match),
0532 #ifdef CONFIG_PM_SLEEP
0533         .pm     = &si470x_i2c_pm,
0534 #endif
0535     },
0536     .probe_new      = si470x_i2c_probe,
0537     .remove         = si470x_i2c_remove,
0538     .id_table       = si470x_i2c_id,
0539 };
0540 
0541 module_i2c_driver(si470x_i2c_driver);
0542 
0543 MODULE_LICENSE("GPL");
0544 MODULE_AUTHOR(DRIVER_AUTHOR);
0545 MODULE_DESCRIPTION(DRIVER_DESC);
0546 MODULE_VERSION(DRIVER_VERSION);