Re: [PATCH REVIEW 03/18] Montage M88DS3103 DVB-S/S2 demodulator driver
Hi Antti, I have a small suggestion, see below. On 08.12.2013 23:31, Antti Palosaari wrote: > diff --git a/drivers/media/dvb-frontends/m88ds3103.c > b/drivers/media/dvb-frontends/m88ds3103.c > new file mode 100644 > index 000..91b3729 > --- /dev/null > +++ b/drivers/media/dvb-frontends/m88ds3103.c > @@ -0,0 +1,1293 @@ > +/* > + * Montage M88DS3103 demodulator driver > + * > + * Copyright (C) 2013 Antti Palosaari > + * > + *This program is free software; you can redistribute it and/or modify > + *it under the terms of the GNU General Public License as published by > + *the Free Software Foundation; either version 2 of the License, or > + *(at your option) any later version. > + * > + *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 Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include "m88ds3103_priv.h" > + > +static struct dvb_frontend_ops m88ds3103_ops; > + > +/* write multiple registers */ > +static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, > + u8 reg, const u8 *val, int len) > +{ > + int ret; > + u8 buf[1 + len]; Looking at the recent patches for variable length arrays, I think this should be converted to fixed size. > + struct i2c_msg msg[1] = { > + { > + .addr = priv->cfg->i2c_addr, > + .flags = 0, > + .len = sizeof(buf), > + .buf = buf, > + } > + }; > + > + buf[0] = reg; > + memcpy(&buf[1], val, len); > + > + mutex_lock(&priv->i2c_mutex); > + ret = i2c_transfer(priv->i2c, msg, 1); > + mutex_unlock(&priv->i2c_mutex); > + if (ret == 1) { > + ret = 0; > + } else { > + dev_warn(&priv->i2c->dev, > + "%s: i2c wr failed=%d reg=%02x len=%d\n", > + KBUILD_MODNAME, ret, reg, len); > + ret = -EREMOTEIO; > + } > + > + return ret; > +} > + > +/* read multiple registers */ > +static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, > + u8 reg, u8 *val, int len) > +{ > + int ret; > + u8 buf[len]; Same as above. > + struct i2c_msg msg[2] = { > + { > + .addr = priv->cfg->i2c_addr, > + .flags = 0, > + .len = 1, > + .buf = ®, > + }, { > + .addr = priv->cfg->i2c_addr, > + .flags = I2C_M_RD, > + .len = sizeof(buf), > + .buf = buf, > + } > + }; > + > + mutex_lock(&priv->i2c_mutex); > + ret = i2c_transfer(priv->i2c, msg, 2); > + mutex_unlock(&priv->i2c_mutex); > + if (ret == 2) { > + memcpy(val, buf, len); > + ret = 0; > + } else { > + dev_warn(&priv->i2c->dev, > + "%s: i2c rd failed=%d reg=%02x len=%d\n", > + KBUILD_MODNAME, ret, reg, len); > + ret = -EREMOTEIO; > + } > + > + return ret; > +} > + Regards Matthias -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Profitable & Important
Good day, I have a business proposal which will be of great benefit to you. Contact me for details through: Email: shu...@qq.com I await your prompt response. Thanks. shu...@qq.com -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
cron job: media_tree daily build: WARNINGS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Mon Dec 9 04:00:18 CET 2013 git branch: test git hash: 3f823e094b935c1882605f8720336ee23433a16d gcc version:i686-linux-gcc (GCC) 4.8.1 sparse version: 0.4.5-rc1 host hardware: x86_64 host os:3.12-0.slh.2-amd64 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-exynos: OK linux-git-arm-mx: OK linux-git-arm-omap: OK linux-git-arm-omap1: OK linux-git-arm-pxa: OK linux-git-blackfin: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.31.14-i686: WARNINGS linux-2.6.32.27-i686: WARNINGS linux-2.6.33.7-i686: WARNINGS linux-2.6.34.7-i686: WARNINGS linux-2.6.35.9-i686: WARNINGS linux-2.6.36.4-i686: WARNINGS linux-2.6.37.6-i686: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.39.4-i686: WARNINGS linux-3.0.60-i686: WARNINGS linux-3.1.10-i686: WARNINGS linux-3.2.37-i686: OK linux-3.3.8-i686: OK linux-3.4.27-i686: WARNINGS linux-3.5.7-i686: WARNINGS linux-3.6.11-i686: WARNINGS linux-3.7.4-i686: WARNINGS linux-3.8-i686: WARNINGS linux-3.9.2-i686: WARNINGS linux-3.10.1-i686: OK linux-3.11.1-i686: OK linux-3.12-i686: OK linux-3.13-rc1-i686: OK linux-2.6.31.14-x86_64: WARNINGS linux-2.6.32.27-x86_64: WARNINGS linux-2.6.33.7-x86_64: WARNINGS linux-2.6.34.7-x86_64: WARNINGS linux-2.6.35.9-x86_64: WARNINGS linux-2.6.36.4-x86_64: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-x86_64: WARNINGS linux-3.1.10-x86_64: WARNINGS linux-3.2.37-x86_64: OK linux-3.3.8-x86_64: OK linux-3.4.27-x86_64: WARNINGS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9.2-x86_64: WARNINGS linux-3.10.1-x86_64: OK linux-3.11.1-x86_64: OK linux-3.12-x86_64: OK linux-3.13-rc1-x86_64: OK apps: WARNINGS spec-git: OK sparse version: 0.4.5-rc1 sparse: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Monday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Monday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/media.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Profitable & Important
Good day, I have a business proposal which will be of great benefit to you. Contact me for details through: Email: shu...@qq.com I await your prompt response. Thanks. shu...@qq.com -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [GIT PULL] git://linuxtv.org/mkrufky/dvb cx24117
Mauro, What is the status of this pull request? Patchwork says "changes requested" but I have no record of any changes requested https://patchwork.linuxtv.org/patch/20728/ Thanks, Mike On Wed, Nov 13, 2013 at 6:01 PM, Michael Krufky wrote: > The following changes since commit > 80f93c7b0f4599ffbdac8d964ecd1162b8b618b9: > > [media] media: st-rc: Add ST remote control driver (2013-10-31 > 08:20:08 -0200) > > are available in the git repository at: > > git://linuxtv.org/mkrufky/dvb cx24117 > > for you to fetch changes up to 1c468cec3701eb6e26c4911f8a9e8e35cbdebc01: > > cx24117: Fix LNB set_voltage function (2013-11-13 13:06:44 -0500) > > > Luis Alves (2): > cx24117: Add complete demod command list > cx24117: Fix LNB set_voltage function > > drivers/media/dvb-frontends/cx24117.c | 121 > -- 1 file changed, 71 insertions(+), > 50 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL FOR 3.14] smiapp and lm3560 fixes
The following changes since commit 3f823e094b935c1882605f8720336ee23433a16d: [media] exynos4-is: Simplify fimc-is hardware polling helpers (2013-12-04 15:54:19 -0200) are available in the git repository at: ssh://linuxtv.org/git/sailus/media_tree.git upstream for you to fetch changes up to 1af0a5b798934777abba890abde5a3c5ef334277: media: i2c: lm3560: fix missing unlock on error, fault handling (2013-12-09 01:41:23 +0200) Daniel Jeong (1): media: i2c: lm3560: fix missing unlock on error, fault handling Ricardo Ribalda Delgado (1): smiapp: Fix BUG_ON() on an impossible condition drivers/media/i2c/lm3560.c | 14 +++--- drivers/media/i2c/smiapp/smiapp-core.c |1 - 2 files changed, 7 insertions(+), 8 deletions(-) -- Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Your Email HAs Won You £500.000GBP
You are among the winners of this year Microsoft Promotion Award Team your email have won you £500.000GBP,(Five Hundred Thousand Pounds Sterling). To file for your claim, please contact our fiduciary agent for claims with the information below: Agent Name: Mr.Joe Oliver Tel: +447 086 463801 Email: micrw...@blumail.org TICKET No:56475600545 188 1. Full Names:. 2. Home Address:... 3. Age: 4. Sex: 5. Marital Status:. 6. Occupation:. 7. Phone numbers:.. 8. Country: Yours in service, Mrs.Rose Mata [Publicity Secretary] Co-ordinator Microsoft Promotion -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 09/18] m88ds3103: do not use dynamic stack allocation
I2C transfer were using dynamic stack allocation. Get rid of it. Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 91b3729..302c923 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -26,17 +26,22 @@ static struct dvb_frontend_ops m88ds3103_ops; static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, u8 reg, const u8 *val, int len) { +#define MAX_WR_LEN 32 +#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) int ret; - u8 buf[1 + len]; + u8 buf[MAX_WR_XFER_LEN]; struct i2c_msg msg[1] = { { .addr = priv->cfg->i2c_addr, .flags = 0, - .len = sizeof(buf), + .len = 1 + len, .buf = buf, } }; + if (WARN_ON(len > MAX_WR_LEN)) + return -EINVAL; + buf[0] = reg; memcpy(&buf[1], val, len); @@ -59,8 +64,10 @@ static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, u8 reg, u8 *val, int len) { +#define MAX_RD_LEN 3 +#define MAX_RD_XFER_LEN (MAX_RD_LEN) int ret; - u8 buf[len]; + u8 buf[MAX_RD_XFER_LEN]; struct i2c_msg msg[2] = { { .addr = priv->cfg->i2c_addr, @@ -70,11 +77,14 @@ static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, }, { .addr = priv->cfg->i2c_addr, .flags = I2C_M_RD, - .len = sizeof(buf), + .len = len, .buf = buf, } }; + if (WARN_ON(len > MAX_RD_LEN)) + return -EINVAL; + mutex_lock(&priv->i2c_mutex); ret = i2c_transfer(priv->i2c, msg, 2); mutex_unlock(&priv->i2c_mutex); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 01/18] em28xx: add support for Empia EM28178
New chip version, which is very similar than EM28174. Signed-off-by: Antti Palosaari --- drivers/media/usb/em28xx/em28xx-cards.c | 5 + drivers/media/usb/em28xx/em28xx-core.c | 9 ++--- drivers/media/usb/em28xx/em28xx-input.c | 2 ++ drivers/media/usb/em28xx/em28xx-reg.h | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index a519669..62332a6 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2968,6 +2968,11 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, dev->wait_after_write = 0; dev->eeprom_addrwidth_16bit = 1; break; + case CHIP_ID_EM28178: + chip_name = "em28178"; + dev->wait_after_write = 0; + dev->eeprom_addrwidth_16bit = 1; + break; case CHIP_ID_EM2883: chip_name = "em2882/3"; dev->wait_after_write = 0; diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index fc157af..0c5fdba 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -482,8 +482,10 @@ int em28xx_audio_setup(struct em28xx *dev) int vid1, vid2, feat, cfg; u32 vid; - if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874 - || dev->chip_id == CHIP_ID_EM28174) { + if (dev->chip_id == CHIP_ID_EM2870 || + dev->chip_id == CHIP_ID_EM2874 || + dev->chip_id == CHIP_ID_EM28174 || + dev->chip_id == CHIP_ID_EM28178) { /* Digital only device - don't load any alsa module */ dev->audio_mode.has_audio = false; dev->has_audio_class = false; @@ -606,7 +608,8 @@ int em28xx_capture_start(struct em28xx *dev, int start) if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM2884 || - dev->chip_id == CHIP_ID_EM28174) { + dev->chip_id == CHIP_ID_EM28174 || + dev->chip_id == CHIP_ID_EM28178) { /* The Transport Stream Enable Register moved in em2874 */ if (!start) { rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index ea181e4..d4a0a75 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -442,6 +442,7 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) case CHIP_ID_EM2884: case CHIP_ID_EM2874: case CHIP_ID_EM28174: + case CHIP_ID_EM28178: return em2874_ir_change_protocol(rc_dev, rc_type); default: printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", @@ -633,6 +634,7 @@ static int em28xx_ir_init(struct em28xx *dev) case CHIP_ID_EM2884: case CHIP_ID_EM2874: case CHIP_ID_EM28174: + case CHIP_ID_EM28178: ir->get_key = em2874_polling_getkey; rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | RC_BIT_RC6_0; diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 0e04778..b769ceb 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -245,6 +245,7 @@ enum em28xx_chip_id { CHIP_ID_EM2874 = 65, CHIP_ID_EM2884 = 68, CHIP_ID_EM28174 = 113, + CHIP_ID_EM28178 = 114, }; /* -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 17/18] m88ts2022: convert to Kernel I2C driver model
Convert driver from proprietary DVB driver model to standard I2C driver model. Signed-off-by: Antti Palosaari --- drivers/media/tuners/m88ts2022.c | 121 -- drivers/media/tuners/m88ts2022.h | 24 ++- drivers/media/tuners/m88ts2022_priv.h | 4 +- drivers/media/usb/em28xx/em28xx-dvb.c | 25 +++ 4 files changed, 90 insertions(+), 84 deletions(-) diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c index b11e740..1155603 100644 --- a/drivers/media/tuners/m88ts2022.c +++ b/drivers/media/tuners/m88ts2022.c @@ -32,7 +32,7 @@ static int m88ts2022_wr_regs(struct m88ts2022_priv *priv, u8 buf[MAX_WR_XFER_LEN]; struct i2c_msg msg[1] = { { - .addr = priv->cfg->i2c_addr, + .addr = priv->client->addr, .flags = 0, .len = 1 + len, .buf = buf, @@ -45,11 +45,11 @@ static int m88ts2022_wr_regs(struct m88ts2022_priv *priv, buf[0] = reg; memcpy(&buf[1], val, len); - ret = i2c_transfer(priv->i2c, msg, 1); + ret = i2c_transfer(priv->client->adapter, msg, 1); if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, + dev_warn(&priv->client->dev, "%s: i2c wr failed=%d reg=%02x len=%d\n", KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; @@ -68,12 +68,12 @@ static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg, u8 buf[MAX_RD_XFER_LEN]; struct i2c_msg msg[2] = { { - .addr = priv->cfg->i2c_addr, + .addr = priv->client->addr, .flags = 0, .len = 1, .buf = ®, }, { - .addr = priv->cfg->i2c_addr, + .addr = priv->client->addr, .flags = I2C_M_RD, .len = len, .buf = buf, @@ -83,12 +83,12 @@ static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg, if (WARN_ON(len > MAX_RD_LEN)) return -EINVAL; - ret = i2c_transfer(priv->i2c, msg, 2); + ret = i2c_transfer(priv->client->adapter, msg, 2); if (ret == 2) { memcpy(val, buf, len); ret = 0; } else { - dev_warn(&priv->i2c->dev, + dev_warn(&priv->client->dev, "%s: i2c rd failed=%d reg=%02x len=%d\n", KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; @@ -144,7 +144,7 @@ static int m88ts2022_cmd(struct dvb_frontend *fe, }; for (i = 0; i < 2; i++) { - dev_dbg(&priv->i2c->dev, + dev_dbg(&priv->client->dev, "%s: i=%d op=%02x reg=%02x mask=%02x val=%02x\n", __func__, i, op, reg, mask, val); @@ -180,14 +180,14 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28; u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min; u16 u16tmp; - dev_dbg(&priv->i2c->dev, + dev_dbg(&priv->client->dev, "%s: frequency=%d symbol_rate=%d rolloff=%d\n", __func__, c->frequency, c->symbol_rate, c->rolloff); /* * Integer-N PLL synthesizer * kHz is used for all calculations to keep calculations within 32-bit */ - f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg->clock, 1000); + f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg.clock, 1000); div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000); if (c->symbol_rate < 500) @@ -230,7 +230,7 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) if (ret) goto err; - dev_dbg(&priv->i2c->dev, + dev_dbg(&priv->client->dev, "%s: frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n", __func__, priv->frequency_khz, priv->frequency_khz - c->frequency, f_vco_khz, pll_n, @@ -374,7 +374,7 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) goto err; err: if (ret) - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret); return ret; } @@ -397,7 +397,7 @@ static int m88ts2022_init(struct dvb_frontend *fe) {0x24, 0x02}, {0x12, 0xa0}, }; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&priv->client->dev, "%s:\n", __func__); ret = m88ts2022_wr_reg(priv, 0x00, 0x01)
[PATCH REVIEW 07/18] MAINTAINERS: add M88TS2022
It is Montage M88TS2022 DVB-S/S2 silicon tuner driver. Signed-off-by: Antti Palosaari --- MAINTAINERS | 10 ++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0604247..16661e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5365,6 +5365,16 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ S: Maintained F: drivers/media/dvb-frontends/m88rs2000* +M88TS2022 MEDIA DRIVER +M: Antti Palosaari +L: linux-media@vger.kernel.org +W: http://linuxtv.org/ +W: http://palosaari.fi/linux/ +Q: http://patchwork.linuxtv.org/project/linux-media/list/ +T: git git://linuxtv.org/anttip/media_tree.git +S: Maintained +F: drivers/media/tuners/m88ts2022* + MA901 MASTERKIT USB FM RADIO DRIVER M: Alexey Klimov L: linux-media@vger.kernel.org -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 16/18] m88ds3103: I/O optimize inittab write
Write inittab using reg address auto-increment in order to reduce I/O a little bit. Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103.c | 43 +++-- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index f9d8967..76bd85a 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -157,6 +157,38 @@ static int m88ds3103_rd_reg_mask(struct m88ds3103_priv *priv, return 0; } +/* write reg val table using reg addr auto increment */ +static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv, + const struct m88ds3103_reg_val *tab, int tab_len) +{ + int ret, i, j; + u8 buf[83]; + dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len); + + if (tab_len > 83) { + ret = -EINVAL; + goto err; + } + + for (i = 0, j = 0; i < tab_len; i++, j++) { + buf[j] = tab[i].val; + + if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1 || + !((j + 1) % (priv->cfg->i2c_wr_max - 1))) { + ret = m88ds3103_wr_regs(priv, tab[i].reg - j, buf, j + 1); + if (ret) + goto err; + + j = -1; + } + } + + return 0; +err: + dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct m88ds3103_priv *priv = fe->demodulator_priv; @@ -214,7 +246,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) { struct m88ds3103_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i, len; + int ret, len; const struct m88ds3103_reg_val *init; u8 u8tmp, u8tmp1, u8tmp2; u8 buf[2]; @@ -308,12 +340,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) /* program init table */ if (c->delivery_system != priv->delivery_system) { - dev_dbg(&priv->i2c->dev, "%s: program init\n", __func__); - for (i = 0; i < len; i++) { - ret = m88ds3103_wr_reg(priv, init[i].reg, init[i].val); - if (ret) - goto err; - } + ret = m88ds3103_wr_reg_val_tab(priv, init, len); + if (ret) + goto err; } u8tmp1 = 0; /* silence compiler warning */ -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 18/18] m88ds3103: fix possible i2c deadlock
Adapter is locked by I2C core already. Use unlocked i2c_transfer() version __i2c_transfer() to avoid deadlock. Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 76bd85a..b5503ed 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1159,7 +1159,7 @@ static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) mutex_lock(&priv->i2c_mutex); /* open tuner I2C repeater for 1 xfer, closes automatically */ - ret = i2c_transfer(priv->i2c, gate_open_msg, 1); + ret = __i2c_transfer(priv->i2c, gate_open_msg, 1); if (ret != 1) { dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d\n", KBUILD_MODNAME, ret); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 06/18] MAINTAINERS: add M88DS3103
It is Montage M88DS3103 DVB-S/S2 demodulator driver. Signed-off-by: Antti Palosaari --- MAINTAINERS | 10 ++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8285ed4..0604247 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5347,6 +5347,16 @@ W: http://www.tazenda.demon.co.uk/phil/linux-hp S: Maintained F: arch/m68k/hp300/ +M88DS3103 MEDIA DRIVER +M: Antti Palosaari +L: linux-media@vger.kernel.org +W: http://linuxtv.org/ +W: http://palosaari.fi/linux/ +Q: http://patchwork.linuxtv.org/project/linux-media/list/ +T: git git://linuxtv.org/anttip/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/m88ds3103* + M88RS2000 MEDIA DRIVER M: Malcolm Priestley L: linux-media@vger.kernel.org -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 11/18] m88ds3103: use kernel macro to round division
DIV_ROUND_CLOSEST does the job and looks better. Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index e07e8d6..bd9effa 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -460,8 +460,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - u16tmp = (((c->symbol_rate / 1000) << 15) + (M88DS3103_MCLK_KHZ / 4)) / - (M88DS3103_MCLK_KHZ / 2); + u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, M88DS3103_MCLK_KHZ / 2); buf[0] = (u16tmp >> 0) & 0xff; buf[1] = (u16tmp >> 8) & 0xff; ret = m88ds3103_wr_regs(priv, 0x61, buf, 2); @@ -484,7 +483,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) (tuner_frequency - c->frequency)); s32tmp = 0x1 * (tuner_frequency - c->frequency); - s32tmp = (2 * s32tmp + M88DS3103_MCLK_KHZ) / (2 * M88DS3103_MCLK_KHZ); + s32tmp = DIV_ROUND_CLOSEST(s32tmp, M88DS3103_MCLK_KHZ); if (s32tmp < 0) s32tmp += 0x1; -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 13/18] m88ts2022: reimplement synthesizer calculations
Used synthesizer is very typical integer-N PLL, with configurable reference frequency divider, output frequency divider and of course N itself. Most common method to calculate values is first select output divider, then calculate VCO frequency and finally calculate PLL N from VCO frequency. Do it that way. Also make some cleanups for filter logic and signal strength. Signed-off-by: Antti Palosaari --- drivers/media/tuners/m88ts2022.c | 121 +-- 1 file changed, 53 insertions(+), 68 deletions(-) diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c index 4b3eec2..b11e740 100644 --- a/drivers/media/tuners/m88ts2022.c +++ b/drivers/media/tuners/m88ts2022.c @@ -175,27 +175,33 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) { struct m88ts2022_priv *priv = fe->tuner_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret = 0, div; - u8 buf[3], u8tmp, cap_code, lpf_mxdiv, div_max, div_min; - u16 N_reg, N, K; - u32 lpf_gm, lpf_coeff, gdiv28, frequency_khz, frequency_offset; - u32 freq_3db; + int ret; + unsigned int frequency_khz, frequency_offset_khz, f_3db_hz; + unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28; + u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min; + u16 u16tmp; dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d rolloff=%d\n", __func__, c->frequency, c->symbol_rate, c->rolloff); + /* +* Integer-N PLL synthesizer +* kHz is used for all calculations to keep calculations within 32-bit +*/ + f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg->clock, 1000); + div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000); if (c->symbol_rate < 500) - frequency_offset = 300; /* 3 MHz */ + frequency_offset_khz = 3000; /* 3 MHz */ else - frequency_offset = 0; + frequency_offset_khz = 0; - frequency_khz = c->frequency + (frequency_offset / 1000); + frequency_khz = c->frequency + frequency_offset_khz; if (frequency_khz < 1103000) { - div = 2; + div_out = 4; u8tmp = 0x1b; } else { - div = 1; + div_out = 2; u8tmp = 0x0b; } @@ -205,30 +211,30 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) if (ret) goto err; - K = DIV_ROUND_CLOSEST((priv->cfg->clock / 2), 100); - N = 1ul * frequency_khz * K * div * 2 / (priv->cfg->clock / 1000); - N += N % 2; + f_vco_khz = frequency_khz * div_out; + pll_n = f_vco_khz * div_ref / f_ref_khz; + pll_n += pll_n % 2; + priv->frequency_khz = pll_n * f_ref_khz / div_ref / div_out; - if (N < 4095) - N_reg = N - 1024; - else if (N < 6143) - N_reg = N + 1024; + if (pll_n < 4095) + u16tmp = pll_n - 1024; + else if (pll_n < 6143) + u16tmp = pll_n + 1024; else - N_reg = N + 3072; + u16tmp = pll_n + 3072; - buf[0] = (N_reg >> 8) & 0x3f; - buf[1] = (N_reg >> 0) & 0xff; - buf[2] = K - 8; + buf[0] = (u16tmp >> 8) & 0x3f; + buf[1] = (u16tmp >> 0) & 0xff; + buf[2] = div_ref - 8; ret = m88ts2022_wr_regs(priv, 0x01, buf, 3); if (ret) goto err; - priv->frequency_khz = 1ul * N * (priv->cfg->clock / 1000) / K / div / 2; - dev_dbg(&priv->i2c->dev, - "%s: frequency=%d offset=%d K=%d N=%d div=%d\n", + "%s: frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n", __func__, priv->frequency_khz, - priv->frequency_khz - c->frequency, K, N, div); + priv->frequency_khz - c->frequency, f_vco_khz, pll_n, + div_ref, div_out); ret = m88ts2022_cmd(fe, 0x10, 5, 0x15, 0x40, 0x00, NULL); if (ret) @@ -284,7 +290,8 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) if (ret) goto err; - gdiv28 = DIV_ROUND_CLOSEST(priv->cfg->clock / 100 * 1694, 1000); + /* filters */ + gdiv28 = DIV_ROUND_CLOSEST(f_ref_khz * 1694U, 100U); ret = m88ts2022_wr_reg(priv, 0x04, gdiv28); if (ret) @@ -309,35 +316,20 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) gdiv28 = gdiv28 * 207 / (cap_code * 2 + 151); div_max = gdiv28 * 135 / 100; div_min = gdiv28 * 78 / 100; - if (div_max > 63) - div_max = 63; - - freq_3db = 1ul * c->symbol_rate * 135 / 200 + 200; - freq_3db += frequency_offset; - if (freq_3db < 700) - freq_3db = 700; - if (f
[PATCH REVIEW 10/18] m88ds3103: use I2C mux for tuner I2C adapter
Switch standard I2C adapter to muxed I2C adapter. David reported that I2C adapter implementation caused deadlock. I discussed with Jean and he suggested to implement it as a multiplexed i2c adapter because tuner I2C bus could be seen like own I2C segment. Reported-by: David Howells Cc: Jean Delvare Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/Kconfig | 2 +- drivers/media/dvb-frontends/m88ds3103.c | 73 +++- drivers/media/dvb-frontends/m88ds3103_priv.h | 3 +- 3 files changed, 31 insertions(+), 47 deletions(-) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 6c46caf..dd12a1e 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -37,7 +37,7 @@ config DVB_STV6110x config DVB_M88DS3103 tristate "Montage M88DS3103" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && I2C_MUX default m if !MEDIA_SUBDRV_AUTOSELECT help Say Y when you want to support this frontend. diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 302c923..e07e8d6 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1108,15 +1108,16 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe, return 0; } -static u32 m88ds3103_tuner_i2c_func(struct i2c_adapter *adapter) +static void m88ds3103_release(struct dvb_frontend *fe) { - return I2C_FUNC_I2C; + struct m88ds3103_priv *priv = fe->demodulator_priv; + i2c_del_mux_adapter(priv->i2c_adapter); + kfree(priv); } -static int m88ds3103_tuner_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msg[], int num) +static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) { - struct m88ds3103_priv *priv = i2c_get_adapdata(i2c_adap); + struct m88ds3103_priv *priv = mux_priv; int ret; struct i2c_msg gate_open_msg[1] = { { @@ -1126,43 +1127,31 @@ static int m88ds3103_tuner_i2c_xfer(struct i2c_adapter *i2c_adap, .buf = "\x03\x11", } }; - dev_dbg(&priv->i2c->dev, "%s: num=%d\n", __func__, num); mutex_lock(&priv->i2c_mutex); - /* open i2c-gate */ + /* open tuner I2C repeater for 1 xfer, closes automatically */ ret = i2c_transfer(priv->i2c, gate_open_msg, 1); if (ret != 1) { - mutex_unlock(&priv->i2c_mutex); - dev_warn(&priv->i2c->dev, - "%s: i2c wr failed=%d\n", + dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d\n", KBUILD_MODNAME, ret); - ret = -EREMOTEIO; - goto err; - } + if (ret >= 0) + ret = -EREMOTEIO; - ret = i2c_transfer(priv->i2c, msg, num); - mutex_unlock(&priv->i2c_mutex); - if (ret < 0) - dev_warn(&priv->i2c->dev, "%s: i2c failed=%d\n", - KBUILD_MODNAME, ret); + return ret; + } - return ret; -err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - return ret; + return 0; } -static struct i2c_algorithm m88ds3103_tuner_i2c_algo = { - .master_xfer = m88ds3103_tuner_i2c_xfer, - .functionality = m88ds3103_tuner_i2c_func, -}; - -static void m88ds3103_release(struct dvb_frontend *fe) +static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv, + u32 chan) { - struct m88ds3103_priv *priv = fe->demodulator_priv; - i2c_del_adapter(&priv->i2c_adapter); - kfree(priv); + struct m88ds3103_priv *priv = mux_priv; + + mutex_unlock(&priv->i2c_mutex); + + return 0; } struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, @@ -1228,24 +1217,18 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, if (ret) goto err; + /* create mux i2c adapter for tuner */ + priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0, + m88ds3103_select, m88ds3103_deselect); + if (priv->i2c_adapter == NULL) + goto err; + + *tuner_i2c_adapter = priv->i2c_adapter; + /* create dvb_frontend */ memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); priv->fe.demodulator_priv = priv; - /* create i2c adapter for tuner */ - strlcpy(priv->i2c_adapter.name, KBUILD_MODNAME, - sizeof(priv->i2c_adapter.name)); - priv->i2c_adapter.algo = &m88ds3103_tuner_i2c_algo; - priv->i2c_adapter.algo_data = NULL; - i2c_set_adapdata(&priv->i2c_adapter, priv); - ret = i2c_add_adapter(&priv->i2c_adapter); - if (ret) { -
[PATCH REVIEW 04/18] Montage M88TS2022 silicon tuner driver
M88TS2022 is DVB-S/S2 RF tuner used usually in conjunction with Montage M88DS3103 DVB-S/S2 demodulator. Signed-off-by: Antti Palosaari --- drivers/media/tuners/Kconfig | 7 + drivers/media/tuners/Makefile | 1 + drivers/media/tuners/m88ts2022.c | 664 ++ drivers/media/tuners/m88ts2022.h | 72 drivers/media/tuners/m88ts2022_priv.h | 38 ++ 5 files changed, 782 insertions(+) create mode 100644 drivers/media/tuners/m88ts2022.c create mode 100644 drivers/media/tuners/m88ts2022.h create mode 100644 drivers/media/tuners/m88ts2022_priv.h diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index 15665de..ba2e365 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -215,6 +215,13 @@ config MEDIA_TUNER_FC2580 help FCI FC2580 silicon tuner driver. +config MEDIA_TUNER_M88TS2022 + tristate "Montage M88TS2022 silicon tuner" + depends on MEDIA_SUPPORT && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Montage M88TS2022 silicon tuner driver. + config MEDIA_TUNER_TUA9001 tristate "Infineon TUA 9001 silicon tuner" depends on MEDIA_SUPPORT && I2C diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile index 308f108..efe82a9 100644 --- a/drivers/media/tuners/Makefile +++ b/drivers/media/tuners/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o +obj-$(CONFIG_MEDIA_TUNER_M88TS2022) += m88ts2022.o obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c new file mode 100644 index 000..0625e36 --- /dev/null +++ b/drivers/media/tuners/m88ts2022.c @@ -0,0 +1,664 @@ +/* + * Montage M88TS2022 silicon tuner driver + * + * Copyright (C) 2013 Antti Palosaari + * + *This program is free software; you can redistribute it and/or modify + *it under the terms of the GNU General Public License as published by + *the Free Software Foundation; either version 2 of the License, or + *(at your option) any later version. + * + *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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Some calculations are taken from existing TS2020 driver. + */ + +#include "m88ts2022_priv.h" + +/* write multiple registers */ +static int m88ts2022_wr_regs(struct m88ts2022_priv *priv, + u8 reg, const u8 *val, int len) +{ + int ret; + u8 buf[1 + len]; + struct i2c_msg msg[1] = { + { + .addr = priv->cfg->i2c_addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = reg; + memcpy(&buf[1], val, len); + + ret = i2c_transfer(priv->i2c, msg, 1); + if (ret == 1) { + ret = 0; + } else { + dev_warn(&priv->i2c->dev, + "%s: i2c wr failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* read multiple registers */ +static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg, + u8 *val, int len) +{ + int ret; + u8 buf[len]; + struct i2c_msg msg[2] = { + { + .addr = priv->cfg->i2c_addr, + .flags = 0, + .len = 1, + .buf = ®, + }, { + .addr = priv->cfg->i2c_addr, + .flags = I2C_M_RD, + .len = sizeof(buf), + .buf = buf, + } + }; + + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret == 2) { + memcpy(val, buf, len); + ret = 0; + } else { + dev_warn(&priv->i2c->dev, + "%s: i2c rd failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* write single register */ +static int m88ts2022_wr_reg(struct m88ts2022_priv *priv, u8 reg, u8 val) +{ + return m88ts2022_wr_regs(priv, reg, &val,
[PATCH REVIEW 08/18] m88ts2022: do not use dynamic stack allocation
I2C transfer were using dynamic stack allocation. Get rid of it. Signed-off-by: Antti Palosaari --- drivers/media/tuners/m88ts2022.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c index 0625e36..4b3eec2 100644 --- a/drivers/media/tuners/m88ts2022.c +++ b/drivers/media/tuners/m88ts2022.c @@ -26,17 +26,22 @@ static int m88ts2022_wr_regs(struct m88ts2022_priv *priv, u8 reg, const u8 *val, int len) { +#define MAX_WR_LEN 3 +#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) int ret; - u8 buf[1 + len]; + u8 buf[MAX_WR_XFER_LEN]; struct i2c_msg msg[1] = { { .addr = priv->cfg->i2c_addr, .flags = 0, - .len = sizeof(buf), + .len = 1 + len, .buf = buf, } }; + if (WARN_ON(len > MAX_WR_LEN)) + return -EINVAL; + buf[0] = reg; memcpy(&buf[1], val, len); @@ -57,8 +62,10 @@ static int m88ts2022_wr_regs(struct m88ts2022_priv *priv, static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg, u8 *val, int len) { +#define MAX_RD_LEN 1 +#define MAX_RD_XFER_LEN (MAX_RD_LEN) int ret; - u8 buf[len]; + u8 buf[MAX_RD_XFER_LEN]; struct i2c_msg msg[2] = { { .addr = priv->cfg->i2c_addr, @@ -68,11 +75,14 @@ static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg, }, { .addr = priv->cfg->i2c_addr, .flags = I2C_M_RD, - .len = sizeof(buf), + .len = len, .buf = buf, } }; + if (WARN_ON(len > MAX_RD_LEN)) + return -EINVAL; + ret = i2c_transfer(priv->i2c, msg, 2); if (ret == 2) { memcpy(val, buf, len); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 12/18] m88ds3103: fix TS mode config
TS mode was configured wrongly. Reported-by: David Howells Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index bd9effa..f9d8967 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -321,32 +321,32 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) case M88DS3103_TS_SERIAL: u8tmp1 = 0x00; ts_clk = 0; - u8tmp = 0x04; + u8tmp = 0x46; break; case M88DS3103_TS_SERIAL_D7: u8tmp1 = 0x20; ts_clk = 0; - u8tmp = 0x04; + u8tmp = 0x46; break; case M88DS3103_TS_PARALLEL: ts_clk = 24000; - u8tmp = 0x00; + u8tmp = 0x42; break; case M88DS3103_TS_PARALLEL_12: ts_clk = 12000; - u8tmp = 0x00; + u8tmp = 0x42; break; case M88DS3103_TS_PARALLEL_16: ts_clk = 16000; - u8tmp = 0x00; + u8tmp = 0x42; break; case M88DS3103_TS_PARALLEL_19_2: ts_clk = 19200; - u8tmp = 0x00; + u8tmp = 0x42; break; case M88DS3103_TS_CI: ts_clk = 6000; - u8tmp = 0x01; + u8tmp = 0x43; break; default: dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__); @@ -355,7 +355,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } /* TS mode */ - ret = m88ds3103_wr_reg_mask(priv, 0xfd, u8tmp, 0x05); + ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp); if (ret) goto err; -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 14/18] m88ds3103: remove unneeded AGC from inittab
Optimal AGC is highly depended on used RF tuner and due to that it is already included to chip configuration. However, inittab has default AGC value, which was later replaced by one from config. Add also comment to all chip configuration options about default values and if those are needed to set or not. Reported-by: David Howells Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103.h | 14 -- drivers/media/dvb-frontends/m88ds3103_priv.h | 2 -- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h index 287d62a..eaa5d10 100644 --- a/drivers/media/dvb-frontends/m88ds3103.h +++ b/drivers/media/dvb-frontends/m88ds3103.h @@ -26,26 +26,28 @@ struct m88ds3103_config { /* * I2C address +* Default: none, must set * 0x68, ... */ u8 i2c_addr; /* * clock +* Default: none, must set * 2700 */ u32 clock; /* * max bytes I2C provider is asked to write at once -* Note: Buffer is taken from the stack currently! -* Value must be set. +* Default: none, must set * 33, 65, ... */ u16 i2c_wr_max; /* * TS output mode +* Default: M88DS3103_TS_SERIAL */ #define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */ #define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */ @@ -58,16 +60,19 @@ struct m88ds3103_config { /* * spectrum inversion +* Default: 0 */ u8 spec_inv:1; /* * AGC polarity +* Default: 0 */ u8 agc_inv:1; /* * clock output +* Default: M88DS3103_CLOCK_OUT_DISABLED */ #define M88DS3103_CLOCK_OUT_DISABLED0 #define M88DS3103_CLOCK_OUT_ENABLED 1 @@ -76,9 +81,14 @@ struct m88ds3103_config { /* * DiSEqC envelope mode +* Default: 0 */ u8 envelope_mode:1; + /* +* AGC configuration +* Default: none, must set +*/ u8 agc; }; diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 322db4d..80c5a25 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -57,7 +57,6 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs_init_reg_vals[] = { {0x30, 0x08}, {0x31, 0x40}, {0x32, 0x32}, - {0x33, 0x35}, {0x35, 0xff}, {0x3a, 0x00}, {0x37, 0x10}, @@ -139,7 +138,6 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs2_init_reg_vals[] = { {0x27, 0x31}, {0x30, 0x08}, {0x32, 0x32}, - {0x33, 0x35}, {0x35, 0xff}, {0x3a, 0x00}, {0x37, 0x10}, -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 15/18] m88ds3103: add default value for reg 56
Reg 0x56 should be programmed to 0x01. Add default to inittab. Reported-by: David Howells Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/m88ds3103_priv.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 80c5a25..9cc29b4 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -71,6 +71,7 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs_init_reg_vals[] = { {0x51, 0x36}, {0x52, 0x36}, {0x53, 0x36}, + {0x56, 0x01}, {0x63, 0x0f}, {0x64, 0x30}, {0x65, 0x40}, @@ -152,6 +153,7 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs2_init_reg_vals[] = { {0x51, 0x36}, {0x52, 0x36}, {0x53, 0x36}, + {0x56, 0x01}, {0x63, 0x0f}, {0x64, 0x10}, {0x65, 0x20}, -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 05/18] em28xx: add support for PCTV DVB-S2 Stick (461e) [2013:0258]
Device has following chips: Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293. Signed-off-by: Antti Palosaari --- drivers/media/usb/em28xx/Kconfig| 2 ++ drivers/media/usb/em28xx/em28xx-cards.c | 35 ++ drivers/media/usb/em28xx/em28xx-dvb.c | 53 + drivers/media/usb/em28xx/em28xx.h | 1 + 4 files changed, 91 insertions(+) diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index ca5ee6a..d6ba514 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig @@ -49,6 +49,8 @@ config VIDEO_EM28XX_DVB select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT + select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT ---help--- This adds support for DVB cards based on the Empiatech em28xx chips. diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 62332a6..4db5eab 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -356,6 +356,28 @@ static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { { -1, -1, -1, -1}, }; +/* + * 2013:0258 PCTV DVB-S2 Stick (461e) + * GPIO 0 = POWER_ON + * GPIO 1 = BOOST + * GPIO 2 = VUV_LNB (red LED) + * GPIO 3 = #EXT_12V + * GPIO 4 = INT_DEM + * GPIO 5 = INT_LNB + * GPIO 6 = #RESET_DEM + * GPIO 7 = P07_LED (green LED) + */ +static struct em28xx_reg_seq pctv_461e[] = { + {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff,0}, + {0x0d, 0xff, 0xff,0}, + {EM2874_R80_GPIO_P0_CTRL, 0x3f, 0xff, 100}, /* reset demod */ + {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff, 200}, /* reset demod */ + {0x0d, 0x42, 0xff,0}, + {EM2874_R80_GPIO_P0_CTRL, 0xeb, 0xff,0}, + {EM2874_R5F_TS_ENABLE, 0x84, 0x84,0}, /* parallel? | null discard */ + { -1, -1, -1, -1}, +}; + #if 0 static struct em28xx_reg_seq hauppauge_930c_gpio[] = { {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, @@ -2043,6 +2065,17 @@ struct em28xx_board em28xx_boards[] = { .tuner_gpio = default_tuner_gpio, .def_i2c_bus= 1, }, + /* 2013:0258 PCTV DVB-S2 Stick (461e) +* Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293 */ + [EM28178_BOARD_PCTV_461E] = { + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .name = "PCTV DVB-S2 Stick (461e)", + .tuner_type= TUNER_ABSENT, + .tuner_gpio= pctv_461e, + .has_dvb = 1, + .ir_codes = RC_MAP_PINNACLE_PCTV_HD, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -2208,6 +2241,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2884_BOARD_PCTV_520E }, { USB_DEVICE(0x1b80, 0xe1cc), .driver_info = EM2874_BOARD_DELOCK_61959 }, + { USB_DEVICE(0x2013, 0x0258), + .driver_info = EM28178_BOARD_PCTV_461E }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 344042b..4f8f687 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -51,6 +51,8 @@ #include "a8293.h" #include "qt1010.h" #include "mb86a20s.h" +#include "m88ds3103.h" +#include "m88ts2022.h" MODULE_DESCRIPTION("driver for em28xx based DVB cards"); MODULE_AUTHOR("Mauro Carvalho Chehab "); @@ -808,6 +810,19 @@ static struct tda18271_config c3tech_duo_tda18271_config = { .small_i2c = TDA18271_03_BYTE_CHUNK_INIT, }; +static const struct m88ds3103_config pctv_461e_m88ds3103_config = { + .i2c_addr = 0x68, + .clock = 2700, + .i2c_wr_max = 33, + .clock_out = 0, + .ts_mode = M88DS3103_TS_PARALLEL_16, + .agc = 0x99, +}; + +static const struct m88ts2022_config em28xx_m88ts2022_config = { + .i2c_addr = 0x60, + .clock = 2700, +}; /* -- */ @@ -1330,6 +1345,44 @@ static int em28xx_dvb_init(struct em28xx *dev) goto out_free; } break; + case EM28178_BOARD_PCTV_461E: + { + /* demod I2C adapter */ + struct i2c_adapter *i2c_adapter; + + /* attach demod */ + dvb->fe[0] = dvb_attach(m88ds3103_attach, +
[PATCH REVIEW 02/18] a8293: add small sleep in order to settle LNB voltage
PCTV 461e requires that small delay. Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/a8293.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c index 74fbb5d..780da58 100644 --- a/drivers/media/dvb-frontends/a8293.c +++ b/drivers/media/dvb-frontends/a8293.c @@ -96,6 +96,8 @@ static int a8293_set_voltage(struct dvb_frontend *fe, if (ret) goto err; + usleep_range(1500, 5); + return ret; err: dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH REVIEW 03/18] Montage M88DS3103 DVB-S/S2 demodulator driver
DVB-S/S2 satellite television demodulator driver. Signed-off-by: Antti Palosaari --- drivers/media/dvb-frontends/Kconfig |7 + drivers/media/dvb-frontends/Makefile |1 + drivers/media/dvb-frontends/m88ds3103.c | 1293 ++ drivers/media/dvb-frontends/m88ds3103.h | 108 +++ drivers/media/dvb-frontends/m88ds3103_priv.h | 218 + 5 files changed, 1627 insertions(+) create mode 100644 drivers/media/dvb-frontends/m88ds3103.c create mode 100644 drivers/media/dvb-frontends/m88ds3103.h create mode 100644 drivers/media/dvb-frontends/m88ds3103_priv.h diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index bddbab4..6c46caf 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -35,6 +35,13 @@ config DVB_STV6110x help A Silicon tuner that supports DVB-S and DVB-S2 modes +config DVB_M88DS3103 + tristate "Montage M88DS3103" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Say Y when you want to support this frontend. + comment "Multistandard (cable + terrestrial) frontends" depends on DVB_CORE diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index f9cb43d..0c75a6a 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_DVB_STV6110) += stv6110.o obj-$(CONFIG_DVB_STV0900) += stv0900.o obj-$(CONFIG_DVB_STV090x) += stv090x.o obj-$(CONFIG_DVB_STV6110x) += stv6110x.o +obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o obj-$(CONFIG_DVB_ISL6423) += isl6423.o obj-$(CONFIG_DVB_EC100) += ec100.o obj-$(CONFIG_DVB_HD29L2) += hd29l2.o diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c new file mode 100644 index 000..91b3729 --- /dev/null +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -0,0 +1,1293 @@ +/* + * Montage M88DS3103 demodulator driver + * + * Copyright (C) 2013 Antti Palosaari + * + *This program is free software; you can redistribute it and/or modify + *it under the terms of the GNU General Public License as published by + *the Free Software Foundation; either version 2 of the License, or + *(at your option) any later version. + * + *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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "m88ds3103_priv.h" + +static struct dvb_frontend_ops m88ds3103_ops; + +/* write multiple registers */ +static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, + u8 reg, const u8 *val, int len) +{ + int ret; + u8 buf[1 + len]; + struct i2c_msg msg[1] = { + { + .addr = priv->cfg->i2c_addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = reg; + memcpy(&buf[1], val, len); + + mutex_lock(&priv->i2c_mutex); + ret = i2c_transfer(priv->i2c, msg, 1); + mutex_unlock(&priv->i2c_mutex); + if (ret == 1) { + ret = 0; + } else { + dev_warn(&priv->i2c->dev, + "%s: i2c wr failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* read multiple registers */ +static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, + u8 reg, u8 *val, int len) +{ + int ret; + u8 buf[len]; + struct i2c_msg msg[2] = { + { + .addr = priv->cfg->i2c_addr, + .flags = 0, + .len = 1, + .buf = ®, + }, { + .addr = priv->cfg->i2c_addr, + .flags = I2C_M_RD, + .len = sizeof(buf), + .buf = buf, + } + }; + + mutex_lock(&priv->i2c_mutex); + ret = i2c_transfer(priv->i2c, msg, 2); + mutex_unlock(&priv->i2c_mutex); + if (ret == 2) { + memcpy(val, buf, len); + ret = 0; + } else { + dev_warn(&priv->i2c->dev, + "%s: i2c rd failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* write single register */ +sta
[PATCH REVIEW 00/18] M88DS3103 / M88TS2022 / PCTV 461e
I think these patches are now in a rather good shape and I will make PULL request soon. I decided to convert M88TS2022 RF tuner to Kernel I2C driver model, which is new thing as there is no any other tuner driver using that model. Testers are still wanted. Git tree is waiting for you: http://git.linuxtv.org/anttip/media_tree.git/shortlog/refs/heads/pctv_461e Antti Antti Palosaari (18): em28xx: add support for Empia EM28178 a8293: add small sleep in order to settle LNB voltage Montage M88DS3103 DVB-S/S2 demodulator driver Montage M88TS2022 silicon tuner driver em28xx: add support for PCTV DVB-S2 Stick (461e) [2013:0258] MAINTAINERS: add M88DS3103 MAINTAINERS: add M88TS2022 m88ts2022: do not use dynamic stack allocation m88ds3103: do not use dynamic stack allocation m88ds3103: use I2C mux for tuner I2C adapter m88ds3103: use kernel macro to round division m88ds3103: fix TS mode config m88ts2022: reimplement synthesizer calculations m88ds3103: remove unneeded AGC from inittab m88ds3103: add default value for reg 56 m88ds3103: I/O optimize inittab write m88ts2022: convert to Kernel I2C driver model m88ds3103: fix possible i2c deadlock MAINTAINERS | 20 + drivers/media/dvb-frontends/Kconfig |7 + drivers/media/dvb-frontends/Makefile |1 + drivers/media/dvb-frontends/a8293.c |2 + drivers/media/dvb-frontends/m88ds3103.c | 1314 ++ drivers/media/dvb-frontends/m88ds3103.h | 118 +++ drivers/media/dvb-frontends/m88ds3103_priv.h | 219 + drivers/media/tuners/Kconfig |7 + drivers/media/tuners/Makefile|1 + drivers/media/tuners/m88ts2022.c | 678 + drivers/media/tuners/m88ts2022.h | 58 ++ drivers/media/tuners/m88ts2022_priv.h| 38 + drivers/media/usb/em28xx/Kconfig |2 + drivers/media/usb/em28xx/em28xx-cards.c | 40 + drivers/media/usb/em28xx/em28xx-core.c |9 +- drivers/media/usb/em28xx/em28xx-dvb.c| 54 ++ drivers/media/usb/em28xx/em28xx-input.c |2 + drivers/media/usb/em28xx/em28xx-reg.h|1 + drivers/media/usb/em28xx/em28xx.h|1 + 19 files changed, 2569 insertions(+), 3 deletions(-) create mode 100644 drivers/media/dvb-frontends/m88ds3103.c create mode 100644 drivers/media/dvb-frontends/m88ds3103.h create mode 100644 drivers/media/dvb-frontends/m88ds3103_priv.h create mode 100644 drivers/media/tuners/m88ts2022.c create mode 100644 drivers/media/tuners/m88ts2022.h create mode 100644 drivers/media/tuners/m88ts2022_priv.h -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html