[PATCH 3/3] V4L2: WL1273 FM Radio: Controls for the FM radio.
This file implements V4L2 controls for using the Texas Instruments WL1273 FM Radio. Signed-off-by: Matti J. Aaltonen --- drivers/media/radio/Kconfig| 15 + drivers/media/radio/Makefile |1 + drivers/media/radio/radio-wl1273.c | 1849 3 files changed, 1865 insertions(+), 0 deletions(-) create mode 100644 drivers/media/radio/radio-wl1273.c diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 83567b8..209fd37 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -452,4 +452,19 @@ config RADIO_TIMBERDALE found behind the Timberdale FPGA on the Russellville board. Enabling this driver will automatically select the DSP and tuner. +config RADIO_WL1273 + tristate "Texas Instruments WL1273 I2C FM Radio" +depends on I2C && VIDEO_V4L2 && SND + select FW_LOADER + ---help--- + Choose Y here if you have this FM radio chip. + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux 2 API. Information on + this API and pointers to "v4l2" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called radio-wl1273. + endif # RADIO_ADAPTERS diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index f615583..d297074 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -26,5 +26,6 @@ obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o obj-$(CONFIG_RADIO_TEF6862) += tef6862.o obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o +obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o EXTRA_CFLAGS += -Isound diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c new file mode 100644 index 000..17b72df --- /dev/null +++ b/drivers/media/radio/radio-wl1273.c @@ -0,0 +1,1849 @@ +/* + * Driver for the Texas Instruments WL1273 FM radio. + * + * Copyright (C) Nokia Corporation + * Author: Matti J. Aaltonen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "Wl1273 FM Radio - V4L2" + +#define WL1273_POWER_SET_OFF 0 +#define WL1273_POWER_SET_FM(1 << 0) +#define WL1273_POWER_SET_RDS (1 << 1) +#define WL1273_POWER_SET_RETENTION (1 << 4) + +#define WL1273_PUPD_SET_OFF0x00 +#define WL1273_PUPD_SET_ON 0x01 +#define WL1273_PUPD_SET_RETENTION 0x10 + +#define WL1273_FREQ_MULT (1 / 625) +#define WL1273_INV_FREQ_MULT (625 / 1) +/* + * static unsigned char radio_region - Region + * + * The regions are 0=Japan, 1=USA-Europe. USA-Europe is the default. + */ +static unsigned char radio_region = 1; +module_param(radio_region, byte, 0); +MODULE_PARM_DESC(radio_region, "Region: 0=Japan, 1=USA-Europe*"); + +/* + * static int radio_nr - The number of the radio device + * + * The default is 0. + */ +static int radio_nr = -1; +module_param(radio_nr, int, 0); +MODULE_PARM_DESC(radio_nr, "Radio Nr"); + +struct wl1273_device { + struct v4l2_device v4l2dev; + struct video_device videodev; + struct device *dev; + struct wl1273_core *core; + bool rds_on; +}; + +static int wl1273_fm_set_tx_freq(struct wl1273_core *core, unsigned int freq) +{ + int r = 0; + + if (freq < core->regions[core->region].bottom_frequency) { + dev_err(&core->i2c_dev->dev, + "Frequency out of range: %d < %d\n", + freq, core->regions[core->region].bottom_frequency); + return -EDOM; + } + + if (freq > core->regions[core->region].top_frequency) { + dev_err(&core->i2c_dev->dev, + "Frequency out of range: %d > %d\n", + freq, core->regions[core->region].top_frequency); + return -EDOM; + } + + /* +* The driver works better with this msleep, +* the documentation doesn't mention it. +*/ + msleep(5); + dev_dbg(&core->i2c_dev->dev, "%s: freq: %d kHz\n", __func__, freq); + + INIT_COMPLETION(core->
[PATCH 3/3] V4L2: WL1273 FM Radio: Controls for the FM radio.
This file implements V4L2 controls for using the Texas Instruments WL1273 FM Radio. Signed-off-by: Matti J. Aaltonen --- drivers/media/radio/Kconfig| 15 + drivers/media/radio/Makefile |1 + drivers/media/radio/radio-wl1273.c | 805 3 files changed, 821 insertions(+), 0 deletions(-) create mode 100644 drivers/media/radio/radio-wl1273.c diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 83567b8..209fd37 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -452,4 +452,19 @@ config RADIO_TIMBERDALE found behind the Timberdale FPGA on the Russellville board. Enabling this driver will automatically select the DSP and tuner. +config RADIO_WL1273 + tristate "Texas Instruments WL1273 I2C FM Radio" +depends on I2C && VIDEO_V4L2 && SND + select FW_LOADER + ---help--- + Choose Y here if you have this FM radio chip. + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux 2 API. Information on + this API and pointers to "v4l2" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called radio-wl1273. + endif # RADIO_ADAPTERS diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index f615583..d297074 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -26,5 +26,6 @@ obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o obj-$(CONFIG_RADIO_TEF6862) += tef6862.o obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o +obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o EXTRA_CFLAGS += -Isound diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c new file mode 100644 index 000..07f6787 --- /dev/null +++ b/drivers/media/radio/radio-wl1273.c @@ -0,0 +1,805 @@ +/* + * Driver for the Texas Instruments WL1273 FM radio. + * + * Copyright (C) Nokia Corporation + * Author: Matti J. Aaltonen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#undef DEBUG + +#include +#include +#include +#include +#include + +#define DRIVER_DESC "Wl1273 FM Radio - V4L2" + +/* + * static int radio_nr - The number of the radio device + * + * The default is 0. + */ +static int radio_nr = -1; +module_param(radio_nr, int, 0); +MODULE_PARM_DESC(radio_nr, "Radio Nr"); + +struct wl1273_device { + struct video_device *videodev; + struct device *dev; + struct wl1273_core *core; + bool rds_on; +}; + +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)); + unsigned char *s; + u16 val; + int r; + + dev_dbg(radio->dev, "%s\n", __func__); + + if (radio->core->mode == WL1273_MODE_RX) + return count; + + if (mutex_lock_interruptible(&radio->core->lock)) + return -EINTR; + + /* Manual Mode */ + if (count > 255) + val = 255; + else + val = count; + + wl1273_fm_write_cmd(radio->core, WL1273_RDS_CONFIG_DATA_SET, val); + + s = kmalloc(val + 1, GFP_KERNEL); + if (!s) { + r = -ENOMEM; + goto out; + } + + if (copy_from_user(s + 1, buf, val)) { + kfree(s); + r = -EFAULT; + goto out; + } + + dev_dbg(radio->dev, "Count: %d\n", val); + dev_dbg(radio->dev, "From user: \"%s\"\n", s); + + s[0] = WL1273_RDS_DATA_SET; + wl1273_fm_write_data(radio->core, s, val + 1); + + kfree(s); + r = val; + +out: + mutex_unlock(&radio->core->lock); + + return r; +} + +static unsigned int wl1273_fm_fops_poll(struct file *file, + struct poll_table_struct *pts) +{ + struct wl1273_device *radio = video_get_drvdata(video_devdata(file)); + struct wl1273_core *core = radio->core; + unsigned int rd_index, wr_index; + + /* TODO: handle the case of multiple readers */ + + poll_wait(file, &core->read_queue, pts); + + rd_index = core->