[media] V4L2: WL1273 FM Radio: TI WL1273 FM radio driver

This module implements V4L2 controls for the Texas Instruments
WL1273 FM Radio and handles the communication with the chip.

Signed-off-by: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Matti Aaltonen 2011-03-01 10:10:36 -03:00 committed by Mauro Carvalho Chehab
parent 94fd5b7401
commit 96a9cc681e

View File

@ -1,7 +1,7 @@
/*
* Driver for the Texas Instruments WL1273 FM radio.
*
* Copyright (C) 2010 Nokia Corporation
* Copyright (C) 2011 Nokia Corporation
* Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
*
* This program is free software; you can redistribute it and/or
@ -104,58 +104,6 @@ static unsigned int rds_buf = 100;
module_param(rds_buf, uint, 0);
MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");
static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
{
struct i2c_client *client = core->client;
u8 b[2];
int r;
r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
if (r != 2) {
dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
return -EREMOTEIO;
}
*value = (u16)b[0] << 8 | b[1];
return 0;
}
static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
{
struct i2c_client *client = core->client;
u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
int r;
r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
if (r) {
dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
return r;
}
return 0;
}
static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
{
struct i2c_client *client = core->client;
struct i2c_msg msg;
int r;
msg.addr = client->addr;
msg.flags = 0;
msg.buf = data;
msg.len = len;
r = i2c_transfer(client->adapter, &msg, 1);
if (r != 1) {
dev_err(&client->dev, "%s: write error.\n", __func__);
return -EREMOTEIO;
}
return 0;
}
static int wl1273_fm_write_fw(struct wl1273_core *core,
__u8 *fw, int len)
{
@ -188,94 +136,6 @@ static int wl1273_fm_write_fw(struct wl1273_core *core,
return r;
}
/**
* wl1273_fm_set_audio() - Set audio mode.
* @core: A pointer to the device struct.
* @new_mode: The new audio mode.
*
* Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
*/
static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
{
int r = 0;
if (core->mode == WL1273_MODE_OFF ||
core->mode == WL1273_MODE_SUSPENDED)
return -EPERM;
if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
WL1273_PCM_DEF_MODE);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
core->i2s_mode);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
WL1273_AUDIO_ENABLE_I2S);
if (r)
goto out;
} else if (core->mode == WL1273_MODE_RX &&
new_mode == WL1273_AUDIO_ANALOG) {
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
WL1273_AUDIO_ENABLE_ANALOG);
if (r)
goto out;
} else if (core->mode == WL1273_MODE_TX &&
new_mode == WL1273_AUDIO_DIGITAL) {
r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
core->i2s_mode);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
WL1273_AUDIO_IO_SET_I2S);
if (r)
goto out;
} else if (core->mode == WL1273_MODE_TX &&
new_mode == WL1273_AUDIO_ANALOG) {
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
WL1273_AUDIO_IO_SET_ANALOG);
if (r)
goto out;
}
core->audio_mode = new_mode;
out:
return r;
}
/**
* wl1273_fm_set_volume() - Set volume.
* @core: A pointer to the device struct.
* @volume: The new volume value.
*/
static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
{
u16 val;
int r;
if (volume > WL1273_MAX_VOLUME)
return -EINVAL;
if (core->volume == volume)
return 0;
val = volume;
r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
if (r)
return r;
core->volume = volume;
return 0;
}
#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)
#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)
#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)
@ -306,7 +166,7 @@ static int wl1273_fm_rds(struct wl1273_device *radio)
if (core->mode != WL1273_MODE_RX)
return 0;
r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
r = core->read(core, WL1273_RDS_SYNC_GET, &val);
if (r)
return r;
@ -374,7 +234,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
u16 flags;
int r;
r = wl1273_fm_read_reg(core, WL1273_FLAG_GET, &flags);
r = core->read(core, WL1273_FLAG_GET, &flags);
if (r)
goto out;
@ -398,7 +258,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
if (flags & WL1273_LEV_EVENT) {
u16 level;
r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &level);
r = core->read(core, WL1273_RSSI_LVL_GET, &level);
if (r)
goto out;
@ -439,8 +299,8 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
dev_dbg(radio->dev, "IRQ: FR:\n");
if (core->mode == WL1273_MODE_RX) {
r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET,
TUNER_MODE_STOP_SEARCH);
r = core->write(core, WL1273_TUNER_MODE_SET,
TUNER_MODE_STOP_SEARCH);
if (r) {
dev_err(radio->dev,
"%s: TUNER_MODE_SET fails: %d\n",
@ -448,7 +308,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
goto out;
}
r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &freq);
r = core->read(core, WL1273_FREQ_SET, &freq);
if (r)
goto out;
@ -467,7 +327,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);
} else {
r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &freq);
r = core->read(core, WL1273_CHANL_SET, &freq);
if (r)
goto out;
@ -477,8 +337,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
}
out:
wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET,
radio->irq_flags);
core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
complete(&radio->busy);
return IRQ_HANDLED;
@ -512,7 +371,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);
/* Set the current tx channel */
r = wl1273_fm_write_cmd(core, WL1273_CHANL_SET, freq / 10);
r = core->write(core, WL1273_CHANL_SET, freq / 10);
if (r)
return r;
@ -526,7 +385,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r);
/* Enable the output power */
r = wl1273_fm_write_cmd(core, WL1273_POWER_ENB_SET, 1);
r = core->write(core, WL1273_POWER_ENB_SET, 1);
if (r)
return r;
@ -566,20 +425,20 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)
dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);
wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags);
core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
if (radio->band == WL1273_BAND_JAPAN)
f = (freq - WL1273_BAND_JAPAN_LOW) / 50;
else
f = (freq - WL1273_BAND_OTHER_LOW) / 50;
r = wl1273_fm_write_cmd(core, WL1273_FREQ_SET, f);
r = core->write(core, WL1273_FREQ_SET, f);
if (r) {
dev_err(radio->dev, "FREQ_SET fails\n");
goto err;
}
r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
if (r) {
dev_err(radio->dev, "TUNER_MODE_SET fails\n");
goto err;
@ -609,7 +468,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
int r;
if (core->mode == WL1273_MODE_RX) {
r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &f);
r = core->read(core, WL1273_FREQ_SET, &f);
if (r)
return r;
@ -619,7 +478,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
else
freq = WL1273_BAND_OTHER_LOW + 50 * f;
} else {
r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &f);
r = core->read(core, WL1273_CHANL_SET, &f);
if (r)
return r;
@ -670,7 +529,7 @@ static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)
}
/* ignore possible error here */
wl1273_fm_write_cmd(core, WL1273_RESET, 0);
core->write(core, WL1273_RESET, 0);
dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);
out:
@ -683,14 +542,14 @@ static int wl1273_fm_stop(struct wl1273_device *radio)
struct wl1273_core *core = radio->core;
if (core->mode == WL1273_MODE_RX) {
int r = wl1273_fm_write_cmd(core, WL1273_POWER_SET,
int r = core->write(core, WL1273_POWER_SET,
WL1273_POWER_SET_OFF);
if (r)
dev_err(radio->dev, "%s: POWER_SET fails: %d\n",
__func__, r);
} else if (core->mode == WL1273_MODE_TX) {
int r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_OFF);
int r = core->write(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_OFF);
if (r)
dev_err(radio->dev,
"%s: PUPD_SET fails: %d\n", __func__, r);
@ -725,11 +584,11 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
val |= WL1273_POWER_SET_RDS;
/* If this fails try again */
r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val);
r = core->write(core, WL1273_POWER_SET, val);
if (r) {
msleep(100);
r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val);
r = core->write(core, WL1273_POWER_SET, val);
if (r) {
dev_err(dev, "%s: POWER_SET fails\n", __func__);
goto fail;
@ -742,11 +601,10 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
} else if (new_mode == WL1273_MODE_TX) {
/* If this fails try again once */
r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_ON);
r = core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON);
if (r) {
msleep(100);
r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
r = core->write(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_ON);
if (r) {
dev_err(dev, "%s: PUPD_SET fails\n", __func__);
@ -755,9 +613,9 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
}
if (radio->rds_on)
r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1);
r = core->write(core, WL1273_RDS_DATA_ENB, 1);
else
r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0);
r = core->write(core, WL1273_RDS_DATA_ENB, 0);
} else {
dev_warn(dev, "%s: Illegal mode.\n", __func__);
}
@ -777,14 +635,14 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
if (radio->rds_on)
val |= WL1273_POWER_SET_RDS;
r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val);
r = core->write(core, WL1273_POWER_SET, val);
if (r) {
dev_err(dev, "%s: POWER_SET fails\n", __func__);
goto fail;
}
} else if (new_mode == WL1273_MODE_TX) {
r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_ON);
r = core->write(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_ON);
if (r) {
dev_err(dev, "%s: PUPD_SET fails\n", __func__);
goto fail;
@ -808,10 +666,10 @@ static int wl1273_fm_suspend(struct wl1273_device *radio)
/* Cannot go from OFF to SUSPENDED */
if (core->mode == WL1273_MODE_RX)
r = wl1273_fm_write_cmd(core, WL1273_POWER_SET,
r = core->write(core, WL1273_POWER_SET,
WL1273_POWER_SET_RETENTION);
else if (core->mode == WL1273_MODE_TX)
r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET,
r = core->write(core, WL1273_PUPD_SET,
WL1273_PUPD_SET_RETENTION);
else
r = -EINVAL;
@ -852,8 +710,7 @@ static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)
}
core->mode = mode;
r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET,
radio->irq_flags);
r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
if (r) {
dev_err(dev, "INT_MASK_SET fails.\n");
goto out;
@ -951,22 +808,21 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
INIT_COMPLETION(radio->busy);
dev_dbg(radio->dev, "%s: BUSY\n", __func__);
r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags);
r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
if (r)
goto out;
dev_dbg(radio->dev, "%s\n", __func__);
r = wl1273_fm_write_cmd(core, WL1273_SEARCH_LVL_SET, level);
r = core->write(core, WL1273_SEARCH_LVL_SET, level);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_SEARCH_DIR_SET, dir);
r = core->write(core, WL1273_SEARCH_DIR_SET, dir);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET,
TUNER_MODE_AUTO_SEEK);
r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
if (r)
goto out;
@ -994,8 +850,7 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
INIT_COMPLETION(radio->busy);
dev_dbg(radio->dev, "%s: BUSY\n", __func__);
r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET,
TUNER_MODE_AUTO_SEEK);
r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
if (r)
goto out;
@ -1020,7 +875,7 @@ static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)
core->mode == WL1273_MODE_SUSPENDED)
return -EPERM;
r = wl1273_fm_read_reg(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
r = core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
if (r) {
dev_err(dev, "%s: read error: %d\n", __func__, r);
goto out;
@ -1066,7 +921,7 @@ static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,
goto out;
}
r = wl1273_fm_write_cmd(core, WL1273_PREMPH_SET, em);
r = core->write(core, WL1273_PREMPH_SET, em);
if (r)
goto out;
@ -1086,7 +941,7 @@ static int wl1273_fm_rds_on(struct wl1273_device *radio)
if (radio->rds_on)
return 0;
r = wl1273_fm_write_cmd(core, WL1273_POWER_SET,
r = core->write(core, WL1273_POWER_SET,
WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);
if (r)
goto out;
@ -1108,7 +963,7 @@ static int wl1273_fm_rds_off(struct wl1273_device *radio)
radio->irq_flags &= ~WL1273_RDS_EVENT;
r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags);
r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
if (r)
goto out;
@ -1120,7 +975,7 @@ static int wl1273_fm_rds_off(struct wl1273_device *radio)
dev_dbg(radio->dev, "%s\n", __func__);
r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
r = core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
if (r)
goto out;
@ -1143,14 +998,14 @@ static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)
return -EPERM;
if (new_mode == WL1273_RDS_RESET) {
r = wl1273_fm_write_cmd(core, WL1273_RDS_CNTRL_SET, 1);
r = core->write(core, WL1273_RDS_CNTRL_SET, 1);
return r;
}
if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {
r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0);
r = core->write(core, WL1273_RDS_DATA_ENB, 0);
} else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {
r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1);
r = core->write(core, WL1273_RDS_DATA_ENB, 1);
} else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {
r = wl1273_fm_rds_off(radio);
} else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {
@ -1171,12 +1026,13 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
struct wl1273_core *core = radio->core;
u16 val;
int r;
dev_dbg(radio->dev, "%s\n", __func__);
if (radio->core->mode != WL1273_MODE_TX)
if (core->mode != WL1273_MODE_TX)
return count;
if (radio->rds_users == 0) {
@ -1184,7 +1040,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
return 0;
}
if (mutex_lock_interruptible(&radio->core->lock))
if (mutex_lock_interruptible(&core->lock))
return -EINTR;
/*
* Multiple processes can open the device, but only
@ -1202,7 +1058,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
else
val = count;
wl1273_fm_write_cmd(radio->core, WL1273_RDS_CONFIG_DATA_SET, val);
core->write(core, WL1273_RDS_CONFIG_DATA_SET, val);
if (copy_from_user(radio->write_buf + 1, buf, val)) {
r = -EFAULT;
@ -1213,11 +1069,11 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);
radio->write_buf[0] = WL1273_RDS_DATA_SET;
wl1273_fm_write_data(radio->core, radio->write_buf, val + 1);
core->write_data(core, radio->write_buf, val + 1);
r = val;
out:
mutex_unlock(&radio->core->lock);
mutex_unlock(&core->lock);
return r;
}
@ -1263,8 +1119,8 @@ static int wl1273_fm_fops_open(struct file *file)
radio->irq_flags |= WL1273_RDS_EVENT;
r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET,
radio->irq_flags);
r = core->write(core, WL1273_INT_MASK_SET,
radio->irq_flags);
if (r) {
mutex_unlock(&core->lock);
goto out;
@ -1295,9 +1151,9 @@ static int wl1273_fm_fops_release(struct file *file)
radio->irq_flags &= ~WL1273_RDS_EVENT;
if (core->mode == WL1273_MODE_RX) {
r = wl1273_fm_write_cmd(core,
WL1273_INT_MASK_SET,
radio->irq_flags);
r = core->write(core,
WL1273_INT_MASK_SET,
radio->irq_flags);
if (r) {
mutex_unlock(&core->lock);
goto out;
@ -1324,7 +1180,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
dev_dbg(radio->dev, "%s\n", __func__);
if (radio->core->mode != WL1273_MODE_RX)
if (core->mode != WL1273_MODE_RX)
return 0;
if (radio->rds_users == 0) {
@ -1345,7 +1201,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
}
radio->owner = file;
r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
r = core->read(core, WL1273_RDS_SYNC_GET, &val);
if (r) {
dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);
goto out;
@ -1466,23 +1322,24 @@ static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
*/
static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
{
struct wl1273_core *core = radio->core;
int r;
if (radio->core->mode == WL1273_MODE_OFF ||
radio->core->mode == WL1273_MODE_SUSPENDED)
if (core->mode == WL1273_MODE_OFF ||
core->mode == WL1273_MODE_SUSPENDED)
return -EPERM;
mutex_lock(&radio->core->lock);
mutex_lock(&core->lock);
/* Convert the dBuV value to chip presentation */
r = wl1273_fm_write_cmd(radio->core, WL1273_POWER_LEV_SET, 122 - power);
r = core->write(core, WL1273_POWER_LEV_SET, 122 - power);
if (r)
goto out;
radio->tx_power = power;
out:
mutex_unlock(&radio->core->lock);
mutex_unlock(&core->lock);
return r;
}
@ -1493,23 +1350,24 @@ static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,
unsigned int spacing)
{
struct wl1273_core *core = radio->core;
int r;
if (spacing == 0) {
r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_100kHz);
r = core->write(core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_100kHz);
radio->spacing = 100;
} else if (spacing - 50000 < 25000) {
r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_50kHz);
r = core->write(core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_50kHz);
radio->spacing = 50;
} else if (spacing - 100000 < 50000) {
r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_100kHz);
r = core->write(core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_100kHz);
radio->spacing = 100;
} else {
r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_200kHz);
r = core->write(core, WL1273_SCAN_SPACING_SET,
WL1273_SPACING_200kHz);
radio->spacing = 200;
}
@ -1567,17 +1425,17 @@ static int wl1273_fm_vidioc_s_ctrl(struct v4l2_ctrl *ctrl)
return -EINTR;
if (core->mode == WL1273_MODE_RX && ctrl->val)
r = wl1273_fm_write_cmd(core,
WL1273_MUTE_STATUS_SET,
WL1273_MUTE_HARD_LEFT |
WL1273_MUTE_HARD_RIGHT);
r = core->write(core,
WL1273_MUTE_STATUS_SET,
WL1273_MUTE_HARD_LEFT |
WL1273_MUTE_HARD_RIGHT);
else if (core->mode == WL1273_MODE_RX)
r = wl1273_fm_write_cmd(core,
WL1273_MUTE_STATUS_SET, 0x0);
r = core->write(core,
WL1273_MUTE_STATUS_SET, 0x0);
else if (core->mode == WL1273_MODE_TX && ctrl->val)
r = wl1273_fm_write_cmd(core, WL1273_MUTE, 1);
r = core->write(core, WL1273_MUTE, 1);
else if (core->mode == WL1273_MODE_TX)
r = wl1273_fm_write_cmd(core, WL1273_MUTE, 0);
r = core->write(core, WL1273_MUTE, 0);
mutex_unlock(&core->lock);
break;
@ -1672,7 +1530,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
if (mutex_lock_interruptible(&core->lock))
return -EINTR;
r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val);
r = core->read(core, WL1273_STEREO_GET, &val);
if (r)
goto out;
@ -1681,7 +1539,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
else
tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val);
r = core->read(core, WL1273_RSSI_LVL_GET, &val);
if (r)
goto out;
@ -1690,7 +1548,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
tuner->afc = 0;
r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
r = core->read(core, WL1273_RDS_SYNC_GET, &val);
if (r)
goto out;
@ -1736,8 +1594,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);
if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET,
WL1273_RX_MONO);
r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
if (r < 0) {
dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
__func__, r);
@ -1745,8 +1602,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
}
radio->stereo = false;
} else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {
r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET,
WL1273_RX_STEREO);
r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
if (r < 0) {
dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
__func__, r);
@ -1885,10 +1741,10 @@ static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, WL1273_TX_MONO);
r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
else
r = wl1273_fm_write_cmd(core, WL1273_MONO_SET,
WL1273_RX_STEREO);
r = core->write(core, WL1273_MONO_SET,
WL1273_RX_STEREO);
if (r < 0)
dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
"MONO_SET fails: %d\n", r);
@ -1923,7 +1779,7 @@ static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
if (mutex_lock_interruptible(&core->lock))
return -EINTR;
r = wl1273_fm_read_reg(core, WL1273_MONO_SET, &val);
r = core->read(core, WL1273_MONO_SET, &val);
if (r)
goto out;
@ -1960,38 +1816,38 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
return 0;
}
r = wl1273_fm_read_reg(core, WL1273_ASIC_ID_GET, &val);
r = core->read(core, WL1273_ASIC_ID_GET, &val);
if (r)
dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);
else
dev_info(dev, "ASIC_ID: 0x%04x\n", val);
r = wl1273_fm_read_reg(core, WL1273_ASIC_VER_GET, &val);
r = core->read(core, WL1273_ASIC_VER_GET, &val);
if (r)
dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);
else
dev_info(dev, "ASIC Version: 0x%04x\n", val);
r = wl1273_fm_read_reg(core, WL1273_FIRM_VER_GET, &val);
r = core->read(core, WL1273_FIRM_VER_GET, &val);
if (r)
dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);
else
dev_info(dev, "FW version: %d(0x%04x)\n", val, val);
r = wl1273_fm_read_reg(core, WL1273_BAND_SET, &val);
r = core->read(core, WL1273_BAND_SET, &val);
if (r)
dev_err(dev, "%s: Get BAND fails.\n", __func__);
else
dev_info(dev, "BAND: %d\n", val);
if (core->mode == WL1273_MODE_TX) {
r = wl1273_fm_read_reg(core, WL1273_PUPD_SET, &val);
r = core->read(core, WL1273_PUPD_SET, &val);
if (r)
dev_err(dev, "%s: Get PUPD fails.\n", __func__);
else
dev_info(dev, "PUPD: 0x%04x\n", val);
r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &val);
r = core->read(core, WL1273_CHANL_SET, &val);
if (r)
dev_err(dev, "%s: Get CHANL fails.\n", __func__);
else
@ -1999,13 +1855,13 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
} else if (core->mode == WL1273_MODE_RX) {
int bf = radio->rangelow;
r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &val);
r = core->read(core, WL1273_FREQ_SET, &val);
if (r)
dev_err(dev, "%s: Get FREQ fails.\n", __func__);
else
dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);
r = wl1273_fm_read_reg(core, WL1273_MOST_MODE_SET, &val);
r = core->read(core, WL1273_MOST_MODE_SET, &val);
if (r)
dev_err(dev, "%s: Get MOST_MODE fails.\n",
__func__);
@ -2016,7 +1872,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
else
dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);
r = wl1273_fm_read_reg(core, WL1273_MOST_BLEND_SET, &val);
r = core->read(core, WL1273_MOST_BLEND_SET, &val);
if (r)
dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);
else if (val == 0)
@ -2027,7 +1883,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
else
dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);
r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val);
r = core->read(core, WL1273_STEREO_GET, &val);
if (r)
dev_err(dev, "%s: Get STEREO fails.\n", __func__);
else if (val == 0)
@ -2037,25 +1893,25 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
else
dev_info(dev, "STEREO: Unexpected value: %d\n", val);
r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val);
r = core->read(core, WL1273_RSSI_LVL_GET, &val);
if (r)
dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);
else
dev_info(dev, "RX signal strength: %d\n", (s16) val);
r = wl1273_fm_read_reg(core, WL1273_POWER_SET, &val);
r = core->read(core, WL1273_POWER_SET, &val);
if (r)
dev_err(dev, "%s: Get POWER fails.\n", __func__);
else
dev_info(dev, "POWER: 0x%04x\n", val);
r = wl1273_fm_read_reg(core, WL1273_INT_MASK_SET, &val);
r = core->read(core, WL1273_INT_MASK_SET, &val);
if (r)
dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);
else
dev_info(dev, "INT_MASK: 0x%04x\n", val);
r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val);
r = core->read(core, WL1273_RDS_SYNC_GET, &val);
if (r)
dev_err(dev, "%s: Get RDS_SYNC fails.\n",
__func__);
@ -2067,14 +1923,14 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
else
dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);
r = wl1273_fm_read_reg(core, WL1273_I2S_MODE_CONFIG_SET, &val);
r = core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val);
if (r)
dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",
__func__);
else
dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);
r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
r = core->read(core, WL1273_VOLUME_SET, &val);
if (r)
dev_err(dev, "%s: Get VOLUME fails.\n", __func__);
else
@ -2184,10 +2040,6 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
radio->stereo = true;
radio->bus_type = "I2C";
radio->core->write = wl1273_fm_write_cmd;
radio->core->set_audio = wl1273_fm_set_audio;
radio->core->set_volume = wl1273_fm_set_volume;
if (radio->core->pdata->request_resources) {
r = radio->core->pdata->request_resources(radio->core->client);
if (r) {