Path: blob/master/drivers/media/radio/radio-wl1273.c
15111 views
/*1* Driver for the Texas Instruments WL1273 FM radio.2*3* Copyright (C) 2011 Nokia Corporation4* Author: Matti J. Aaltonen <[email protected]>5*6* This program is free software; you can redistribute it and/or7* modify it under the terms of the GNU General Public License8* version 2 as published by the Free Software Foundation.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18*/1920#include <linux/delay.h>21#include <linux/firmware.h>22#include <linux/interrupt.h>23#include <linux/mfd/wl1273-core.h>24#include <linux/slab.h>25#include <media/v4l2-common.h>26#include <media/v4l2-ctrls.h>27#include <media/v4l2-device.h>28#include <media/v4l2-ioctl.h>2930#define DRIVER_DESC "Wl1273 FM Radio"3132#define WL1273_POWER_SET_OFF 033#define WL1273_POWER_SET_FM BIT(0)34#define WL1273_POWER_SET_RDS BIT(1)35#define WL1273_POWER_SET_RETENTION BIT(4)3637#define WL1273_PUPD_SET_OFF 0x0038#define WL1273_PUPD_SET_ON 0x0139#define WL1273_PUPD_SET_RETENTION 0x104041#define WL1273_FREQ(x) (x * 10000 / 625)42#define WL1273_INV_FREQ(x) (x * 625 / 10000)4344/*45* static int radio_nr - The number of the radio device46*47* The default is 0.48*/49static int radio_nr;50module_param(radio_nr, int, 0);51MODULE_PARM_DESC(radio_nr, "The number of the radio device. Default = 0");5253struct wl1273_device {54char *bus_type;5556u8 forbidden;57unsigned int preemphasis;58unsigned int spacing;59unsigned int tx_power;60unsigned int rx_frequency;61unsigned int tx_frequency;62unsigned int rangelow;63unsigned int rangehigh;64unsigned int band;65bool stereo;6667/* RDS */68unsigned int rds_on;6970wait_queue_head_t read_queue;71struct mutex lock; /* for serializing fm radio operations */72struct completion busy;7374unsigned char *buffer;75unsigned int buf_size;76unsigned int rd_index;77unsigned int wr_index;7879/* Selected interrupts */80u16 irq_flags;81u16 irq_received;8283struct v4l2_ctrl_handler ctrl_handler;84struct v4l2_device v4l2dev;85struct video_device videodev;86struct device *dev;87struct wl1273_core *core;88struct file *owner;89char *write_buf;90unsigned int rds_users;91};9293#define WL1273_IRQ_MASK (WL1273_FR_EVENT | \94WL1273_POW_ENB_EVENT)9596/*97* static unsigned int rds_buf - the number of RDS buffer blocks used.98*99* The default number is 100.100*/101static unsigned int rds_buf = 100;102module_param(rds_buf, uint, 0);103MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");104105static int wl1273_fm_write_fw(struct wl1273_core *core,106__u8 *fw, int len)107{108struct i2c_client *client = core->client;109struct i2c_msg msg;110int i, r = 0;111112msg.addr = client->addr;113msg.flags = 0;114115for (i = 0; i <= len; i++) {116msg.len = fw[0];117msg.buf = fw + 1;118119fw += msg.len + 1;120dev_dbg(&client->dev, "%s:len[%d]: %d\n", __func__, i, msg.len);121122r = i2c_transfer(client->adapter, &msg, 1);123if (r < 0 && i < len + 1)124break;125}126127dev_dbg(&client->dev, "%s: i: %d\n", __func__, i);128dev_dbg(&client->dev, "%s: len + 1: %d\n", __func__, len + 1);129130/* Last transfer always fails. */131if (i == len || r == 1)132r = 0;133134return r;135}136137#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)138#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)139#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)140141static int wl1273_fm_rds(struct wl1273_device *radio)142{143struct wl1273_core *core = radio->core;144struct i2c_client *client = core->client;145u16 val;146u8 b0 = WL1273_RDS_DATA_GET, status;147struct v4l2_rds_data rds = { 0, 0, 0 };148struct i2c_msg msg[] = {149{150.addr = client->addr,151.flags = 0,152.buf = &b0,153.len = 1,154},155{156.addr = client->addr,157.flags = I2C_M_RD,158.buf = (u8 *) &rds,159.len = sizeof(rds),160}161};162int r;163164if (core->mode != WL1273_MODE_RX)165return 0;166167r = core->read(core, WL1273_RDS_SYNC_GET, &val);168if (r)169return r;170171if ((val & 0x01) == 0) {172/* RDS decoder not synchronized */173return -EAGAIN;174}175176/* copy all four RDS blocks to internal buffer */177do {178r = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));179if (r != ARRAY_SIZE(msg)) {180dev_err(radio->dev, WL1273_FM_DRIVER_NAME181": %s: read_rds error r == %i)\n",182__func__, r);183}184185status = rds.block;186187if (!WL1273_FIFO_HAS_DATA(status))188break;189190/* copy bits 0-2 (the block ID) to bits 3-5 */191rds.block = V4L2_RDS_BLOCK_MSK & status;192rds.block |= rds.block << 3;193194/* copy the error bits to standard positions */195if (WL1273_RDS_UNCORRECTABLE_ERROR & status) {196rds.block |= V4L2_RDS_BLOCK_ERROR;197rds.block &= ~V4L2_RDS_BLOCK_CORRECTED;198} else if (WL1273_RDS_CORRECTABLE_ERROR & status) {199rds.block &= ~V4L2_RDS_BLOCK_ERROR;200rds.block |= V4L2_RDS_BLOCK_CORRECTED;201}202203/* copy RDS block to internal buffer */204memcpy(&radio->buffer[radio->wr_index], &rds, RDS_BLOCK_SIZE);205radio->wr_index += 3;206207/* wrap write pointer */208if (radio->wr_index >= radio->buf_size)209radio->wr_index = 0;210211/* check for overflow & start over */212if (radio->wr_index == radio->rd_index) {213dev_dbg(radio->dev, "RDS OVERFLOW");214215radio->rd_index = 0;216radio->wr_index = 0;217break;218}219} while (WL1273_FIFO_HAS_DATA(status));220221/* wake up read queue */222if (radio->wr_index != radio->rd_index)223wake_up_interruptible(&radio->read_queue);224225return 0;226}227228static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)229{230struct wl1273_device *radio = dev_id;231struct wl1273_core *core = radio->core;232u16 flags;233int r;234235r = core->read(core, WL1273_FLAG_GET, &flags);236if (r)237goto out;238239if (flags & WL1273_BL_EVENT) {240radio->irq_received = flags;241dev_dbg(radio->dev, "IRQ: BL\n");242}243244if (flags & WL1273_RDS_EVENT) {245msleep(200);246247wl1273_fm_rds(radio);248}249250if (flags & WL1273_BBLK_EVENT)251dev_dbg(radio->dev, "IRQ: BBLK\n");252253if (flags & WL1273_LSYNC_EVENT)254dev_dbg(radio->dev, "IRQ: LSYNC\n");255256if (flags & WL1273_LEV_EVENT) {257u16 level;258259r = core->read(core, WL1273_RSSI_LVL_GET, &level);260if (r)261goto out;262263if (level > 14)264dev_dbg(radio->dev, "IRQ: LEV: 0x%x04\n", level);265}266267if (flags & WL1273_IFFR_EVENT)268dev_dbg(radio->dev, "IRQ: IFFR\n");269270if (flags & WL1273_PI_EVENT)271dev_dbg(radio->dev, "IRQ: PI\n");272273if (flags & WL1273_PD_EVENT)274dev_dbg(radio->dev, "IRQ: PD\n");275276if (flags & WL1273_STIC_EVENT)277dev_dbg(radio->dev, "IRQ: STIC\n");278279if (flags & WL1273_MAL_EVENT)280dev_dbg(radio->dev, "IRQ: MAL\n");281282if (flags & WL1273_POW_ENB_EVENT) {283complete(&radio->busy);284dev_dbg(radio->dev, "NOT BUSY\n");285dev_dbg(radio->dev, "IRQ: POW_ENB\n");286}287288if (flags & WL1273_SCAN_OVER_EVENT)289dev_dbg(radio->dev, "IRQ: SCAN_OVER\n");290291if (flags & WL1273_ERROR_EVENT)292dev_dbg(radio->dev, "IRQ: ERROR\n");293294if (flags & WL1273_FR_EVENT) {295u16 freq;296297dev_dbg(radio->dev, "IRQ: FR:\n");298299if (core->mode == WL1273_MODE_RX) {300r = core->write(core, WL1273_TUNER_MODE_SET,301TUNER_MODE_STOP_SEARCH);302if (r) {303dev_err(radio->dev,304"%s: TUNER_MODE_SET fails: %d\n",305__func__, r);306goto out;307}308309r = core->read(core, WL1273_FREQ_SET, &freq);310if (r)311goto out;312313if (radio->band == WL1273_BAND_JAPAN)314radio->rx_frequency = WL1273_BAND_JAPAN_LOW +315freq * 50;316else317radio->rx_frequency = WL1273_BAND_OTHER_LOW +318freq * 50;319/*320* The driver works better with this msleep,321* the documentation doesn't mention it.322*/323usleep_range(10000, 15000);324325dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);326327} else {328r = core->read(core, WL1273_CHANL_SET, &freq);329if (r)330goto out;331332dev_dbg(radio->dev, "%dkHz\n", freq);333}334dev_dbg(radio->dev, "%s: NOT BUSY\n", __func__);335}336337out:338core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);339complete(&radio->busy);340341return IRQ_HANDLED;342}343344static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)345{346struct wl1273_core *core = radio->core;347int r = 0;348349if (freq < WL1273_BAND_TX_LOW) {350dev_err(radio->dev,351"Frequency out of range: %d < %d\n", freq,352WL1273_BAND_TX_LOW);353return -ERANGE;354}355356if (freq > WL1273_BAND_TX_HIGH) {357dev_err(radio->dev,358"Frequency out of range: %d > %d\n", freq,359WL1273_BAND_TX_HIGH);360return -ERANGE;361}362363/*364* The driver works better with this sleep,365* the documentation doesn't mention it.366*/367usleep_range(5000, 10000);368369dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);370371/* Set the current tx channel */372r = core->write(core, WL1273_CHANL_SET, freq / 10);373if (r)374return r;375376INIT_COMPLETION(radio->busy);377378/* wait for the FR IRQ */379r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000));380if (!r)381return -ETIMEDOUT;382383dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r);384385/* Enable the output power */386r = core->write(core, WL1273_POWER_ENB_SET, 1);387if (r)388return r;389390INIT_COMPLETION(radio->busy);391392/* wait for the POWER_ENB IRQ */393r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));394if (!r)395return -ETIMEDOUT;396397radio->tx_frequency = freq;398dev_dbg(radio->dev, "WL1273_POWER_ENB_SET: %d\n", r);399400return 0;401}402403static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)404{405struct wl1273_core *core = radio->core;406int r, f;407408if (freq < radio->rangelow) {409dev_err(radio->dev,410"Frequency out of range: %d < %d\n", freq,411radio->rangelow);412r = -ERANGE;413goto err;414}415416if (freq > radio->rangehigh) {417dev_err(radio->dev,418"Frequency out of range: %d > %d\n", freq,419radio->rangehigh);420r = -ERANGE;421goto err;422}423424dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);425426core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);427428if (radio->band == WL1273_BAND_JAPAN)429f = (freq - WL1273_BAND_JAPAN_LOW) / 50;430else431f = (freq - WL1273_BAND_OTHER_LOW) / 50;432433r = core->write(core, WL1273_FREQ_SET, f);434if (r) {435dev_err(radio->dev, "FREQ_SET fails\n");436goto err;437}438439r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);440if (r) {441dev_err(radio->dev, "TUNER_MODE_SET fails\n");442goto err;443}444445INIT_COMPLETION(radio->busy);446447r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000));448if (!r) {449dev_err(radio->dev, "%s: TIMEOUT\n", __func__);450return -ETIMEDOUT;451}452453radio->rd_index = 0;454radio->wr_index = 0;455radio->rx_frequency = freq;456return 0;457err:458return r;459}460461static int wl1273_fm_get_freq(struct wl1273_device *radio)462{463struct wl1273_core *core = radio->core;464unsigned int freq;465u16 f;466int r;467468if (core->mode == WL1273_MODE_RX) {469r = core->read(core, WL1273_FREQ_SET, &f);470if (r)471return r;472473dev_dbg(radio->dev, "Freq get: 0x%04x\n", f);474if (radio->band == WL1273_BAND_JAPAN)475freq = WL1273_BAND_JAPAN_LOW + 50 * f;476else477freq = WL1273_BAND_OTHER_LOW + 50 * f;478} else {479r = core->read(core, WL1273_CHANL_SET, &f);480if (r)481return r;482483freq = f * 10;484}485486return freq;487}488489/**490* wl1273_fm_upload_firmware_patch() - Upload the firmware.491* @radio: A pointer to the device struct.492*493* The firmware file consists of arrays of bytes where the first byte494* gives the array length. The first byte in the file gives the495* number of these arrays.496*/497static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)498{499struct wl1273_core *core = radio->core;500unsigned int packet_num;501const struct firmware *fw_p;502const char *fw_name = "radio-wl1273-fw.bin";503struct device *dev = radio->dev;504__u8 *ptr;505int r;506507dev_dbg(dev, "%s:\n", __func__);508509/*510* Uploading the firmware patch is not always necessary,511* so we only print an info message.512*/513if (request_firmware(&fw_p, fw_name, dev)) {514dev_info(dev, "%s - %s not found\n", __func__, fw_name);515516return 0;517}518519ptr = (__u8 *) fw_p->data;520packet_num = ptr[0];521dev_dbg(dev, "%s: packets: %d\n", __func__, packet_num);522523r = wl1273_fm_write_fw(core, ptr + 1, packet_num);524if (r) {525dev_err(dev, "FW upload error: %d\n", r);526goto out;527}528529/* ignore possible error here */530core->write(core, WL1273_RESET, 0);531532dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);533out:534release_firmware(fw_p);535return r;536}537538static int wl1273_fm_stop(struct wl1273_device *radio)539{540struct wl1273_core *core = radio->core;541542if (core->mode == WL1273_MODE_RX) {543int r = core->write(core, WL1273_POWER_SET,544WL1273_POWER_SET_OFF);545if (r)546dev_err(radio->dev, "%s: POWER_SET fails: %d\n",547__func__, r);548} else if (core->mode == WL1273_MODE_TX) {549int r = core->write(core, WL1273_PUPD_SET,550WL1273_PUPD_SET_OFF);551if (r)552dev_err(radio->dev,553"%s: PUPD_SET fails: %d\n", __func__, r);554}555556if (core->pdata->disable) {557core->pdata->disable();558dev_dbg(radio->dev, "Back to reset\n");559}560561return 0;562}563564static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)565{566struct wl1273_core *core = radio->core;567struct wl1273_fm_platform_data *pdata = core->pdata;568struct device *dev = radio->dev;569int r = -EINVAL;570571if (pdata->enable && core->mode == WL1273_MODE_OFF) {572dev_dbg(radio->dev, "Out of reset\n");573574pdata->enable();575msleep(250);576}577578if (new_mode == WL1273_MODE_RX) {579u16 val = WL1273_POWER_SET_FM;580581if (radio->rds_on)582val |= WL1273_POWER_SET_RDS;583584/* If this fails try again */585r = core->write(core, WL1273_POWER_SET, val);586if (r) {587msleep(100);588589r = core->write(core, WL1273_POWER_SET, val);590if (r) {591dev_err(dev, "%s: POWER_SET fails\n", __func__);592goto fail;593}594}595596/* rds buffer configuration */597radio->wr_index = 0;598radio->rd_index = 0;599600} else if (new_mode == WL1273_MODE_TX) {601/* If this fails try again once */602r = core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON);603if (r) {604msleep(100);605r = core->write(core, WL1273_PUPD_SET,606WL1273_PUPD_SET_ON);607if (r) {608dev_err(dev, "%s: PUPD_SET fails\n", __func__);609goto fail;610}611}612613if (radio->rds_on)614r = core->write(core, WL1273_RDS_DATA_ENB, 1);615else616r = core->write(core, WL1273_RDS_DATA_ENB, 0);617} else {618dev_warn(dev, "%s: Illegal mode.\n", __func__);619}620621if (core->mode == WL1273_MODE_OFF) {622r = wl1273_fm_upload_firmware_patch(radio);623if (r)624dev_warn(dev, "Firmware upload failed.\n");625626/*627* Sometimes the chip is in a wrong power state at this point.628* So we set the power once again.629*/630if (new_mode == WL1273_MODE_RX) {631u16 val = WL1273_POWER_SET_FM;632633if (radio->rds_on)634val |= WL1273_POWER_SET_RDS;635636r = core->write(core, WL1273_POWER_SET, val);637if (r) {638dev_err(dev, "%s: POWER_SET fails\n", __func__);639goto fail;640}641} else if (new_mode == WL1273_MODE_TX) {642r = core->write(core, WL1273_PUPD_SET,643WL1273_PUPD_SET_ON);644if (r) {645dev_err(dev, "%s: PUPD_SET fails\n", __func__);646goto fail;647}648}649}650651return 0;652fail:653if (pdata->disable)654pdata->disable();655656dev_dbg(dev, "%s: return: %d\n", __func__, r);657return r;658}659660static int wl1273_fm_suspend(struct wl1273_device *radio)661{662struct wl1273_core *core = radio->core;663int r = 0;664665/* Cannot go from OFF to SUSPENDED */666if (core->mode == WL1273_MODE_RX)667r = core->write(core, WL1273_POWER_SET,668WL1273_POWER_SET_RETENTION);669else if (core->mode == WL1273_MODE_TX)670r = core->write(core, WL1273_PUPD_SET,671WL1273_PUPD_SET_RETENTION);672else673r = -EINVAL;674675if (r) {676dev_err(radio->dev, "%s: POWER_SET fails: %d\n", __func__, r);677goto out;678}679680out:681return r;682}683684static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)685{686struct wl1273_core *core = radio->core;687struct device *dev = radio->dev;688int old_mode;689int r;690691dev_dbg(dev, "%s\n", __func__);692dev_dbg(dev, "Forbidden modes: 0x%02x\n", radio->forbidden);693694old_mode = core->mode;695if (mode & radio->forbidden) {696r = -EPERM;697goto out;698}699700switch (mode) {701case WL1273_MODE_RX:702case WL1273_MODE_TX:703r = wl1273_fm_start(radio, mode);704if (r) {705dev_err(dev, "%s: Cannot start.\n", __func__);706wl1273_fm_stop(radio);707goto out;708}709710core->mode = mode;711r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);712if (r) {713dev_err(dev, "INT_MASK_SET fails.\n");714goto out;715}716717/* remember previous settings */718if (mode == WL1273_MODE_RX) {719r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);720if (r) {721dev_err(dev, "set freq fails: %d.\n", r);722goto out;723}724725r = core->set_volume(core, core->volume);726if (r) {727dev_err(dev, "set volume fails: %d.\n", r);728goto out;729}730731dev_dbg(dev, "%s: Set vol: %d.\n", __func__,732core->volume);733} else {734r = wl1273_fm_set_tx_freq(radio, radio->tx_frequency);735if (r) {736dev_err(dev, "set freq fails: %d.\n", r);737goto out;738}739}740741dev_dbg(radio->dev, "%s: Set audio mode.\n", __func__);742743r = core->set_audio(core, core->audio_mode);744if (r)745dev_err(dev, "Cannot set audio mode.\n");746break;747748case WL1273_MODE_OFF:749r = wl1273_fm_stop(radio);750if (r)751dev_err(dev, "%s: Off fails: %d\n", __func__, r);752else753core->mode = WL1273_MODE_OFF;754755break;756757case WL1273_MODE_SUSPENDED:758r = wl1273_fm_suspend(radio);759if (r)760dev_err(dev, "%s: Suspend fails: %d\n", __func__, r);761else762core->mode = WL1273_MODE_SUSPENDED;763764break;765766default:767dev_err(dev, "%s: Unknown mode: %d\n", __func__, mode);768r = -EINVAL;769break;770}771out:772if (r)773core->mode = old_mode;774775return r;776}777778static int wl1273_fm_set_seek(struct wl1273_device *radio,779unsigned int wrap_around,780unsigned int seek_upward,781int level)782{783struct wl1273_core *core = radio->core;784int r = 0;785unsigned int dir = (seek_upward == 0) ? 0 : 1;786unsigned int f;787788f = radio->rx_frequency;789dev_dbg(radio->dev, "rx_frequency: %d\n", f);790791if (dir && f + radio->spacing <= radio->rangehigh)792r = wl1273_fm_set_rx_freq(radio, f + radio->spacing);793else if (dir && wrap_around)794r = wl1273_fm_set_rx_freq(radio, radio->rangelow);795else if (f - radio->spacing >= radio->rangelow)796r = wl1273_fm_set_rx_freq(radio, f - radio->spacing);797else if (wrap_around)798r = wl1273_fm_set_rx_freq(radio, radio->rangehigh);799800if (r)801goto out;802803if (level < SCHAR_MIN || level > SCHAR_MAX)804return -EINVAL;805806INIT_COMPLETION(radio->busy);807dev_dbg(radio->dev, "%s: BUSY\n", __func__);808809r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);810if (r)811goto out;812813dev_dbg(radio->dev, "%s\n", __func__);814815r = core->write(core, WL1273_SEARCH_LVL_SET, level);816if (r)817goto out;818819r = core->write(core, WL1273_SEARCH_DIR_SET, dir);820if (r)821goto out;822823r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);824if (r)825goto out;826827wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));828if (!(radio->irq_received & WL1273_BL_EVENT))829goto out;830831radio->irq_received &= ~WL1273_BL_EVENT;832833if (!wrap_around)834goto out;835836/* Wrap around */837dev_dbg(radio->dev, "Wrap around in HW seek.\n");838839if (seek_upward)840f = radio->rangelow;841else842f = radio->rangehigh;843844r = wl1273_fm_set_rx_freq(radio, f);845if (r)846goto out;847848INIT_COMPLETION(radio->busy);849dev_dbg(radio->dev, "%s: BUSY\n", __func__);850851r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);852if (r)853goto out;854855wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));856out:857dev_dbg(radio->dev, "%s: Err: %d\n", __func__, r);858return r;859}860861/**862* wl1273_fm_get_tx_ctune() - Get the TX tuning capacitor value.863* @radio: A pointer to the device struct.864*/865static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)866{867struct wl1273_core *core = radio->core;868struct device *dev = radio->dev;869u16 val;870int r;871872if (core->mode == WL1273_MODE_OFF ||873core->mode == WL1273_MODE_SUSPENDED)874return -EPERM;875876r = core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val);877if (r) {878dev_err(dev, "%s: read error: %d\n", __func__, r);879goto out;880}881882out:883return val;884}885886/**887* wl1273_fm_set_preemphasis() - Set the TX pre-emphasis value.888* @radio: A pointer to the device struct.889* @preemphasis: The new pre-amphasis value.890*891* Possible pre-emphasis values are: V4L2_PREEMPHASIS_DISABLED,892* V4L2_PREEMPHASIS_50_uS and V4L2_PREEMPHASIS_75_uS.893*/894static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,895unsigned int preemphasis)896{897struct wl1273_core *core = radio->core;898int r;899u16 em;900901if (core->mode == WL1273_MODE_OFF ||902core->mode == WL1273_MODE_SUSPENDED)903return -EPERM;904905mutex_lock(&core->lock);906907switch (preemphasis) {908case V4L2_PREEMPHASIS_DISABLED:909em = 1;910break;911case V4L2_PREEMPHASIS_50_uS:912em = 0;913break;914case V4L2_PREEMPHASIS_75_uS:915em = 2;916break;917default:918r = -EINVAL;919goto out;920}921922r = core->write(core, WL1273_PREMPH_SET, em);923if (r)924goto out;925926radio->preemphasis = preemphasis;927928out:929mutex_unlock(&core->lock);930return r;931}932933static int wl1273_fm_rds_on(struct wl1273_device *radio)934{935struct wl1273_core *core = radio->core;936int r;937938dev_dbg(radio->dev, "%s\n", __func__);939if (radio->rds_on)940return 0;941942r = core->write(core, WL1273_POWER_SET,943WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);944if (r)945goto out;946947r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);948if (r)949dev_err(radio->dev, "set freq fails: %d.\n", r);950out:951return r;952}953954static int wl1273_fm_rds_off(struct wl1273_device *radio)955{956struct wl1273_core *core = radio->core;957int r;958959if (!radio->rds_on)960return 0;961962radio->irq_flags &= ~WL1273_RDS_EVENT;963964r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);965if (r)966goto out;967968/* Service pending read */969wake_up_interruptible(&radio->read_queue);970971dev_dbg(radio->dev, "%s\n", __func__);972973r = core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);974if (r)975goto out;976977r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);978if (r)979dev_err(radio->dev, "set freq fails: %d.\n", r);980out:981dev_dbg(radio->dev, "%s: exiting...\n", __func__);982983return r;984}985986static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)987{988int r = 0;989struct wl1273_core *core = radio->core;990991if (core->mode == WL1273_MODE_OFF ||992core->mode == WL1273_MODE_SUSPENDED)993return -EPERM;994995if (new_mode == WL1273_RDS_RESET) {996r = core->write(core, WL1273_RDS_CNTRL_SET, 1);997return r;998}9991000if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {1001r = core->write(core, WL1273_RDS_DATA_ENB, 0);1002} else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {1003r = core->write(core, WL1273_RDS_DATA_ENB, 1);1004} else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {1005r = wl1273_fm_rds_off(radio);1006} else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {1007r = wl1273_fm_rds_on(radio);1008} else {1009dev_err(radio->dev, "%s: Unknown mode: %d\n",1010__func__, new_mode);1011r = -EINVAL;1012}10131014if (!r)1015radio->rds_on = (new_mode == WL1273_RDS_ON) ? true : false;10161017return r;1018}10191020static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,1021size_t count, loff_t *ppos)1022{1023struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1024struct wl1273_core *core = radio->core;1025u16 val;1026int r;10271028dev_dbg(radio->dev, "%s\n", __func__);10291030if (core->mode != WL1273_MODE_TX)1031return count;10321033if (radio->rds_users == 0) {1034dev_warn(radio->dev, "%s: RDS not on.\n", __func__);1035return 0;1036}10371038if (mutex_lock_interruptible(&core->lock))1039return -EINTR;1040/*1041* Multiple processes can open the device, but only1042* one gets to write to it.1043*/1044if (radio->owner && radio->owner != file) {1045r = -EBUSY;1046goto out;1047}1048radio->owner = file;10491050/* Manual Mode */1051if (count > 255)1052val = 255;1053else1054val = count;10551056core->write(core, WL1273_RDS_CONFIG_DATA_SET, val);10571058if (copy_from_user(radio->write_buf + 1, buf, val)) {1059r = -EFAULT;1060goto out;1061}10621063dev_dbg(radio->dev, "Count: %d\n", val);1064dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);10651066radio->write_buf[0] = WL1273_RDS_DATA_SET;1067core->write_data(core, radio->write_buf, val + 1);10681069r = val;1070out:1071mutex_unlock(&core->lock);10721073return r;1074}10751076static unsigned int wl1273_fm_fops_poll(struct file *file,1077struct poll_table_struct *pts)1078{1079struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1080struct wl1273_core *core = radio->core;10811082if (radio->owner && radio->owner != file)1083return -EBUSY;10841085radio->owner = file;10861087if (core->mode == WL1273_MODE_RX) {1088poll_wait(file, &radio->read_queue, pts);10891090if (radio->rd_index != radio->wr_index)1091return POLLIN | POLLRDNORM;10921093} else if (core->mode == WL1273_MODE_TX) {1094return POLLOUT | POLLWRNORM;1095}10961097return 0;1098}10991100static int wl1273_fm_fops_open(struct file *file)1101{1102struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1103struct wl1273_core *core = radio->core;1104int r = 0;11051106dev_dbg(radio->dev, "%s\n", __func__);11071108if (core->mode == WL1273_MODE_RX && radio->rds_on &&1109!radio->rds_users) {1110dev_dbg(radio->dev, "%s: Mode: %d\n", __func__, core->mode);11111112if (mutex_lock_interruptible(&core->lock))1113return -EINTR;11141115radio->irq_flags |= WL1273_RDS_EVENT;11161117r = core->write(core, WL1273_INT_MASK_SET,1118radio->irq_flags);1119if (r) {1120mutex_unlock(&core->lock);1121goto out;1122}11231124radio->rds_users++;11251126mutex_unlock(&core->lock);1127}1128out:1129return r;1130}11311132static int wl1273_fm_fops_release(struct file *file)1133{1134struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1135struct wl1273_core *core = radio->core;1136int r = 0;11371138dev_dbg(radio->dev, "%s\n", __func__);11391140if (radio->rds_users > 0) {1141radio->rds_users--;1142if (radio->rds_users == 0) {1143if (mutex_lock_interruptible(&core->lock))1144return -EINTR;11451146radio->irq_flags &= ~WL1273_RDS_EVENT;11471148if (core->mode == WL1273_MODE_RX) {1149r = core->write(core,1150WL1273_INT_MASK_SET,1151radio->irq_flags);1152if (r) {1153mutex_unlock(&core->lock);1154goto out;1155}1156}1157mutex_unlock(&core->lock);1158}1159}11601161if (file == radio->owner)1162radio->owner = NULL;1163out:1164return r;1165}11661167static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,1168size_t count, loff_t *ppos)1169{1170int r = 0;1171struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1172struct wl1273_core *core = radio->core;1173unsigned int block_count = 0;1174u16 val;11751176dev_dbg(radio->dev, "%s\n", __func__);11771178if (core->mode != WL1273_MODE_RX)1179return 0;11801181if (radio->rds_users == 0) {1182dev_warn(radio->dev, "%s: RDS not on.\n", __func__);1183return 0;1184}11851186if (mutex_lock_interruptible(&core->lock))1187return -EINTR;11881189/*1190* Multiple processes can open the device, but only1191* one at a time gets read access.1192*/1193if (radio->owner && radio->owner != file) {1194r = -EBUSY;1195goto out;1196}1197radio->owner = file;11981199r = core->read(core, WL1273_RDS_SYNC_GET, &val);1200if (r) {1201dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);1202goto out;1203} else if (val == 0) {1204dev_info(radio->dev, "RDS_SYNC: Not synchronized\n");1205r = -ENODATA;1206goto out;1207}12081209/* block if no new data available */1210while (radio->wr_index == radio->rd_index) {1211if (file->f_flags & O_NONBLOCK) {1212r = -EWOULDBLOCK;1213goto out;1214}12151216dev_dbg(radio->dev, "%s: Wait for RDS data.\n", __func__);1217if (wait_event_interruptible(radio->read_queue,1218radio->wr_index !=1219radio->rd_index) < 0) {1220r = -EINTR;1221goto out;1222}1223}12241225/* calculate block count from byte count */1226count /= RDS_BLOCK_SIZE;12271228/* copy RDS blocks from the internal buffer and to user buffer */1229while (block_count < count) {1230if (radio->rd_index == radio->wr_index)1231break;12321233/* always transfer complete RDS blocks */1234if (copy_to_user(buf, &radio->buffer[radio->rd_index],1235RDS_BLOCK_SIZE))1236break;12371238/* increment and wrap the read pointer */1239radio->rd_index += RDS_BLOCK_SIZE;1240if (radio->rd_index >= radio->buf_size)1241radio->rd_index = 0;12421243/* increment counters */1244block_count++;1245buf += RDS_BLOCK_SIZE;1246r += RDS_BLOCK_SIZE;1247}12481249out:1250dev_dbg(radio->dev, "%s: exit\n", __func__);1251mutex_unlock(&core->lock);12521253return r;1254}12551256static const struct v4l2_file_operations wl1273_fops = {1257.owner = THIS_MODULE,1258.read = wl1273_fm_fops_read,1259.write = wl1273_fm_fops_write,1260.poll = wl1273_fm_fops_poll,1261.unlocked_ioctl = video_ioctl2,1262.open = wl1273_fm_fops_open,1263.release = wl1273_fm_fops_release,1264};12651266static int wl1273_fm_vidioc_querycap(struct file *file, void *priv,1267struct v4l2_capability *capability)1268{1269struct wl1273_device *radio = video_get_drvdata(video_devdata(file));12701271dev_dbg(radio->dev, "%s\n", __func__);12721273strlcpy(capability->driver, WL1273_FM_DRIVER_NAME,1274sizeof(capability->driver));1275strlcpy(capability->card, "Texas Instruments Wl1273 FM Radio",1276sizeof(capability->card));1277strlcpy(capability->bus_info, radio->bus_type,1278sizeof(capability->bus_info));12791280capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |1281V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_AUDIO |1282V4L2_CAP_RDS_CAPTURE | V4L2_CAP_MODULATOR |1283V4L2_CAP_RDS_OUTPUT;12841285return 0;1286}12871288static int wl1273_fm_vidioc_g_input(struct file *file, void *priv,1289unsigned int *i)1290{1291struct wl1273_device *radio = video_get_drvdata(video_devdata(file));12921293dev_dbg(radio->dev, "%s\n", __func__);12941295*i = 0;12961297return 0;1298}12991300static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,1301unsigned int i)1302{1303struct wl1273_device *radio = video_get_drvdata(video_devdata(file));13041305dev_dbg(radio->dev, "%s\n", __func__);13061307if (i != 0)1308return -EINVAL;13091310return 0;1311}13121313/**1314* wl1273_fm_set_tx_power() - Set the transmission power value.1315* @core: A pointer to the device struct.1316* @power: The new power value.1317*/1318static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)1319{1320struct wl1273_core *core = radio->core;1321int r;13221323if (core->mode == WL1273_MODE_OFF ||1324core->mode == WL1273_MODE_SUSPENDED)1325return -EPERM;13261327mutex_lock(&core->lock);13281329/* Convert the dBuV value to chip presentation */1330r = core->write(core, WL1273_POWER_LEV_SET, 122 - power);1331if (r)1332goto out;13331334radio->tx_power = power;13351336out:1337mutex_unlock(&core->lock);1338return r;1339}13401341#define WL1273_SPACING_50kHz 11342#define WL1273_SPACING_100kHz 21343#define WL1273_SPACING_200kHz 413441345static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,1346unsigned int spacing)1347{1348struct wl1273_core *core = radio->core;1349int r;13501351if (spacing == 0) {1352r = core->write(core, WL1273_SCAN_SPACING_SET,1353WL1273_SPACING_100kHz);1354radio->spacing = 100;1355} else if (spacing - 50000 < 25000) {1356r = core->write(core, WL1273_SCAN_SPACING_SET,1357WL1273_SPACING_50kHz);1358radio->spacing = 50;1359} else if (spacing - 100000 < 50000) {1360r = core->write(core, WL1273_SCAN_SPACING_SET,1361WL1273_SPACING_100kHz);1362radio->spacing = 100;1363} else {1364r = core->write(core, WL1273_SCAN_SPACING_SET,1365WL1273_SPACING_200kHz);1366radio->spacing = 200;1367}13681369return r;1370}13711372static int wl1273_fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl)1373{1374struct wl1273_device *radio = ctrl->priv;1375struct wl1273_core *core = radio->core;13761377dev_dbg(radio->dev, "%s\n", __func__);13781379if (mutex_lock_interruptible(&core->lock))1380return -EINTR;13811382switch (ctrl->id) {1383case V4L2_CID_TUNE_ANTENNA_CAPACITOR:1384ctrl->cur.val = wl1273_fm_get_tx_ctune(radio);1385break;13861387default:1388dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n",1389__func__, ctrl->id);1390break;1391}13921393mutex_unlock(&core->lock);13941395return 0;1396}13971398#define WL1273_MUTE_SOFT_ENABLE (1 << 0)1399#define WL1273_MUTE_AC (1 << 1)1400#define WL1273_MUTE_HARD_LEFT (1 << 2)1401#define WL1273_MUTE_HARD_RIGHT (1 << 3)1402#define WL1273_MUTE_SOFT_FORCE (1 << 4)14031404static inline struct wl1273_device *to_radio(struct v4l2_ctrl *ctrl)1405{1406return container_of(ctrl->handler, struct wl1273_device, ctrl_handler);1407}14081409static int wl1273_fm_vidioc_s_ctrl(struct v4l2_ctrl *ctrl)1410{1411struct wl1273_device *radio = to_radio(ctrl);1412struct wl1273_core *core = radio->core;1413int r = 0;14141415dev_dbg(radio->dev, "%s\n", __func__);14161417switch (ctrl->id) {1418case V4L2_CID_AUDIO_MUTE:1419if (mutex_lock_interruptible(&core->lock))1420return -EINTR;14211422if (core->mode == WL1273_MODE_RX && ctrl->val)1423r = core->write(core,1424WL1273_MUTE_STATUS_SET,1425WL1273_MUTE_HARD_LEFT |1426WL1273_MUTE_HARD_RIGHT);1427else if (core->mode == WL1273_MODE_RX)1428r = core->write(core,1429WL1273_MUTE_STATUS_SET, 0x0);1430else if (core->mode == WL1273_MODE_TX && ctrl->val)1431r = core->write(core, WL1273_MUTE, 1);1432else if (core->mode == WL1273_MODE_TX)1433r = core->write(core, WL1273_MUTE, 0);14341435mutex_unlock(&core->lock);1436break;14371438case V4L2_CID_AUDIO_VOLUME:1439if (ctrl->val == 0)1440r = wl1273_fm_set_mode(radio, WL1273_MODE_OFF);1441else1442r = core->set_volume(core, core->volume);1443break;14441445case V4L2_CID_TUNE_PREEMPHASIS:1446r = wl1273_fm_set_preemphasis(radio, ctrl->val);1447break;14481449case V4L2_CID_TUNE_POWER_LEVEL:1450r = wl1273_fm_set_tx_power(radio, ctrl->val);1451break;14521453default:1454dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n",1455__func__, ctrl->id);1456break;1457}14581459dev_dbg(radio->dev, "%s\n", __func__);1460return r;1461}14621463static int wl1273_fm_vidioc_g_audio(struct file *file, void *priv,1464struct v4l2_audio *audio)1465{1466struct wl1273_device *radio = video_get_drvdata(video_devdata(file));14671468dev_dbg(radio->dev, "%s\n", __func__);14691470if (audio->index > 1)1471return -EINVAL;14721473strlcpy(audio->name, "Radio", sizeof(audio->name));1474audio->capability = V4L2_AUDCAP_STEREO;14751476return 0;1477}14781479static int wl1273_fm_vidioc_s_audio(struct file *file, void *priv,1480struct v4l2_audio *audio)1481{1482struct wl1273_device *radio = video_get_drvdata(video_devdata(file));14831484dev_dbg(radio->dev, "%s\n", __func__);14851486if (audio->index != 0)1487return -EINVAL;14881489return 0;1490}14911492#define WL1273_RDS_NOT_SYNCHRONIZED 01493#define WL1273_RDS_SYNCHRONIZED 114941495static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,1496struct v4l2_tuner *tuner)1497{1498struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1499struct wl1273_core *core = radio->core;1500u16 val;1501int r;15021503dev_dbg(radio->dev, "%s\n", __func__);15041505if (tuner->index > 0)1506return -EINVAL;15071508strlcpy(tuner->name, WL1273_FM_DRIVER_NAME, sizeof(tuner->name));1509tuner->type = V4L2_TUNER_RADIO;15101511tuner->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);1512tuner->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);15131514tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |1515V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO;15161517if (radio->stereo)1518tuner->audmode = V4L2_TUNER_MODE_STEREO;1519else1520tuner->audmode = V4L2_TUNER_MODE_MONO;15211522if (core->mode != WL1273_MODE_RX)1523return 0;15241525if (mutex_lock_interruptible(&core->lock))1526return -EINTR;15271528r = core->read(core, WL1273_STEREO_GET, &val);1529if (r)1530goto out;15311532if (val == 1)1533tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;1534else1535tuner->rxsubchans = V4L2_TUNER_SUB_MONO;15361537r = core->read(core, WL1273_RSSI_LVL_GET, &val);1538if (r)1539goto out;15401541tuner->signal = (s16) val;1542dev_dbg(radio->dev, "Signal: %d\n", tuner->signal);15431544tuner->afc = 0;15451546r = core->read(core, WL1273_RDS_SYNC_GET, &val);1547if (r)1548goto out;15491550if (val == WL1273_RDS_SYNCHRONIZED)1551tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;1552out:1553mutex_unlock(&core->lock);15541555return r;1556}15571558static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,1559struct v4l2_tuner *tuner)1560{1561struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1562struct wl1273_core *core = radio->core;1563int r = 0;15641565dev_dbg(radio->dev, "%s\n", __func__);1566dev_dbg(radio->dev, "tuner->index: %d\n", tuner->index);1567dev_dbg(radio->dev, "tuner->name: %s\n", tuner->name);1568dev_dbg(radio->dev, "tuner->capability: 0x%04x\n", tuner->capability);1569dev_dbg(radio->dev, "tuner->rxsubchans: 0x%04x\n", tuner->rxsubchans);1570dev_dbg(radio->dev, "tuner->rangelow: %d\n", tuner->rangelow);1571dev_dbg(radio->dev, "tuner->rangehigh: %d\n", tuner->rangehigh);15721573if (tuner->index > 0)1574return -EINVAL;15751576if (mutex_lock_interruptible(&core->lock))1577return -EINTR;15781579r = wl1273_fm_set_mode(radio, WL1273_MODE_RX);1580if (r)1581goto out;15821583if (tuner->rxsubchans & V4L2_TUNER_SUB_RDS)1584r = wl1273_fm_set_rds(radio, WL1273_RDS_ON);1585else1586r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);15871588if (r)1589dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);15901591if (tuner->audmode == V4L2_TUNER_MODE_MONO) {1592r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);1593if (r < 0) {1594dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",1595__func__, r);1596goto out;1597}1598radio->stereo = false;1599} else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {1600r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);1601if (r < 0) {1602dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",1603__func__, r);1604goto out;1605}1606radio->stereo = true;1607} else {1608dev_err(radio->dev, "%s: tuner->audmode: %d\n",1609__func__, tuner->audmode);1610r = -EINVAL;1611goto out;1612}16131614out:1615mutex_unlock(&core->lock);16161617return r;1618}16191620static int wl1273_fm_vidioc_g_frequency(struct file *file, void *priv,1621struct v4l2_frequency *freq)1622{1623struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1624struct wl1273_core *core = radio->core;16251626dev_dbg(radio->dev, "%s\n", __func__);16271628if (mutex_lock_interruptible(&core->lock))1629return -EINTR;16301631freq->type = V4L2_TUNER_RADIO;1632freq->frequency = WL1273_FREQ(wl1273_fm_get_freq(radio));16331634mutex_unlock(&core->lock);16351636return 0;1637}16381639static int wl1273_fm_vidioc_s_frequency(struct file *file, void *priv,1640struct v4l2_frequency *freq)1641{1642struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1643struct wl1273_core *core = radio->core;1644int r;16451646dev_dbg(radio->dev, "%s: %d\n", __func__, freq->frequency);16471648if (freq->type != V4L2_TUNER_RADIO) {1649dev_dbg(radio->dev,1650"freq->type != V4L2_TUNER_RADIO: %d\n", freq->type);1651return -EINVAL;1652}16531654if (mutex_lock_interruptible(&core->lock))1655return -EINTR;16561657if (core->mode == WL1273_MODE_RX) {1658dev_dbg(radio->dev, "freq: %d\n", freq->frequency);16591660r = wl1273_fm_set_rx_freq(radio,1661WL1273_INV_FREQ(freq->frequency));1662if (r)1663dev_warn(radio->dev, WL1273_FM_DRIVER_NAME1664": set frequency failed with %d\n", r);1665} else {1666r = wl1273_fm_set_tx_freq(radio,1667WL1273_INV_FREQ(freq->frequency));1668if (r)1669dev_warn(radio->dev, WL1273_FM_DRIVER_NAME1670": set frequency failed with %d\n", r);1671}16721673mutex_unlock(&core->lock);16741675dev_dbg(radio->dev, "wl1273_vidioc_s_frequency: DONE\n");1676return r;1677}16781679#define WL1273_DEFAULT_SEEK_LEVEL 716801681static int wl1273_fm_vidioc_s_hw_freq_seek(struct file *file, void *priv,1682struct v4l2_hw_freq_seek *seek)1683{1684struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1685struct wl1273_core *core = radio->core;1686int r;16871688dev_dbg(radio->dev, "%s\n", __func__);16891690if (seek->tuner != 0 || seek->type != V4L2_TUNER_RADIO)1691return -EINVAL;16921693if (mutex_lock_interruptible(&core->lock))1694return -EINTR;16951696r = wl1273_fm_set_mode(radio, WL1273_MODE_RX);1697if (r)1698goto out;16991700r = wl1273_fm_tx_set_spacing(radio, seek->spacing);1701if (r)1702dev_warn(radio->dev, "HW seek failed: %d\n", r);17031704r = wl1273_fm_set_seek(radio, seek->wrap_around, seek->seek_upward,1705WL1273_DEFAULT_SEEK_LEVEL);1706if (r)1707dev_warn(radio->dev, "HW seek failed: %d\n", r);17081709out:1710mutex_unlock(&core->lock);1711return r;1712}17131714static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,1715struct v4l2_modulator *modulator)1716{1717struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1718struct wl1273_core *core = radio->core;1719int r = 0;17201721dev_dbg(radio->dev, "%s\n", __func__);17221723if (modulator->index > 0)1724return -EINVAL;17251726if (mutex_lock_interruptible(&core->lock))1727return -EINTR;17281729r = wl1273_fm_set_mode(radio, WL1273_MODE_TX);1730if (r)1731goto out;17321733if (modulator->txsubchans & V4L2_TUNER_SUB_RDS)1734r = wl1273_fm_set_rds(radio, WL1273_RDS_ON);1735else1736r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);17371738if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)1739r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);1740else1741r = core->write(core, WL1273_MONO_SET,1742WL1273_RX_STEREO);1743if (r < 0)1744dev_warn(radio->dev, WL1273_FM_DRIVER_NAME1745"MONO_SET fails: %d\n", r);1746out:1747mutex_unlock(&core->lock);17481749return r;1750}17511752static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,1753struct v4l2_modulator *modulator)1754{1755struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1756struct wl1273_core *core = radio->core;1757u16 val;1758int r;17591760dev_dbg(radio->dev, "%s\n", __func__);17611762strlcpy(modulator->name, WL1273_FM_DRIVER_NAME,1763sizeof(modulator->name));17641765modulator->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);1766modulator->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);17671768modulator->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |1769V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO;17701771if (core->mode != WL1273_MODE_TX)1772return 0;17731774if (mutex_lock_interruptible(&core->lock))1775return -EINTR;17761777r = core->read(core, WL1273_MONO_SET, &val);1778if (r)1779goto out;17801781if (val == WL1273_TX_STEREO)1782modulator->txsubchans = V4L2_TUNER_SUB_STEREO;1783else1784modulator->txsubchans = V4L2_TUNER_SUB_MONO;17851786if (radio->rds_on)1787modulator->txsubchans |= V4L2_TUNER_SUB_RDS;1788out:1789mutex_unlock(&core->lock);17901791return 0;1792}17931794static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)1795{1796struct wl1273_device *radio = video_get_drvdata(video_devdata(file));1797struct wl1273_core *core = radio->core;1798struct device *dev = radio->dev;1799u16 val;1800int r;18011802dev_info(dev, DRIVER_DESC);18031804if (core->mode == WL1273_MODE_OFF) {1805dev_info(dev, "Mode: Off\n");1806return 0;1807}18081809if (core->mode == WL1273_MODE_SUSPENDED) {1810dev_info(dev, "Mode: Suspended\n");1811return 0;1812}18131814r = core->read(core, WL1273_ASIC_ID_GET, &val);1815if (r)1816dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);1817else1818dev_info(dev, "ASIC_ID: 0x%04x\n", val);18191820r = core->read(core, WL1273_ASIC_VER_GET, &val);1821if (r)1822dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);1823else1824dev_info(dev, "ASIC Version: 0x%04x\n", val);18251826r = core->read(core, WL1273_FIRM_VER_GET, &val);1827if (r)1828dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);1829else1830dev_info(dev, "FW version: %d(0x%04x)\n", val, val);18311832r = core->read(core, WL1273_BAND_SET, &val);1833if (r)1834dev_err(dev, "%s: Get BAND fails.\n", __func__);1835else1836dev_info(dev, "BAND: %d\n", val);18371838if (core->mode == WL1273_MODE_TX) {1839r = core->read(core, WL1273_PUPD_SET, &val);1840if (r)1841dev_err(dev, "%s: Get PUPD fails.\n", __func__);1842else1843dev_info(dev, "PUPD: 0x%04x\n", val);18441845r = core->read(core, WL1273_CHANL_SET, &val);1846if (r)1847dev_err(dev, "%s: Get CHANL fails.\n", __func__);1848else1849dev_info(dev, "Tx frequency: %dkHz\n", val*10);1850} else if (core->mode == WL1273_MODE_RX) {1851int bf = radio->rangelow;18521853r = core->read(core, WL1273_FREQ_SET, &val);1854if (r)1855dev_err(dev, "%s: Get FREQ fails.\n", __func__);1856else1857dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);18581859r = core->read(core, WL1273_MOST_MODE_SET, &val);1860if (r)1861dev_err(dev, "%s: Get MOST_MODE fails.\n",1862__func__);1863else if (val == 0)1864dev_info(dev, "MOST_MODE: Stereo according to blend\n");1865else if (val == 1)1866dev_info(dev, "MOST_MODE: Force mono output\n");1867else1868dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);18691870r = core->read(core, WL1273_MOST_BLEND_SET, &val);1871if (r)1872dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);1873else if (val == 0)1874dev_info(dev,1875"MOST_BLEND: Switched blend & hysteresis.\n");1876else if (val == 1)1877dev_info(dev, "MOST_BLEND: Soft blend.\n");1878else1879dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);18801881r = core->read(core, WL1273_STEREO_GET, &val);1882if (r)1883dev_err(dev, "%s: Get STEREO fails.\n", __func__);1884else if (val == 0)1885dev_info(dev, "STEREO: Not detected\n");1886else if (val == 1)1887dev_info(dev, "STEREO: Detected\n");1888else1889dev_info(dev, "STEREO: Unexpected value: %d\n", val);18901891r = core->read(core, WL1273_RSSI_LVL_GET, &val);1892if (r)1893dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);1894else1895dev_info(dev, "RX signal strength: %d\n", (s16) val);18961897r = core->read(core, WL1273_POWER_SET, &val);1898if (r)1899dev_err(dev, "%s: Get POWER fails.\n", __func__);1900else1901dev_info(dev, "POWER: 0x%04x\n", val);19021903r = core->read(core, WL1273_INT_MASK_SET, &val);1904if (r)1905dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);1906else1907dev_info(dev, "INT_MASK: 0x%04x\n", val);19081909r = core->read(core, WL1273_RDS_SYNC_GET, &val);1910if (r)1911dev_err(dev, "%s: Get RDS_SYNC fails.\n",1912__func__);1913else if (val == 0)1914dev_info(dev, "RDS_SYNC: Not synchronized\n");19151916else if (val == 1)1917dev_info(dev, "RDS_SYNC: Synchronized\n");1918else1919dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);19201921r = core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val);1922if (r)1923dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",1924__func__);1925else1926dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);19271928r = core->read(core, WL1273_VOLUME_SET, &val);1929if (r)1930dev_err(dev, "%s: Get VOLUME fails.\n", __func__);1931else1932dev_info(dev, "VOLUME: 0x%04x\n", val);1933}19341935return 0;1936}19371938static void wl1273_vdev_release(struct video_device *dev)1939{1940}19411942static const struct v4l2_ctrl_ops wl1273_ctrl_ops = {1943.s_ctrl = wl1273_fm_vidioc_s_ctrl,1944.g_volatile_ctrl = wl1273_fm_g_volatile_ctrl,1945};19461947static const struct v4l2_ioctl_ops wl1273_ioctl_ops = {1948.vidioc_querycap = wl1273_fm_vidioc_querycap,1949.vidioc_g_input = wl1273_fm_vidioc_g_input,1950.vidioc_s_input = wl1273_fm_vidioc_s_input,1951.vidioc_g_audio = wl1273_fm_vidioc_g_audio,1952.vidioc_s_audio = wl1273_fm_vidioc_s_audio,1953.vidioc_g_tuner = wl1273_fm_vidioc_g_tuner,1954.vidioc_s_tuner = wl1273_fm_vidioc_s_tuner,1955.vidioc_g_frequency = wl1273_fm_vidioc_g_frequency,1956.vidioc_s_frequency = wl1273_fm_vidioc_s_frequency,1957.vidioc_s_hw_freq_seek = wl1273_fm_vidioc_s_hw_freq_seek,1958.vidioc_g_modulator = wl1273_fm_vidioc_g_modulator,1959.vidioc_s_modulator = wl1273_fm_vidioc_s_modulator,1960.vidioc_log_status = wl1273_fm_vidioc_log_status,1961};19621963static struct video_device wl1273_viddev_template = {1964.fops = &wl1273_fops,1965.ioctl_ops = &wl1273_ioctl_ops,1966.name = WL1273_FM_DRIVER_NAME,1967.release = wl1273_vdev_release,1968};19691970static int wl1273_fm_radio_remove(struct platform_device *pdev)1971{1972struct wl1273_device *radio = platform_get_drvdata(pdev);1973struct wl1273_core *core = radio->core;19741975dev_info(&pdev->dev, "%s.\n", __func__);19761977free_irq(core->client->irq, radio);1978core->pdata->free_resources();19791980v4l2_ctrl_handler_free(&radio->ctrl_handler);1981video_unregister_device(&radio->videodev);1982v4l2_device_unregister(&radio->v4l2dev);1983kfree(radio->buffer);1984kfree(radio->write_buf);1985kfree(radio);19861987return 0;1988}19891990static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)1991{1992struct wl1273_core **core = pdev->dev.platform_data;1993struct wl1273_device *radio;1994struct v4l2_ctrl *ctrl;1995int r = 0;19961997pr_debug("%s\n", __func__);19981999if (!core) {2000dev_err(&pdev->dev, "No platform data.\n");2001r = -EINVAL;2002goto pdata_err;2003}20042005radio = kzalloc(sizeof(*radio), GFP_KERNEL);2006if (!radio) {2007r = -ENOMEM;2008goto pdata_err;2009}20102011/* RDS buffer allocation */2012radio->buf_size = rds_buf * RDS_BLOCK_SIZE;2013radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);2014if (!radio->buffer) {2015pr_err("Cannot allocate memory for RDS buffer.\n");2016r = -ENOMEM;2017goto err_kmalloc;2018}20192020radio->core = *core;2021radio->irq_flags = WL1273_IRQ_MASK;2022radio->dev = &radio->core->client->dev;2023radio->rds_on = false;2024radio->core->mode = WL1273_MODE_OFF;2025radio->tx_power = 118;2026radio->core->audio_mode = WL1273_AUDIO_ANALOG;2027radio->band = WL1273_BAND_OTHER;2028radio->core->i2s_mode = WL1273_I2S_DEF_MODE;2029radio->core->channel_number = 2;2030radio->core->volume = WL1273_DEFAULT_VOLUME;2031radio->rx_frequency = WL1273_BAND_OTHER_LOW;2032radio->tx_frequency = WL1273_BAND_OTHER_HIGH;2033radio->rangelow = WL1273_BAND_OTHER_LOW;2034radio->rangehigh = WL1273_BAND_OTHER_HIGH;2035radio->stereo = true;2036radio->bus_type = "I2C";20372038if (radio->core->pdata->request_resources) {2039r = radio->core->pdata->request_resources(radio->core->client);2040if (r) {2041dev_err(radio->dev, WL1273_FM_DRIVER_NAME2042": Cannot get platform data\n");2043goto err_resources;2044}20452046dev_dbg(radio->dev, "irq: %d\n", radio->core->client->irq);20472048r = request_threaded_irq(radio->core->client->irq, NULL,2049wl1273_fm_irq_thread_handler,2050IRQF_ONESHOT | IRQF_TRIGGER_FALLING,2051"wl1273-fm", radio);2052if (r < 0) {2053dev_err(radio->dev, WL1273_FM_DRIVER_NAME2054": Unable to register IRQ handler: %d\n", r);2055goto err_request_irq;2056}2057} else {2058dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ"2059" not configured");2060r = -EINVAL;2061goto err_resources;2062}20632064init_completion(&radio->busy);2065init_waitqueue_head(&radio->read_queue);20662067radio->write_buf = kmalloc(256, GFP_KERNEL);2068if (!radio->write_buf) {2069r = -ENOMEM;2070goto write_buf_err;2071}20722073radio->dev = &pdev->dev;2074radio->v4l2dev.ctrl_handler = &radio->ctrl_handler;2075radio->rds_users = 0;20762077r = v4l2_device_register(&pdev->dev, &radio->v4l2dev);2078if (r) {2079dev_err(&pdev->dev, "Cannot register v4l2_device.\n");2080goto device_register_err;2081}20822083/* V4L2 configuration */2084memcpy(&radio->videodev, &wl1273_viddev_template,2085sizeof(wl1273_viddev_template));20862087radio->videodev.v4l2_dev = &radio->v4l2dev;20882089v4l2_ctrl_handler_init(&radio->ctrl_handler, 6);20902091/* add in ascending ID order */2092v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,2093V4L2_CID_AUDIO_VOLUME, 0, WL1273_MAX_VOLUME, 1,2094WL1273_DEFAULT_VOLUME);20952096v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,2097V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);20982099v4l2_ctrl_new_std_menu(&radio->ctrl_handler, &wl1273_ctrl_ops,2100V4L2_CID_TUNE_PREEMPHASIS,2101V4L2_PREEMPHASIS_75_uS, 0x03,2102V4L2_PREEMPHASIS_50_uS);21032104v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,2105V4L2_CID_TUNE_POWER_LEVEL, 91, 122, 1, 118);21062107ctrl = v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,2108V4L2_CID_TUNE_ANTENNA_CAPACITOR,21090, 255, 1, 255);2110if (ctrl)2111ctrl->is_volatile = 1;21122113if (radio->ctrl_handler.error) {2114r = radio->ctrl_handler.error;2115dev_err(&pdev->dev, "Ctrl handler error: %d\n", r);2116goto handler_init_err;2117}21182119video_set_drvdata(&radio->videodev, radio);2120platform_set_drvdata(pdev, radio);21212122/* register video device */2123r = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);2124if (r) {2125dev_err(&pdev->dev, WL1273_FM_DRIVER_NAME2126": Could not register video device\n");2127goto handler_init_err;2128}21292130return 0;21312132handler_init_err:2133v4l2_ctrl_handler_free(&radio->ctrl_handler);2134v4l2_device_unregister(&radio->v4l2dev);2135device_register_err:2136kfree(radio->write_buf);2137write_buf_err:2138free_irq(radio->core->client->irq, radio);2139err_request_irq:2140radio->core->pdata->free_resources();2141err_resources:2142kfree(radio->buffer);2143err_kmalloc:2144kfree(radio);2145pdata_err:2146return r;2147}21482149MODULE_ALIAS("platform:wl1273_fm_radio");21502151static struct platform_driver wl1273_fm_radio_driver = {2152.probe = wl1273_fm_radio_probe,2153.remove = __devexit_p(wl1273_fm_radio_remove),2154.driver = {2155.name = "wl1273_fm_radio",2156.owner = THIS_MODULE,2157},2158};21592160static int __init wl1273_fm_module_init(void)2161{2162pr_info("%s\n", __func__);2163return platform_driver_register(&wl1273_fm_radio_driver);2164}2165module_init(wl1273_fm_module_init);21662167static void __exit wl1273_fm_module_exit(void)2168{2169platform_driver_unregister(&wl1273_fm_radio_driver);2170pr_info(DRIVER_DESC ", Exiting.\n");2171}2172module_exit(wl1273_fm_module_exit);21732174MODULE_AUTHOR("Matti Aaltonen <[email protected]>");2175MODULE_DESCRIPTION(DRIVER_DESC);2176MODULE_LICENSE("GPL");217721782179