Re: [PATCH v9 2/4] MFD: WL1273 FM Radio: MFD driver for the FM radio.
Em 30-08-2010 08:38, Matti J. Aaltonen escreveu: This is a parent for two child drivers: a V4L2 driver and an ALSA codec driver. The MFD part implements I2C communication to the device and provides a couple of functions that are called from both children. Signed-off-by: Matti J. Aaltonen matti.j.aalto...@nokia.com --- drivers/mfd/wl1273-core.c | 612 +++ include/linux/mfd/wl1273-core.h | 314 2 files changed, 926 insertions(+), 0 deletions(-) create mode 100644 drivers/mfd/wl1273-core.c create mode 100644 include/linux/mfd/wl1273-core.h diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c new file mode 100644 index 000..9fa3850 --- /dev/null +++ b/drivers/mfd/wl1273-core.c @@ -0,0 +1,612 @@ +/* + * MFD driver for wl1273 FM radio and audio codec submodules. + * + * Author: Matti Aaltonen matti.j.aalto...@nokia.com + * + * Copyright: (C) 2010 Nokia Corporation + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include linux/delay.h +#include linux/interrupt.h +#include linux/mfd/wl1273-core.h +#include linux/slab.h +#include media/v4l2-common.h + +#define DRIVER_DESC WL1273 FM Radio Core + +#define WL1273_IRQ_MASK (WL1273_FR_EVENT | \ + WL1273_POW_ENB_EVENT) + +static const struct band_info bands[] = { + /* USA Europe */ + { + .bottom_frequency = 87500, + .top_frequency = 108000, + .band = V4L2_FM_BAND_OTHER, + }, + /* Japan */ + { + .bottom_frequency = 76000, + .top_frequency = 9, + .band = V4L2_FM_BAND_JAPAN, + }, +}; + +/* + * static unsigned char radio_band - Band + * + * The bands are 0 == USA-Europe, 1 == Japan. USA-Europe is the default. + */ +static unsigned char radio_band; +module_param(radio_band, byte, 0); +MODULE_PARM_DESC(radio_band, Band: 0=USA-Europe, 1=Japan); There's no need for a parameter to set the bandwidth. + +/* + * static unsigned int rds_buf - the number of RDS buffer blocks used. + * + * The default number is 100. + */ +static unsigned int rds_buf = 100; +module_param(rds_buf, uint, 0); +MODULE_PARM_DESC(rds_buf, RDS buffer entries: *100*); Hmm... it would be better to use, instead: MODULE_PARM_DESC(rds_buf, Number of RDS buffer entries. Default = 100); + +int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value) +{ + struct i2c_client *client = core-i2c_dev; + u8 b[2]; + int r; + + r = i2c_smbus_read_i2c_block_data(client, reg, 2, 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; +} +EXPORT_SYMBOL(wl1273_fm_read_reg); Hmm... why do you need to export a symbol here? + +int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param) +{ + struct i2c_client *client = core-i2c_dev; + u8 buf[] = { (param 8) 0xff, param 0xff }; + int r; + + r = i2c_smbus_write_i2c_block_data(client, cmd, 2, buf); + if (r) { + dev_err(client-dev, %s: Cmd: %d fails.\n, __func__, cmd); + return r; + } + + return 0; +} +EXPORT_SYMBOL(wl1273_fm_write_cmd); Hmm... why do you need to export a symbol here? + +int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len) +{ + struct i2c_client *client = core-i2c_dev; + struct i2c_msg msg[1]; + int r; + + msg[0].addr = client-addr; + msg[0].flags = 0; + msg[0].buf = data; + msg[0].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; +} +EXPORT_SYMBOL(wl1273_fm_write_data); Hmm... why do you need to export a symbol here? + +/** + * 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. + */ +int
[PATCH v9 2/4] MFD: WL1273 FM Radio: MFD driver for the FM radio.
This is a parent for two child drivers: a V4L2 driver and an ALSA codec driver. The MFD part implements I2C communication to the device and provides a couple of functions that are called from both children. Signed-off-by: Matti J. Aaltonen matti.j.aalto...@nokia.com --- drivers/mfd/wl1273-core.c | 612 +++ include/linux/mfd/wl1273-core.h | 314 2 files changed, 926 insertions(+), 0 deletions(-) create mode 100644 drivers/mfd/wl1273-core.c create mode 100644 include/linux/mfd/wl1273-core.h diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c new file mode 100644 index 000..9fa3850 --- /dev/null +++ b/drivers/mfd/wl1273-core.c @@ -0,0 +1,612 @@ +/* + * MFD driver for wl1273 FM radio and audio codec submodules. + * + * Author: Matti Aaltonen matti.j.aalto...@nokia.com + * + * Copyright: (C) 2010 Nokia Corporation + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include linux/delay.h +#include linux/interrupt.h +#include linux/mfd/wl1273-core.h +#include linux/slab.h +#include media/v4l2-common.h + +#define DRIVER_DESC WL1273 FM Radio Core + +#define WL1273_IRQ_MASK (WL1273_FR_EVENT | \ + WL1273_POW_ENB_EVENT) + +static const struct band_info bands[] = { + /* USA Europe */ + { + .bottom_frequency = 87500, + .top_frequency = 108000, + .band = V4L2_FM_BAND_OTHER, + }, + /* Japan */ + { + .bottom_frequency = 76000, + .top_frequency = 9, + .band = V4L2_FM_BAND_JAPAN, + }, +}; + +/* + * static unsigned char radio_band - Band + * + * The bands are 0 == USA-Europe, 1 == Japan. USA-Europe is the default. + */ +static unsigned char radio_band; +module_param(radio_band, byte, 0); +MODULE_PARM_DESC(radio_band, Band: 0=USA-Europe, 1=Japan); + +/* + * static unsigned int rds_buf - the number of RDS buffer blocks used. + * + * The default number is 100. + */ +static unsigned int rds_buf = 100; +module_param(rds_buf, uint, 0); +MODULE_PARM_DESC(rds_buf, RDS buffer entries: *100*); + +int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value) +{ + struct i2c_client *client = core-i2c_dev; + u8 b[2]; + int r; + + r = i2c_smbus_read_i2c_block_data(client, reg, 2, 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; +} +EXPORT_SYMBOL(wl1273_fm_read_reg); + +int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param) +{ + struct i2c_client *client = core-i2c_dev; + u8 buf[] = { (param 8) 0xff, param 0xff }; + int r; + + r = i2c_smbus_write_i2c_block_data(client, cmd, 2, buf); + if (r) { + dev_err(client-dev, %s: Cmd: %d fails.\n, __func__, cmd); + return r; + } + + return 0; +} +EXPORT_SYMBOL(wl1273_fm_write_cmd); + +int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len) +{ + struct i2c_client *client = core-i2c_dev; + struct i2c_msg msg[1]; + int r; + + msg[0].addr = client-addr; + msg[0].flags = 0; + msg[0].buf = data; + msg[0].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; +} +EXPORT_SYMBOL(wl1273_fm_write_data); + +/** + * 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. + */ +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); +