Re: [PATCH] cxd2841er: Do some changes at the dvbv5 stats logic
Hi, [auto build test WARNING on linuxtv-media/master] [also build test WARNING on v4.7-rc5 next-20160629] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Mauro-Carvalho-Chehab/cxd2841er-Do-some-changes-at-the-dvbv5-stats-logic/20160630-120109 base: git://linuxtv.org/media_tree.git master config: x86_64-acpi-redef (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): drivers/media/dvb-frontends/cxd2841er.c: In function 'cxd2841er_init_stats': >> drivers/media/dvb-frontends/cxd2841er.c:3397:1: warning: no return statement >> in function returning non-void [-Wreturn-type] } ^ vim +3397 drivers/media/dvb-frontends/cxd2841er.c 3381 dev_dbg(>i2c->dev, "%s()\n", __func__); 3382 return DVBFE_ALGO_HW; 3383 } 3384 3385 static int cxd2841er_init_stats(struct dvb_frontend *fe) 3386 { 3387 struct dtv_frontend_properties *p = >dtv_property_cache; 3388 3389 p->strength.len = 1; 3390 p->strength.stat[0].scale = FE_SCALE_RELATIVE; 3391 p->cnr.len = 1; 3392 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3393 p->block_error.len = 1; 3394 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3395 p->post_bit_error.len = 1; 3396 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; > 3397 } 3398 3399 3400 static int cxd2841er_init_s(struct dvb_frontend *fe) 3401 { 3402 struct cxd2841er_priv *priv = fe->demodulator_priv; 3403 3404 /* sanity. force demod to SHUTDOWN state */ 3405 if (priv->state == STATE_SLEEP_S) { --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
Re: [RESEND PATCH v2 1/5] ir-rx51: Fix build after multiarch changes broke it
* Ivaylo Dimitrov[160627 11:22]: > On 23.06.2016 20:48, Pali Rohár wrote: > > On Wednesday 22 June 2016 21:22:17 Ivaylo Dimitrov wrote: > > > The ir-rx51 driver for n900 has been disabled since the multiarch > > > changes as plat include directory no longer is SoC specific. > > > > > > Let's fix it with minimal changes to pass the dmtimer calls in > > > pdata. Then the following changes can be done while things can > > > be tested to be working for each change: > > > > > > 1. Change the non-pwm dmtimer to use just hrtimer if possible > > > > > > 2. Change the pwm dmtimer to use Linux PWM API with the new > > > drivers/pwm/pwm-omap-dmtimer.c and remove the direct calls > > > to dmtimer functions > > > > > > 3. Parse configuration from device tree and drop the pdata > > > > > > Note compilation of this depends on the previous patch > > > "ARM: OMAP2+: Add more functions to pwm pdata for ir-rx51". > > > > I think that this extensive description is not needed for commit > > message. Just for email discussion. > > > > I guess Tony can strip the description a bit before applying. OK I'll leave out the last paragraph as that already got merged earlier. Tony -- 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] cxd2841er: Do some changes at the dvbv5 stats logic
It is a good idea to measure the signal strength while tuning, as this helps to identify if the antenna is ok. Also, such measure helps to identify the quality of the signal. Do some changes to enable it before signal lock. While here, optimize the code to only initialize the stats length once, and make sure that, just after set_frontend, any reading for the stats that depends on lock to return FE_SCALE_NOT_AVAILABLE. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/cxd2841er.c | 45 - 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index d369a7567d18..3d39ae954fe2 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -2936,31 +2936,25 @@ static int cxd2841er_get_frontend(struct dvb_frontend *fe, else if (priv->state == STATE_ACTIVE_TC) cxd2841er_read_status_tc(fe, ); + cxd2841er_read_signal_strength(fe, ); + p->strength.stat[0].scale = FE_SCALE_RELATIVE; + p->strength.stat[0].uvalue = strength; + if (status & FE_HAS_LOCK) { - cxd2841er_read_signal_strength(fe, ); - p->strength.len = 1; - p->strength.stat[0].scale = FE_SCALE_RELATIVE; - p->strength.stat[0].uvalue = strength; cxd2841er_read_snr(fe, ); - p->cnr.len = 1; p->cnr.stat[0].scale = FE_SCALE_DECIBEL; p->cnr.stat[0].svalue = snr; + cxd2841er_read_ucblocks(fe, ); - p->block_error.len = 1; p->block_error.stat[0].scale = FE_SCALE_COUNTER; p->block_error.stat[0].uvalue = errors; + cxd2841er_read_ber(fe, ); - p->post_bit_error.len = 1; p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; p->post_bit_error.stat[0].uvalue = ber; } else { - p->strength.len = 1; - p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->cnr.len = 1; p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->block_error.len = 1; p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->post_bit_error.len = 1; p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } return 0; @@ -3021,6 +3015,12 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe) __func__, carr_offset); } done: + /* Reset stats */ + p->strength.stat[0].scale = FE_SCALE_RELATIVE; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + return ret; } @@ -3382,6 +3382,21 @@ static enum dvbfe_algo cxd2841er_get_algo(struct dvb_frontend *fe) return DVBFE_ALGO_HW; } +static int cxd2841er_init_stats(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *p = >dtv_property_cache; + + p->strength.len = 1; + p->strength.stat[0].scale = FE_SCALE_RELATIVE; + p->cnr.len = 1; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->block_error.len = 1; + p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_error.len = 1; + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +} + + static int cxd2841er_init_s(struct dvb_frontend *fe) { struct cxd2841er_priv *priv = fe->demodulator_priv; @@ -3403,6 +3418,9 @@ static int cxd2841er_init_s(struct dvb_frontend *fe) /* SONY_DEMOD_CONFIG_SAT_IFAGCNEG set to 1 */ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xb9, 0x01, 0x01); + + cxd2841er_init_stats(fe); + return 0; } @@ -3422,6 +3440,9 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe) /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x80); + + cxd2841er_init_stats(fe); + return 0; } -- 2.7.4 -- 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: ERRORS
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: Thu Jun 30 04:00:30 CEST 2016 git branch: test git hash: d81295d1bed850335f9f4ccb6b1aa4f6a123d4f0 gcc version:i686-linux-gcc (GCC) 5.3.0 sparse version: v0.5.0-56-g7647c77 smatch version: v0.5.0-3428-gdfe27cf host hardware: x86_64 host os:4.6.0-164 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-exynos: OK linux-git-arm-mtk: OK linux-git-arm-mx: OK linux-git-arm-omap: OK linux-git-arm-pxa: OK linux-git-blackfin-bf561: 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.36.4-i686: OK linux-2.6.37.6-i686: OK linux-2.6.38.8-i686: OK linux-2.6.39.4-i686: OK linux-3.0.60-i686: OK linux-3.1.10-i686: OK linux-3.2.37-i686: OK linux-3.3.8-i686: OK linux-3.4.27-i686: OK linux-3.5.7-i686: OK linux-3.6.11-i686: ERRORS linux-3.7.4-i686: ERRORS linux-3.8-i686: ERRORS linux-3.9.2-i686: ERRORS linux-3.10.1-i686: ERRORS linux-3.11.1-i686: ERRORS linux-3.12.23-i686: ERRORS linux-3.13.11-i686: ERRORS linux-3.14.9-i686: ERRORS linux-3.15.2-i686: ERRORS linux-3.16.7-i686: ERRORS linux-3.17.8-i686: ERRORS linux-3.18.7-i686: ERRORS linux-3.19-i686: ERRORS linux-4.0-i686: ERRORS linux-4.1.1-i686: ERRORS linux-4.2-i686: ERRORS linux-4.3-i686: ERRORS linux-4.4-i686: OK linux-4.5-i686: OK linux-4.6-i686: OK linux-4.7-rc1-i686: OK linux-2.6.36.4-x86_64: OK linux-2.6.37.6-x86_64: OK linux-2.6.38.8-x86_64: OK linux-2.6.39.4-x86_64: OK linux-3.0.60-x86_64: OK linux-3.1.10-x86_64: OK linux-3.2.37-x86_64: OK linux-3.3.8-x86_64: OK linux-3.4.27-x86_64: OK linux-3.5.7-x86_64: OK linux-3.6.11-x86_64: ERRORS linux-3.7.4-x86_64: ERRORS linux-3.8-x86_64: ERRORS linux-3.9.2-x86_64: ERRORS linux-3.10.1-x86_64: ERRORS linux-3.11.1-x86_64: ERRORS linux-3.12.23-x86_64: ERRORS linux-3.13.11-x86_64: ERRORS linux-3.14.9-x86_64: ERRORS linux-3.15.2-x86_64: ERRORS linux-3.16.7-x86_64: ERRORS linux-3.17.8-x86_64: ERRORS linux-3.18.7-x86_64: ERRORS linux-3.19-x86_64: ERRORS linux-4.0-x86_64: ERRORS linux-4.1.1-x86_64: ERRORS linux-4.2-x86_64: ERRORS linux-4.3-x86_64: ERRORS linux-4.4-x86_64: OK linux-4.5-x86_64: OK linux-4.6-x86_64: OK linux-4.7-rc1-x86_64: OK apps: OK spec-git: OK sparse: WARNINGS smatch: WARNINGS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Thursday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Thursday.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
Re: [PATCH 04/15] lirc_dev: replace printk with pr_* or dev_*
On Wed, 2016-06-29 at 22:20 +0900, Andi Shyti wrote: > This patch mutes also all the checkpatch warnings related to > printk. > > Reword all the printouts so that the string doesn't need to be > split, which fixes the following checkpatch warning: Adding #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt before any #include would allow these to be prefixed automatically and allow the embedded prefixes to be removed. > diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c [] > @@ -240,59 +240,51 @@ static int lirc_allocate_driver(struct lirc_driver *d) > int err; > > if (!d) { > - printk(KERN_ERR "lirc_dev: lirc_register_driver: " > - "driver pointer must be not NULL!\n"); > + pr_err("lirc_dev: driver pointer must be not NULL!\n"); > err = -EBADRQC; > goto out; > } pr_err("driver pointer must not be NULL!\n"); And typical multiple line statement alignment is to the open parenthesis. -- 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: [PATCH 15/15] include: lirc: add set length and frequency ioctl options
Hi Sean, > > For that we need to have more control on the device frequency to > > set (which is a new concept fro LIRC) and we also need to provide > > to userspace, as feedback, the values of the used frequency and > > length. > > Please can you elaborate on what exactly you mean by frequency and > length. > > The carrier frequency can already be set with LIRC_SET_SEND_CARRIER. yes, I mean carrier's frequency. I didn't understand that LIRC_SET_SEND_CARRIER was related to the frequency. > > Add the LIRC_SET_LENGTH, LIRC_GET_FREQUENCY and > > LIRC_SET_FREQUENCY ioctl commands in order to allow the above > > mentioned operations. > > You're also adding ioctls without any drivers implementing them > unless I missed something. You're right; the first idea was to submit also the device driver, but then I decided to keep it separate from this patchset. Anyway, we can drop this one (it's the last of the series) and, in case it will be needed after the above comment, I will re-send it with the driver. Thanks, Andi -- 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 3/3] rtl2832: do not allow driver unbind
Disable runtime unbind as driver does not support it. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/rtl2832.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index c16c69e..0ced01f 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -1148,6 +1148,7 @@ MODULE_DEVICE_TABLE(i2c, rtl2832_id_table); static struct i2c_driver rtl2832_driver = { .driver = { .name = "rtl2832", + .suppress_bind_attrs= true, }, .probe = rtl2832_probe, .remove = rtl2832_remove, -- http://palosaari.fi/ -- 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 1/3] rtl2830: do not allow driver unbind
Disable runtime unbind as driver does not support it. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/rtl2830.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index d25d1e0..ec1e94a 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -922,7 +922,8 @@ MODULE_DEVICE_TABLE(i2c, rtl2830_id_table); static struct i2c_driver rtl2830_driver = { .driver = { - .name = "rtl2830", + .name = "rtl2830", + .suppress_bind_attrs= true, }, .probe = rtl2830_probe, .remove = rtl2830_remove, -- http://palosaari.fi/ -- 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 2/3] rtl2830: move statistics to read_status()
Move statistics polling to read_status() in order to avoid use of kernel work. Also replace home made sign extension used for statistics with kernel sign_extend32(). Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/rtl2830.c | 200 + drivers/media/dvb-frontends/rtl2830_priv.h | 2 +- 2 files changed, 88 insertions(+), 114 deletions(-) diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index ec1e94a..8722605 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -135,8 +135,6 @@ static int rtl2830_init(struct dvb_frontend *fe) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_count.len = 1; c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - /* start statistics polling */ - schedule_delayed_work(>stat_work, msecs_to_jiffies(2000)); dev->sleeping = false; @@ -152,8 +150,6 @@ static int rtl2830_sleep(struct dvb_frontend *fe) struct rtl2830_dev *dev = i2c_get_clientdata(client); dev->sleeping = true; - /* stop statistics polling */ - cancel_delayed_work_sync(>stat_work); dev->fe_status = 0; return 0; @@ -396,8 +392,10 @@ static int rtl2830_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct rtl2830_dev *dev = i2c_get_clientdata(client); - int ret; - u8 u8tmp; + struct dtv_frontend_properties *c = >fe.dtv_property_cache; + int ret, stmp; + unsigned int utmp; + u8 u8tmp, buf[2]; *status = 0; @@ -419,6 +417,89 @@ static int rtl2830_read_status(struct dvb_frontend *fe, enum fe_status *status) dev->fe_status = *status; + /* Signal strength */ + if (dev->fe_status & FE_HAS_SIGNAL) { + /* Read IF AGC */ + ret = rtl2830_bulk_read(client, 0x359, buf, 2); + if (ret) + goto err; + + stmp = buf[0] << 8 | buf[1] << 0; + stmp = sign_extend32(stmp, 13); + utmp = clamp_val(-4 * stmp + 32767, 0x, 0x); + + dev_dbg(>dev, "IF AGC=%d\n", stmp); + + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = utmp; + } else { + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* CNR */ + if (dev->fe_status & FE_HAS_VITERBI) { + unsigned int hierarchy, constellation; + #define CONSTELLATION_NUM 3 + #define HIERARCHY_NUM 4 + static const u32 constant[CONSTELLATION_NUM][HIERARCHY_NUM] = { + {70705899, 70705899, 70705899, 70705899}, + {82433173, 82433173, 87483115, 94445660}, + {92888734, 92888734, 95487525, 99770748}, + }; + + ret = rtl2830_bulk_read(client, 0x33c, , 1); + if (ret) + goto err; + + constellation = (u8tmp >> 2) & 0x03; /* [3:2] */ + if (constellation > CONSTELLATION_NUM - 1) + goto err; + + hierarchy = (u8tmp >> 4) & 0x07; /* [6:4] */ + if (hierarchy > HIERARCHY_NUM - 1) + goto err; + + ret = rtl2830_bulk_read(client, 0x40c, buf, 2); + if (ret) + goto err; + + utmp = buf[0] << 8 | buf[1] << 0; + if (utmp) + stmp = (constant[constellation][hierarchy] - + intlog10(utmp)) / ((1 << 24) / 1); + else + stmp = 0; + + dev_dbg(>dev, "CNR raw=%u\n", utmp); + + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = stmp; + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* BER */ + if (dev->fe_status & FE_HAS_LOCK) { + ret = rtl2830_bulk_read(client, 0x34e, buf, 2); + if (ret) + goto err; + + utmp = buf[0] << 8 | buf[1] << 0; + dev->post_bit_error += utmp; + dev->post_bit_count += 100; + + dev_dbg(>dev, "BER errors=%u total=100\n", utmp); + + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue = dev->post_bit_error; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue = dev->post_bit_count; + } else { + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + return ret; err:
[PATCH 4/5] m88ds3103: use Hz instead of kHz on calculations
There was some calculations where was kHz used in order to keep calculation withing 32-bit. Convert all to Hz and use 64-bit division helpers where needed. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/m88ds3103.c | 50 ++-- drivers/media/dvb-frontends/m88ds3103_priv.h | 3 +- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index fae9251..5158bf3 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -307,7 +307,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */ u8 buf[3]; u16 u16tmp; - u32 tuner_frequency, target_mclk; + u32 tuner_frequency_khz, target_mclk; s32 s32tmp; dev_dbg(>dev, @@ -344,7 +344,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } if (fe->ops.tuner_ops.get_frequency) { - ret = fe->ops.tuner_ops.get_frequency(fe, _frequency); + ret = fe->ops.tuner_ops.get_frequency(fe, _frequency_khz); if (ret) goto err; } else { @@ -353,20 +353,20 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) * actual frequency used. Carrier offset calculation is not * valid. */ - tuner_frequency = c->frequency; + tuner_frequency_khz = c->frequency; } /* select M88RS6000 demod main mclk and ts mclk from tuner die. */ if (dev->chip_id == M88RS6000_CHIP_ID) { if (c->symbol_rate > 4501) - dev->mclk_khz = 110250; + dev->mclk = 11025; else - dev->mclk_khz = 96000; + dev->mclk = 9600; if (c->delivery_system == SYS_DVBS) - target_mclk = 96000; + target_mclk = 9600; else - target_mclk = 144000; + target_mclk = 14400; /* Enable demod clock path */ ret = regmap_write(dev->regmap, 0x06, 0x00); @@ -375,7 +375,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) usleep_range(1, 2); } else { /* set M88DS3103 mclk and ts mclk. */ - dev->mclk_khz = 96000; + dev->mclk = 9600; switch (dev->cfg->ts_mode) { case M88DS3103_TS_SERIAL: @@ -385,14 +385,14 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) case M88DS3103_TS_PARALLEL: case M88DS3103_TS_CI: if (c->delivery_system == SYS_DVBS) - target_mclk = 96000; + target_mclk = 9600; else { if (c->symbol_rate < 1800) - target_mclk = 96000; + target_mclk = 9600; else if (c->symbol_rate < 2800) - target_mclk = 144000; + target_mclk = 14400; else - target_mclk = 192000; + target_mclk = 19200; } break; default: @@ -402,15 +402,15 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } switch (target_mclk) { - case 96000: + case 9600: u8tmp1 = 0x02; /* 0b10 */ u8tmp2 = 0x01; /* 0b01 */ break; - case 144000: + case 14400: u8tmp1 = 0x00; /* 0b00 */ u8tmp2 = 0x01; /* 0b01 */ break; - case 192000: + case 19200: u8tmp1 = 0x03; /* 0b11 */ u8tmp2 = 0x00; /* 0b00 */ break; @@ -464,8 +464,8 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } if (dev->chip_id == M88RS6000_CHIP_ID) { - if ((c->delivery_system == SYS_DVBS2) - && ((c->symbol_rate / 1000) <= 5000)) { + if (c->delivery_system == SYS_DVBS2 && + c->symbol_rate <= 500) { ret = regmap_write(dev->regmap, 0xc0, 0x04); if (ret) goto err; @@ -532,7 +532,7 @@ static int m88ds3103_set_frontend(struct
[PATCH 2/5] m88ds3103: calculate DiSEqC message sending time
DiSEqC message sending takes 13.5 ms per byte, which is 54 ms total when typical 4 byte message is sent. Don't hard-code time limit to 54 ms, but calculate it. Time limit is only used to determine when to start poll "DiSEqC Tx ready" status from the chip. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/m88ds3103.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 7c19601..6f03ca8 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1116,8 +1116,9 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, #define SEND_MASTER_CMD_TIMEOUT 120 timeout = jiffies + msecs_to_jiffies(SEND_MASTER_CMD_TIMEOUT); - /* DiSEqC message typical period is 54 ms */ - usleep_range(5, 54000); + /* DiSEqC message period is 13.5 ms per byte */ + utmp = diseqc_cmd->msg_len * 13500; + usleep_range(utmp - 4000, utmp); for (utmp = 1; !time_after(jiffies, timeout) && utmp;) { ret = regmap_read(dev->regmap, 0xa1, ); -- http://palosaari.fi/ -- 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 1/5] m88ds3103: remove useless most significant bit clear
No need to clear negative msb bits as those were dropped in any case when data is written to register. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/m88ds3103.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 5557ef8..7c19601 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -605,9 +605,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) s32tmp = 0x1 * (tuner_frequency - c->frequency); s32tmp = DIV_ROUND_CLOSEST(s32tmp, dev->mclk_khz); - if (s32tmp < 0) - s32tmp += 0x1; - buf[0] = (s32tmp >> 0) & 0xff; buf[1] = (s32tmp >> 8) & 0xff; ret = regmap_bulk_write(dev->regmap, 0x5e, buf, 2); -- http://palosaari.fi/ -- 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 1/3] af9033: move statistics to read_status()
Move statistics polling to read_status() in order to avoid use of kernel work. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9033.c | 326 +-- 1 file changed, 154 insertions(+), 172 deletions(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index efebe5c..42fbd0f 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -41,7 +41,6 @@ struct af9033_dev { u64 post_bit_count; u64 error_block_count; u64 total_block_count; - struct delayed_work stat_work; }; /* write multiple registers */ @@ -468,8 +467,6 @@ static int af9033_init(struct dvb_frontend *fe) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_error.len = 1; c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - /* start statistics polling */ - schedule_delayed_work(>stat_work, msecs_to_jiffies(2000)); return 0; @@ -485,9 +482,6 @@ static int af9033_sleep(struct dvb_frontend *fe) int ret, i; u8 tmp; - /* stop statistics polling */ - cancel_delayed_work_sync(>stat_work); - ret = af9033_wr_reg(dev, 0x80004c, 1); if (ret < 0) goto err; @@ -821,36 +815,39 @@ err: static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct af9033_dev *dev = fe->demodulator_priv; - int ret; - u8 tmp; + struct dtv_frontend_properties *c = >dtv_property_cache; + int ret, i, tmp; + u8 u8tmp, buf[7]; + + dev_dbg(>client->dev, "\n"); *status = 0; /* radio channel status, 0=no result, 1=has signal, 2=no signal */ - ret = af9033_rd_reg(dev, 0x800047, ); + ret = af9033_rd_reg(dev, 0x800047, ); if (ret < 0) goto err; /* has signal */ - if (tmp == 0x01) + if (u8tmp == 0x01) *status |= FE_HAS_SIGNAL; - if (tmp != 0x02) { + if (u8tmp != 0x02) { /* TPS lock */ - ret = af9033_rd_reg_mask(dev, 0x80f5a9, , 0x01); + ret = af9033_rd_reg_mask(dev, 0x80f5a9, , 0x01); if (ret < 0) goto err; - if (tmp) + if (u8tmp) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI; /* full lock */ - ret = af9033_rd_reg_mask(dev, 0x80f999, , 0x01); + ret = af9033_rd_reg_mask(dev, 0x80f999, , 0x01); if (ret < 0) goto err; - if (tmp) + if (u8tmp) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; @@ -858,6 +855,148 @@ static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status) dev->fe_status = *status; + /* signal strength */ + if (dev->fe_status & FE_HAS_SIGNAL) { + if (dev->is_af9035) { + ret = af9033_rd_reg(dev, 0x80004a, ); + if (ret) + goto err; + tmp = -u8tmp * 1000; + } else { + ret = af9033_rd_reg(dev, 0x8000f7, ); + if (ret) + goto err; + tmp = (u8tmp - 100) * 1000; + } + + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].svalue = tmp; + } else { + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* CNR */ + if (dev->fe_status & FE_HAS_VITERBI) { + u32 snr_val, snr_lut_size; + const struct val_snr *snr_lut; + + /* read value */ + ret = af9033_rd_regs(dev, 0x80002c, buf, 3); + if (ret) + goto err; + + snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0); + + /* read superframe number */ + ret = af9033_rd_reg(dev, 0x80f78b, ); + if (ret) + goto err; + + if (u8tmp) + snr_val /= u8tmp; + + /* read current transmission mode */ + ret = af9033_rd_reg(dev, 0x80f900, ); + if (ret) + goto err; + + switch ((u8tmp >> 0) & 3) { + case 0: + snr_val *= 4; + break; + case 1: + snr_val *= 1; + break; + case 2: + snr_val
[PATCH 3/5] m88ds3103: improve ts clock setting
Simplify TS clock divider calculation and programming slightly. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/m88ds3103.c | 39 ++--- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 6f03ca8..fae9251 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -306,7 +306,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) const struct m88ds3103_reg_val *init; u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */ u8 buf[3]; - u16 u16tmp, divide_ratio = 0; + u16 u16tmp; u32 tuner_frequency, target_mclk; s32 s32tmp; @@ -522,37 +522,25 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ret = m88ds3103_update_bits(dev, 0x29, 0x20, u8tmp1); if (ret) goto err; - u8tmp1 = 0; - u8tmp2 = 0; + u16tmp = 0; + u8tmp1 = 0x3f; + u8tmp2 = 0x3f; break; default: - if (dev->cfg->ts_clk) { - divide_ratio = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk); - u8tmp1 = divide_ratio / 2; - u8tmp2 = DIV_ROUND_UP(divide_ratio, 2); - } + u16tmp = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk); + u8tmp1 = u16tmp / 2 - 1; + u8tmp2 = DIV_ROUND_UP(u16tmp, 2) - 1; } - dev_dbg(>dev, - "target_mclk=%d ts_clk=%d divide_ratio=%d\n", - target_mclk, dev->cfg->ts_clk, divide_ratio); + dev_dbg(>dev, "target_mclk=%d ts_clk=%d ts_clk_divide_ratio=%u\n", + target_mclk, dev->cfg->ts_clk, u16tmp); - u8tmp1--; - u8tmp2--; /* u8tmp1[5:2] => fe[3:0], u8tmp1[1:0] => ea[7:6] */ - u8tmp1 &= 0x3f; /* u8tmp2[5:0] => ea[5:0] */ - u8tmp2 &= 0x3f; - - ret = regmap_bulk_read(dev->regmap, 0xfe, , 1); - if (ret) - goto err; - - u8tmp = ((u8tmp & 0xf0) << 0) | u8tmp1 >> 2; - ret = regmap_write(dev->regmap, 0xfe, u8tmp); + u8tmp = (u8tmp1 >> 2) & 0x0f; + ret = regmap_update_bits(dev->regmap, 0xfe, 0x0f, u8tmp); if (ret) goto err; - u8tmp = ((u8tmp1 & 0x03) << 6) | u8tmp2 >> 0; ret = regmap_write(dev->regmap, 0xea, u8tmp); if (ret) @@ -1444,6 +1432,11 @@ static int m88ds3103_probe(struct i2c_client *client, goto err_kfree; } + if (!pdata->ts_clk) { + ret = -EINVAL; + goto err_kfree; + } + /* 0x29 register is defined differently for m88rs6000. */ /* set internal tuner address to 0x21 */ if (dev->chip_id == M88RS6000_CHIP_ID) -- http://palosaari.fi/ -- 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 3/3] it913x: do not allow driver unbind
Disable runtime unbind as driver does not support it. Signed-off-by: Antti Palosaari--- drivers/media/tuners/it913x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/tuners/it913x.c b/drivers/media/tuners/it913x.c index 5c96da6..6c3ef21 100644 --- a/drivers/media/tuners/it913x.c +++ b/drivers/media/tuners/it913x.c @@ -464,6 +464,7 @@ MODULE_DEVICE_TABLE(i2c, it913x_id_table); static struct i2c_driver it913x_driver = { .driver = { .name = "it913x", + .suppress_bind_attrs= true, }, .probe = it913x_probe, .remove = it913x_remove, -- http://palosaari.fi/ -- 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 5/5] m88ds3103: refactor firmware download
* remove some unneeded variable initialization * rename variables * use min() macro to calc max i2c xfer len * change bad firmware error code from EFAULT to EINVAL Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/m88ds3103.c | 49 +++-- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 5158bf3..e0fe5bc 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -621,10 +621,10 @@ static int m88ds3103_init(struct dvb_frontend *fe) struct m88ds3103_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = >dtv_property_cache; - int ret, len, remaining; + int ret, len, rem; unsigned int utmp; - const struct firmware *fw = NULL; - u8 *fw_file; + const struct firmware *firmware; + const char *name; dev_dbg(>dev, "\n"); @@ -650,7 +650,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) dev_dbg(>dev, "firmware=%02x\n", utmp); if (utmp) - goto skip_fw_download; + goto warm; /* global reset, global diseqc reset, golbal fec reset */ ret = regmap_write(dev->regmap, 0x07, 0xe0); @@ -665,52 +665,47 @@ static int m88ds3103_init(struct dvb_frontend *fe) m88ds3103_ops.info.name); if (dev->chip_id == M88RS6000_CHIP_ID) - fw_file = M88RS6000_FIRMWARE; + name = M88RS6000_FIRMWARE; else - fw_file = M88DS3103_FIRMWARE; + name = M88DS3103_FIRMWARE; /* request the firmware, this will block and timeout */ - ret = request_firmware(, fw_file, >dev); + ret = request_firmware(, name, >dev); if (ret) { - dev_err(>dev, "firmware file '%s' not found\n", fw_file); + dev_err(>dev, "firmware file '%s' not found\n", name); goto err; } - dev_info(>dev, "downloading firmware from file '%s'\n", -fw_file); + dev_info(>dev, "downloading firmware from file '%s'\n", name); ret = regmap_write(dev->regmap, 0xb2, 0x01); if (ret) - goto error_fw_release; - - for (remaining = fw->size; remaining > 0; - remaining -= (dev->cfg->i2c_wr_max - 1)) { - len = remaining; - if (len > (dev->cfg->i2c_wr_max - 1)) - len = (dev->cfg->i2c_wr_max - 1); + goto err_release_firmware; + for (rem = firmware->size; rem > 0; rem -= (dev->cfg->i2c_wr_max - 1)) { + len = min(dev->cfg->i2c_wr_max - 1, rem); ret = regmap_bulk_write(dev->regmap, 0xb0, - >data[fw->size - remaining], len); + >data[firmware->size - rem], + len); if (ret) { - dev_err(>dev, "firmware download failed=%d\n", + dev_err(>dev, "firmware download failed %d\n", ret); - goto error_fw_release; + goto err_release_firmware; } } ret = regmap_write(dev->regmap, 0xb2, 0x00); if (ret) - goto error_fw_release; + goto err_release_firmware; - release_firmware(fw); - fw = NULL; + release_firmware(firmware); ret = regmap_read(dev->regmap, 0xb9, ); if (ret) goto err; if (!utmp) { + ret = -EINVAL; dev_info(>dev, "firmware did not run\n"); - ret = -EFAULT; goto err; } @@ -719,7 +714,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) dev_info(>dev, "firmware version: %X.%X\n", (utmp >> 4) & 0xf, (utmp >> 0 & 0xf)); -skip_fw_download: +warm: /* warm state */ dev->warm = true; @@ -732,8 +727,8 @@ skip_fw_download: c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; return 0; -error_fw_release: - release_firmware(fw); +err_release_firmware: + release_firmware(firmware); err: dev_dbg(>dev, "failed=%d\n", ret); return ret; -- http://palosaari.fi/ -- 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 2/3] af9033: do not allow driver unbind
Disable runtime unbind as driver does not support it. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9033.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index 42fbd0f..6c2f9b8 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -1373,6 +1373,7 @@ MODULE_DEVICE_TABLE(i2c, af9033_id_table); static struct i2c_driver af9033_driver = { .driver = { .name = "af9033", + .suppress_bind_attrs= true, }, .probe = af9033_probe, .remove = af9033_remove, -- http://palosaari.fi/ -- 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 1/3] si2168: add support for newer firmwares
Si2168-B40 firmware API has changed somewhere between 4.0-11 and 4.0-19 so that sleep will lose firmware upgrade from the chip. Due to that firmware re-upload is needed when newer firmwares are used. Rewrote firmware handling logic partly at the same. Signed-off-by: Antti PalosaariCc: Olli Salonen --- drivers/media/dvb-frontends/si2168.c | 124 ++ drivers/media/dvb-frontends/si2168_priv.h | 8 +- 2 files changed, 80 insertions(+), 52 deletions(-) diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 108a069..124addc 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -357,9 +357,7 @@ static int si2168_init(struct dvb_frontend *fe) struct si2168_dev *dev = i2c_get_clientdata(client); int ret, len, remaining; const struct firmware *fw; - const char *fw_name; struct si2168_cmd cmd; - unsigned int chip_id; dev_dbg(>dev, "\n"); @@ -371,7 +369,7 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; - if (dev->fw_loaded) { + if (dev->warm) { /* resume */ memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8); cmd.wlen = 8; @@ -398,49 +396,14 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; - /* query chip revision */ - memcpy(cmd.args, "\x02", 1); - cmd.wlen = 1; - cmd.rlen = 13; - ret = si2168_cmd_execute(client, ); - if (ret) - goto err; - - chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 | - cmd.args[4] << 0; - - #define SI2168_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0) - #define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0) - #define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0) - - switch (chip_id) { - case SI2168_A20: - fw_name = SI2168_A20_FIRMWARE; - break; - case SI2168_A30: - fw_name = SI2168_A30_FIRMWARE; - break; - case SI2168_B40: - fw_name = SI2168_B40_FIRMWARE; - break; - default: - dev_err(>dev, "unknown chip version Si21%d-%c%c%c\n", - cmd.args[2], cmd.args[1], - cmd.args[3], cmd.args[4]); - ret = -EINVAL; - goto err; - } - - dev_info(>dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n", - cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]); - /* request the firmware, this will block and timeout */ - ret = request_firmware(, fw_name, >dev); + ret = request_firmware(, dev->firmware_name, >dev); if (ret) { /* fallback mechanism to handle old name for Si2168 B40 fw */ - if (chip_id == SI2168_B40) { - fw_name = SI2168_B40_FIRMWARE_FALLBACK; - ret = request_firmware(, fw_name, >dev); + if (dev->chip_id == SI2168_CHIP_ID_B40) { + dev->firmware_name = SI2168_B40_FIRMWARE_FALLBACK; + ret = request_firmware(, dev->firmware_name, + >dev); } if (ret == 0) { @@ -450,13 +413,13 @@ static int si2168_init(struct dvb_frontend *fe) } else { dev_err(>dev, "firmware file '%s' not found\n", - fw_name); + dev->firmware_name); goto err_release_firmware; } } dev_info(>dev, "downloading firmware from file '%s'\n", - fw_name); + dev->firmware_name); if ((fw->size % 17 == 0) && (fw->data[0] > 5)) { /* firmware is in the new format */ @@ -511,8 +474,11 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; - dev_info(>dev, "firmware version: %c.%c.%d\n", - cmd.args[6], cmd.args[7], cmd.args[8]); + dev->version = (cmd.args[9] + '@') << 24 | (cmd.args[6] - '0') << 16 | + (cmd.args[7] - '0') << 8 | (cmd.args[8]) << 0; + dev_info(>dev, "firmware version: %c %d.%d.%d\n", +dev->version >> 24 & 0xff, dev->version >> 16 & 0xff, +dev->version >> 8 & 0xff, dev->version >> 0 & 0xff); /* set ts mode */ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); @@ -525,7 +491,7 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; - dev->fw_loaded = true; + dev->warm = true; warm:
[PATCH 3/3] si2157: do not allow driver unbind
Disable runtime unbind as driver does not support it. Signed-off-by: Antti Palosaari--- drivers/media/tuners/si2157.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index b07a681..57b2508 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -514,7 +514,8 @@ MODULE_DEVICE_TABLE(i2c, si2157_id_table); static struct i2c_driver si2157_driver = { .driver = { - .name = "si2157", + .name= "si2157", + .suppress_bind_attrs = true, }, .probe = si2157_probe, .remove = si2157_remove, -- http://palosaari.fi/ -- 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 2/3] si2168: do not allow driver unbind
Disable runtime unbind as driver does not support it. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/si2168.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 124addc..20b4a65 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -745,7 +745,8 @@ MODULE_DEVICE_TABLE(i2c, si2168_id_table); static struct i2c_driver si2168_driver = { .driver = { - .name = "si2168", + .name= "si2168", + .suppress_bind_attrs = true, }, .probe = si2168_probe, .remove = si2168_remove, -- http://palosaari.fi/ -- 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] media: s5p-mfc fix vidioc_g_crop() to return crop info.
Fix vidioc_g_crop() to report crop information irrepective of ctx state. g_crop is expected to return crop information as long as the passed in v4l2_crop type field is vV4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE. Signed-off-by: Shuah Khan--- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index a01a373..4ace9e1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -774,12 +774,9 @@ static int vidioc_g_crop(struct file *file, void *priv, struct s5p_mfc_dev *dev = ctx->dev; u32 left, right, top, bottom; - if (ctx->state != MFCINST_HEAD_PARSED && - ctx->state != MFCINST_RUNNING && ctx->state != MFCINST_FINISHING - && ctx->state != MFCINST_FINISHED) { - mfc_err("Cannont set crop\n"); - return -EINVAL; - } + if (cr->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) { left = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_h, ctx); right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT; -- 2.7.4 -- 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: [PATCH 15/15] include: lirc: add set length and frequency ioctl options
On Wed, Jun 29, 2016 at 10:20:44PM +0900, Andi Shyti wrote: > The Lirc framework works mainly with receivers, but there is > nothing that prevents us from using it for transmitters as well. The lirc interface already provides for transmitting IR. > For that we need to have more control on the device frequency to > set (which is a new concept fro LIRC) and we also need to provide > to userspace, as feedback, the values of the used frequency and > length. Please can you elaborate on what exactly you mean by frequency and length. The carrier frequency can already be set with LIRC_SET_SEND_CARRIER. > Add the LIRC_SET_LENGTH, LIRC_GET_FREQUENCY and > LIRC_SET_FREQUENCY ioctl commands in order to allow the above > mentioned operations. You're also adding ioctls without any drivers implementing them unless I missed something. > > Signed-off-by: Andi Shyti> --- > include/uapi/linux/lirc.h | 4 > 1 file changed, 4 insertions(+) > > diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h > index 4b3ab29..94a0d8c 100644 > --- a/include/uapi/linux/lirc.h > +++ b/include/uapi/linux/lirc.h > @@ -106,6 +106,7 @@ > > /* code length in bits, currently only for LIRC_MODE_LIRCCODE */ > #define LIRC_GET_LENGTH_IOR('i', 0x000f, __u32) > +#define LIRC_SET_LENGTH_IOW('i', 0x0010, __u32) The LIRC_GET_LENGTH is specific to LIRCCODE encoding. Why are you adding it here? > > #define LIRC_SET_SEND_MODE _IOW('i', 0x0011, __u32) > #define LIRC_SET_REC_MODE _IOW('i', 0x0012, __u32) > @@ -165,4 +166,7 @@ > > #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x0023, __u32) > > +#define LIRC_GET_FREQUENCY _IOR('i', 0x0024, __u32) > +#define LIRC_SET_FREQUENCY _IOW('i', 0x0025, __u32) > + > #endif > -- > 2.8.1 > > -- > 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 -- 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 06/10] au8522: show signal strength in dBm, for devices with xc5000
Devices with xc5000 provide the signal strength value in dBm. So, provide it with the proper scale to userspace. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/au8522_dig.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index 22d837494cc7..518040228064 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -744,6 +744,15 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status) fe->ops.i2c_gate_ctrl(fe, 0); if (ret < 0) state->strength = 0; + + /* +* FIXME: As this frontend is used only with au0828, and, +* currently, the tuner is eiter xc5000 or tda18271, and +* only the first implements get_rf_strength(), we'll assume +* that the strength will be returned in dB. +*/ + c->strength.stat[0].svalue = 35000 - 1000 * (65535 - state->strength) / 256; + c->strength.stat[0].scale = FE_SCALE_DECIBEL; } else { u32 tmp; /* @@ -769,9 +778,9 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status) state->strength = 0x; else state->strength = tmp / 8960; + c->strength.stat[0].uvalue = state->strength; + c->strength.stat[0].scale = FE_SCALE_RELATIVE; } - c->strength.stat[0].scale = FE_SCALE_RELATIVE; - c->strength.stat[0].uvalue = state->strength; /* Read UCB blocks */ if (!(status & FE_HAS_LOCK)) { -- 2.7.4 -- 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 03/10] au8522: add support for dvbv5 statistics API
It is possible to provide both SNR and signal strength in dB. Let's convert it to use the DVBv5 API and start showing the SNR in dB. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/au8522_dig.c | 142 ++ drivers/media/dvb-frontends/au8522_priv.h | 5 ++ 2 files changed, 108 insertions(+), 39 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index ee14fd48c414..8a0764f605b0 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -641,9 +641,17 @@ static int au8522_set_frontend(struct dvb_frontend *fe) state->current_frequency = c->frequency; + /* Reset DVBv5 stats */ + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = 0; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + return 0; } +static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status); + static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct au8522_state *state = fe->demodulator_priv; @@ -699,6 +707,8 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) dprintk("%s() status 0x%08x\n", __func__, *status); + au8522_get_stats(fe, *status); + return 0; } @@ -764,70 +774,108 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) return ret; } -static int au8522_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) +static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status) { - u16 snr; - u32 tmp; + struct dtv_frontend_properties *c = >dtv_property_cache; + struct au8522_state *state = fe->demodulator_priv; int ret; - /* If the tuner has RF strength, use it */ + /* Get S/N ratio */ + if (status & FE_HAS_LOCK) { + ret = au8522_read_snr(fe, >snr); + if (ret < 0) { + state->snr = 0; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } else { + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = state->snr * 100; + } + } else { + state->snr = 0; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* Get (or estimate) RF strength */ if (fe->ops.tuner_ops.get_rf_strength) { + /* If the tuner has RF strength, use it */ + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - ret = fe->ops.tuner_ops.get_rf_strength(fe, signal_strength); + ret = fe->ops.tuner_ops.get_rf_strength(fe, >strength); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - return ret; - } - - /* -* If it doen't, estimate from SNR -* (borrowed from lgdt330x.c) -* -* Calculate strength from SNR up to 35dB -* Even though the SNR can go higher than 35dB, -* there is some comfort factor in having a range of -* strong signals that can show at 100% -*/ - ret = au8522_read_snr(fe, ); - - *signal_strength = 0; - - if (0 == ret) { - /* The following calculation method was chosen + if (ret < 0) + state->strength = 0; + } else { + u32 tmp; + /* +* If it doen't, estimate from SNR +* (borrowed from lgdt330x.c) +* +* Calculate strength from SNR up to 35dB +* Even though the SNR can go higher than 35dB, +* there is some comfort factor in having a range of +* strong signals that can show at 100% +* +* The following calculation method was chosen * purely for the sake of code re-use from the -* other demod drivers that use this method */ +* other demod drivers that use this method +*/ /* Convert from SNR in dB * 10 to 8.24 fixed-point */ - tmp = (snr * ((1 << 24) / 10)); + tmp = (state->snr * ((1 << 24) / 10)); /* Convert from 8.24 fixed-point to -* scale the range 0 - 35*2^24 into 0 - 65535*/ + * scale the range 0 - 35*2^24 into 0 - 65535*/ if (tmp >= 8960 * 0x1) - *signal_strength = 0x; + state->strength = 0x; else - *signal_strength = tmp / 8960; + state->strength
[PATCH 09/10] au8522/xc5000: use the new get_rf_attenuation() ops
Switch to the new get_rf_attenuation(), in order to remove some hacks at au8522. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/au8522_dig.c | 26 +++- drivers/media/tuners/xc5000.c| 42 ++-- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index 518040228064..46887cc2225b 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -734,27 +734,29 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status) } /* Get (or estimate) RF strength */ - if (fe->ops.tuner_ops.get_rf_strength) { + if (fe->ops.tuner_ops.get_rf_attenuation) { + s32 strength; + /* If the tuner has RF strength, use it */ - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - ret = fe->ops.tuner_ops.get_rf_strength(fe, >strength); + strength = fe->ops.tuner_ops.get_rf_attenuation(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - if (ret < 0) - state->strength = 0; - /* -* FIXME: As this frontend is used only with au0828, and, -* currently, the tuner is eiter xc5000 or tda18271, and -* only the first implements get_rf_strength(), we'll assume -* that the strength will be returned in dB. -*/ - c->strength.stat[0].svalue = 35000 - 1000 * (65535 - state->strength) / 256; c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].svalue = 35000 - strength; + + dprintk("Signal strength = %d.%02d dBm\n", + strength / 1000, (strength % 1000) / 10); + + + /* For DVBv3 legacy support, adjust scale */ + strength = 65535 - strength; + state->strength = (strength < 0) ? 0 : strength; } else { u32 tmp; + /* * If it doen't, estimate from SNR * (borrowed from lgdt330x.c) diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 91ad392eb60c..1eb57150b1f6 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -569,24 +569,18 @@ static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain) return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain); } -static int xc5000_get_rf_strength(struct dvb_frontend *fe, u16 *strength) +static s32 xc5000_get_rf_attenuation(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; int ret; - u16 gain = 0; - - *strength = 0; + u16 gain = 65535; ret = xc_get_totalgain(priv, ); if (ret < 0) - return ret; + return 256000; - *strength = 65535 - gain; - - dprintk(1, "Signal strength = 0x%04x (gain = 0x%04x)\n", - *strength, gain); - - return 0; + /* In theory, it will range from 256 dB to 0 dB */ + return (1000 * gain) / 256; } static u16 wait_for_lock(struct xc5000_priv *priv) @@ -1399,20 +1393,20 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { .frequency_step = 5, }, - .release = xc5000_release, - .init = xc5000_init, - .sleep = xc5000_sleep, - .suspend = xc5000_suspend, - .resume= xc5000_resume, + .release= xc5000_release, + .init = xc5000_init, + .sleep = xc5000_sleep, + .suspend= xc5000_suspend, + .resume = xc5000_resume, - .set_config= xc5000_set_config, - .set_params= xc5000_set_digital_params, - .set_analog_params = xc5000_set_analog_params, - .get_frequency = xc5000_get_frequency, - .get_if_frequency = xc5000_get_if_frequency, - .get_bandwidth = xc5000_get_bandwidth, - .get_status= xc5000_get_status, - .get_rf_strength = xc5000_get_rf_strength + .set_config = xc5000_set_config, + .set_params = xc5000_set_digital_params, + .set_analog_params = xc5000_set_analog_params, + .get_frequency = xc5000_get_frequency, + .get_if_frequency = xc5000_get_if_frequency, + .get_bandwidth = xc5000_get_bandwidth, + .get_status = xc5000_get_status, + .get_rf_attenuation = xc5000_get_rf_attenuation, }; struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the
[PATCH 10/10] lgdt3306a: better handle RF fake strength
There's a logic at lgdt3306a with emulates the signal strength via SNR measures. Such logic should be used for dvbv5 stats as well, so change the code to provide a more coherent data to userspace. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/lgdt3306a.c | 121 ++-- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 6b686c3a44ce..446dc264701a 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -65,6 +65,7 @@ struct lgdt3306a_state { enum fe_modulation current_modulation; u32 current_frequency; u32 snr; + u16 strength; }; /* @@ -1573,10 +1574,74 @@ lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state) return LG3306_UNLOCK; } + +static u16 lgdt3306a_fake_strength(struct dvb_frontend *fe) +{ + struct lgdt3306a_state *state = fe->demodulator_priv; + u16 snr; /* snr_x10 */ + int ret; + u32 ref_snr; /* snr*100 */ + u32 str; + + /* +* Calculate some sort of "strength" from SNR +*/ + + switch (state->current_modulation) { + case VSB_8: +ref_snr = 1600; /* 16dB */ +break; + case QAM_64: +ref_snr = 2200; /* 22dB */ +break; + case QAM_256: +ref_snr = 2800; /* 28dB */ +break; + default: + return 0; + } + + ret = fe->ops.read_snr(fe, ); + if (lg_chkerr(ret)) + return 0; + + if (state->snr <= (ref_snr - 100)) + str = 0; + else if (state->snr <= ref_snr) + str = (0x * 65) / 100; /* 65% */ + else { + str = state->snr - ref_snr; + str /= 50; + str += 78; /* 78%-100% */ + if (str > 100) + str = 100; + str = (0x * str) / 100; + } + + return (u16)str; +} + static void lgdt3306a_get_stats(struct dvb_frontend *fe, enum fe_status status) { struct dtv_frontend_properties *p = >dtv_property_cache; struct lgdt3306a_state *state = fe->demodulator_priv; + int ret; + + if (fe->ops.tuner_ops.get_rf_strength) { + state->strength = 0; + + ret = fe->ops.tuner_ops.get_rf_strength(fe, >strength); + if (ret == 0) + dbg_info("strength=%d\n", state->strength); + else + dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n"); + + } else { + state->strength = lgdt3306a_fake_strength(fe); + p->cnr.stat[0].scale = FE_SCALE_RELATIVE; + + dbg_info("strength=%d\n", state->strength); + } if (!(status & FE_HAS_LOCK)) return; @@ -1589,17 +1654,8 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct lgdt3306a_state *state = fe->demodulator_priv; - u16 strength = 0; int ret = 0; - if (fe->ops.tuner_ops.get_rf_strength) { - ret = fe->ops.tuner_ops.get_rf_strength(fe, ); - if (ret == 0) - dbg_info("strength=%d\n", strength); - else - dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n"); - } - *status = 0; if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) { *status |= FE_HAS_SIGNAL; @@ -1633,13 +1689,11 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, state->snr = 0; } - lgdt3306a_get_stats(fe, *status); return ret; } - static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr) { struct lgdt3306a_state *state = fe->demodulator_priv; @@ -1652,52 +1706,11 @@ static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr) static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { - /* -* Calculate some sort of "strength" from SNR -*/ struct lgdt3306a_state *state = fe->demodulator_priv; - u16 snr; /* snr_x10 */ - int ret; - u32 ref_snr; /* snr*100 */ - u32 str; - *strength = 0; + *strength = state->strength; - switch (state->current_modulation) { - case VSB_8: -ref_snr = 1600; /* 16dB */ -break; - case QAM_64: -ref_snr = 2200; /* 22dB */ -break; - case QAM_256: -ref_snr = 2800; /* 28dB */ -break; - default: - return -EINVAL; - } - - ret = fe->ops.read_snr(fe, ); - if (lg_chkerr(ret)) - goto
[PATCH 05/10] au8522: remove au8522_read_ber() ops
There's no code on au8522 to get the bit error rate. Remove the fake function that were returning the number of uncorrected error blocks as if they were ber. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/au8522_dig.c | 30 ++ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index aebee53903cc..22d837494cc7 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -787,15 +787,6 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status) c->block_error.stat[0].scale = FE_SCALE_COUNTER; c->block_error.stat[0].uvalue = state->ucblocks; } -static int au8522_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct au8522_state *state = fe->demodulator_priv; - - *signal_strength = state->strength; - - return 0; -} static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) { @@ -857,6 +848,16 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) return 0; } +static int au8522_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + struct au8522_state *state = fe->demodulator_priv; + + *signal_strength = state->strength; + + return 0; +} + static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct au8522_state *state = fe->demodulator_priv; @@ -866,16 +867,6 @@ static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct au8522_state *state = fe->demodulator_priv; - - /* FIXME: This is so wrong! */ - *ber = state->ucblocks; - - return 0; -} - static int au8522_get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *c) { @@ -987,7 +978,6 @@ static struct dvb_frontend_ops au8522_ops = { .get_frontend = au8522_get_frontend, .get_tune_settings= au8522_get_tune_settings, .read_status = au8522_read_status, - .read_ber = au8522_read_ber, .read_signal_strength = au8522_read_signal_strength, .read_snr = au8522_read_snr, .read_ucblocks= au8522_read_ucblocks, -- 2.7.4 -- 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 04/10] au8522: reorder functions to avoid a forward declaration
Move au8522_read_status() to be after au8522_get_stats(), in order to avoid the need of a forward declaration. No functional changes. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/au8522_dig.c | 122 +++ 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index 8a0764f605b0..aebee53903cc 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -650,68 +650,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe) return 0; } -static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status); - -static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 reg; - u32 tuner_status = 0; - - *status = 0; - - if (state->current_modulation == VSB_8) { - dprintk("%s() Checking VSB_8\n", __func__); - reg = au8522_readreg(state, 0x4088); - if ((reg & 0x03) == 0x03) - *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; - } else { - dprintk("%s() Checking QAM\n", __func__); - reg = au8522_readreg(state, 0x4541); - if (reg & 0x80) - *status |= FE_HAS_VITERBI; - if (reg & 0x20) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - } - - switch (state->config.status_mode) { - case AU8522_DEMODLOCKING: - dprintk("%s() DEMODLOCKING\n", __func__); - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case AU8522_TUNERLOCKING: - /* Get the tuner status */ - dprintk("%s() TUNERLOCKING\n", __func__); - if (fe->ops.tuner_ops.get_status) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.get_status(fe, _status); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (tuner_status) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - } - state->fe_status = *status; - - if (*status & FE_HAS_LOCK) - /* turn on LED, if it isn't on already */ - au8522_led_ctrl(state, -1); - else - /* turn off LED */ - au8522_led_ctrl(state, 0); - - dprintk("%s() status 0x%08x\n", __func__, *status); - - au8522_get_stats(fe, *status); - - return 0; -} - static int au8522_led_status(struct au8522_state *state, const u16 *snr) { struct au8522_led_config *led_config = state->config.led_cfg; @@ -859,6 +797,66 @@ static int au8522_read_signal_strength(struct dvb_frontend *fe, return 0; } +static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) +{ + struct au8522_state *state = fe->demodulator_priv; + u8 reg; + u32 tuner_status = 0; + + *status = 0; + + if (state->current_modulation == VSB_8) { + dprintk("%s() Checking VSB_8\n", __func__); + reg = au8522_readreg(state, 0x4088); + if ((reg & 0x03) == 0x03) + *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; + } else { + dprintk("%s() Checking QAM\n", __func__); + reg = au8522_readreg(state, 0x4541); + if (reg & 0x80) + *status |= FE_HAS_VITERBI; + if (reg & 0x20) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; + } + + switch (state->config.status_mode) { + case AU8522_DEMODLOCKING: + dprintk("%s() DEMODLOCKING\n", __func__); + if (*status & FE_HAS_VITERBI) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + case AU8522_TUNERLOCKING: + /* Get the tuner status */ + dprintk("%s() TUNERLOCKING\n", __func__); + if (fe->ops.tuner_ops.get_status) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.get_status(fe, _status); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + if (tuner_status) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + } + state->fe_status = *status; + + if (*status & FE_HAS_LOCK) + /* turn on LED, if it isn't on already */ +
[PATCH 02/10] au8522: use the RF strentgh provided by the tuner
The usage of SNR to estimate the signal strength is a poor man's approach. The best is to use the RF strength as measured by the tuner. So, use it, if available. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/au8522_dig.c | 22 ++ 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index e676b9461a59..ee14fd48c414 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -767,16 +767,30 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) static int au8522_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - /* borrowed from lgdt330x.c + u16 snr; + u32 tmp; + int ret; + + /* If the tuner has RF strength, use it */ + if (fe->ops.tuner_ops.get_rf_strength) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + ret = fe->ops.tuner_ops.get_rf_strength(fe, signal_strength); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + return ret; + } + + /* +* If it doen't, estimate from SNR +* (borrowed from lgdt330x.c) * * Calculate strength from SNR up to 35dB * Even though the SNR can go higher than 35dB, * there is some comfort factor in having a range of * strong signals that can show at 100% */ - u16 snr; - u32 tmp; - int ret = au8522_read_snr(fe, ); + ret = au8522_read_snr(fe, ); *signal_strength = 0; -- 2.7.4 -- 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 07/10] lgdt3306a: Expose SNR via dvbv5 stats
Add support for dvbv5 stats to expose the S/N ratio in decibels. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-frontends/lgdt3306a.c | 36 +++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 179c26e5eb4e..6b686c3a44ce 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -811,6 +811,7 @@ static int lgdt3306a_fe_sleep(struct dvb_frontend *fe) static int lgdt3306a_init(struct dvb_frontend *fe) { struct lgdt3306a_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = >dtv_property_cache; u8 val; int ret; @@ -962,6 +963,13 @@ static int lgdt3306a_init(struct dvb_frontend *fe) ret = lgdt3306a_sleep(state); lg_chkerr(ret); + /* Initialize DVBv5 statistics */ + p->strength.stat[0].scale = FE_SCALE_RELATIVE; + p->strength.stat[0].uvalue = 0; + p->strength.len = 1; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->cnr.len = 1; + fail: return ret; } @@ -1032,6 +1040,11 @@ static int lgdt3306a_set_parameters(struct dvb_frontend *fe) if (lg_chkerr(ret)) goto fail; + /* Reset DVBv5 stats */ + p->strength.stat[0].scale = FE_SCALE_RELATIVE; + p->strength.stat[0].uvalue = 0; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + #ifdef DBG_DUMP lgdt3306a_DumpAllRegs(state); #endif @@ -1497,6 +1510,8 @@ static u32 lgdt3306a_calculate_snr_x100(struct lgdt3306a_state *state) snr_x100 = log10_x1000((pwr * 1) / mse) - 3000; dbg_info("mse=%u, pwr=%u, snr_x100=%d\n", mse, pwr, snr_x100); + state->snr = snr_x100; + return snr_x100; } @@ -1558,6 +1573,18 @@ lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state) return LG3306_UNLOCK; } +static void lgdt3306a_get_stats(struct dvb_frontend *fe, enum fe_status status) +{ + struct dtv_frontend_properties *p = >dtv_property_cache; + struct lgdt3306a_state *state = fe->demodulator_priv; + + if (!(status & FE_HAS_LOCK)) + return; + + p->cnr.stat[0].scale = FE_SCALE_DECIBEL; + p->cnr.stat[0].svalue = state->snr * 10; +} + static int lgdt3306a_read_status(struct dvb_frontend *fe, enum fe_status *status) { @@ -1599,9 +1626,16 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, } break; default: + state->snr = 0; ret = -EINVAL; } + } else { + state->snr = 0; } + + + lgdt3306a_get_stats(fe, *status); + return ret; } @@ -1610,8 +1644,6 @@ static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr) { struct lgdt3306a_state *state = fe->demodulator_priv; - state->snr = lgdt3306a_calculate_snr_x100(state); - /* report SNR in dB * 10 */ *snr = state->snr/10; return 0; -- 2.7.4 -- 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 08/10] dvb_frontend: create a new ops to help returning signals in dB
add a new ops that will allow tuners to better report the dB level of its AGC logic to the demod drivers. As the maximum gain may vary from tuner to tuner, we'll be reversing the logic here: instead of reporting the gain, let's report the attenuation. This way, converting from it to the legacy DVBv3 way is trivial. It is also easy to adjust the level of the received signal to dBm, as it is just a matter of adding an offset at the demod and/or at the bridge driver. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/dvb-core/dvb_frontend.h | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 9592573a0b41..e8a4d341f420 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -227,8 +227,17 @@ enum dvbfe_search { * should return 0. * @get_status:returns the frontend lock status * @get_rf_strength: returns the RF signal strengh. Used mostly to support - * analog TV and radio. Digital TV should report, instead, - * via DVBv5 API (@dvb_frontend.dtv_property_cache;). + * analog TV and radio. This is deprecated, in favor of + * @get_rf_attenuation. + * @get_rf_attenuation:returns the RF signal attenuation, relative to the + * maximum supported gain, in 1/1000 dB steps. Please + * notice that 0 means that the tuner is using its maximum + * gain. So, a value of 1, for example, means a 10dB + * attenuation. This is ops is meant to be used by + * demodulator drivers to estimate the maximum signal + * strength. For that, it will add an offset, in order to + * expose the signal strength to userspace via dvbv5 + * stats, in dBm. * @get_afc: Used only by analog TV core. Reports the frequency * drift due to AFC. * @calc_regs: callback function used to pass register data settings @@ -264,6 +273,7 @@ struct dvb_tuner_ops { #define TUNER_STATUS_STEREO 2 int (*get_status)(struct dvb_frontend *fe, u32 *status); int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); + s32 (*get_rf_attenuation)(struct dvb_frontend *fe); int (*get_afc)(struct dvb_frontend *fe, s32 *afc); /* -- 2.7.4 -- 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 01/10] xc5000: add support to return RF strength
The xc5000 tuner is able to return the gain used to adjust the signal level. With that, it can return an estimation of the signal strength. So, add support for it. Signed-off-by: Mauro Carvalho Chehab--- drivers/media/tuners/xc5000.c | 28 +--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index e6e5e90d8d95..91ad392eb60c 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -569,6 +569,26 @@ static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain) return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain); } +static int xc5000_get_rf_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct xc5000_priv *priv = fe->tuner_priv; + int ret; + u16 gain = 0; + + *strength = 0; + + ret = xc_get_totalgain(priv, ); + if (ret < 0) + return ret; + + *strength = 65535 - gain; + + dprintk(1, "Signal strength = 0x%04x (gain = 0x%04x)\n", + *strength, gain); + + return 0; +} + static u16 wait_for_lock(struct xc5000_priv *priv) { u16 lock_state = 0; @@ -706,9 +726,10 @@ static void xc_debug_dump(struct xc5000_priv *priv) xc_get_analogsnr(priv, ); dprintk(1, "*** Unweighted analog SNR = %d dB\n", snr & 0x3f); + // With au0828, signal strength is given by (aprox) = 30-gain dBm xc_get_totalgain(priv, ); - dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256, - (totalgain % 256) * 100 / 256); + dprintk(1, "*** Total gain = %d.%d dB (0x%04x)\n", totalgain / 256, + (totalgain % 256) * 100 / 256, totalgain); if (priv->pll_register_no) { xc5000_readreg(priv, priv->pll_register_no, ); @@ -1390,7 +1411,8 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { .get_frequency = xc5000_get_frequency, .get_if_frequency = xc5000_get_if_frequency, .get_bandwidth = xc5000_get_bandwidth, - .get_status= xc5000_get_status + .get_status= xc5000_get_status, + .get_rf_strength = xc5000_get_rf_strength }; struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, -- 2.7.4 -- 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: [media] cec: add HDMI CEC framework (adapter)
Hello Hans Verkuil, The patch 9881fe0ca187: "[media] cec: add HDMI CEC framework (adapter)" from Jun 25, 2016, leads to the following static checker warning: drivers/staging/media/cec/cec-adap.c:1445 cec_receive_notify() error: buffer overflow 'adap->phys_addrs' 15 <= 15 drivers/staging/media/cec/cec-adap.c 1373 static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, 1374bool is_reply) 1375 { 1376 bool is_broadcast = cec_msg_is_broadcast(msg); 1377 u8 dest_laddr = cec_msg_destination(msg); 1378 u8 init_laddr = cec_msg_initiator(msg); 1379 u8 devtype = cec_log_addr2dev(adap, dest_laddr); 1380 int la_idx = cec_log_addr2idx(adap, dest_laddr); 1381 bool is_directed = la_idx >= 0; 1382 bool from_unregistered = init_laddr == 0xf; It's complaining about this. 1383 struct cec_msg tx_cec_msg = { }; 1384 1385 dprintk(1, "cec_receive_notify: %*ph\n", msg->len, msg->msg); 1386 1387 if (adap->ops->received) { 1388 /* Allow drivers to process the message first */ 1389 if (adap->ops->received(adap, msg) != -ENOMSG) 1390 return 0; 1391 } 1392 1393 /* 1394 * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and 1395 * CEC_MSG_USER_CONTROL_RELEASED messages always have to be 1396 * handled by the CEC core, even if the passthrough mode is on. 1397 * The others are just ignored if passthrough mode is on. 1398 */ 1399 switch (msg->msg[1]) { 1400 case CEC_MSG_GET_CEC_VERSION: 1401 case CEC_MSG_GIVE_DEVICE_VENDOR_ID: 1402 case CEC_MSG_ABORT: 1403 case CEC_MSG_GIVE_DEVICE_POWER_STATUS: 1404 case CEC_MSG_GIVE_PHYSICAL_ADDR: 1405 case CEC_MSG_GIVE_OSD_NAME: 1406 case CEC_MSG_GIVE_FEATURES: 1407 /* 1408 * Skip processing these messages if the passthrough mode 1409 * is on. 1410 */ 1411 if (adap->passthrough) 1412 goto skip_processing; 1413 /* Ignore if addressing is wrong */ 1414 if (is_broadcast || from_unregistered) 1415 return 0; 1416 break; 1417 1418 case CEC_MSG_USER_CONTROL_PRESSED: 1419 case CEC_MSG_USER_CONTROL_RELEASED: 1420 /* Wrong addressing mode: don't process */ 1421 if (is_broadcast || from_unregistered) 1422 goto skip_processing; 1423 break; 1424 1425 case CEC_MSG_REPORT_PHYSICAL_ADDR: 1426 /* 1427 * This message is always processed, regardless of the 1428 * passthrough setting. 1429 * 1430 * Exception: don't process if wrong addressing mode. 1431 */ 1432 if (!is_broadcast) Should this be: if (!is_broadcast || from_unregistered) ? Maybe that's not possible. 1433 goto skip_processing; 1434 break; 1435 1436 default: 1437 break; 1438 } 1439 1440 cec_msg_set_reply_to(_cec_msg, msg); 1441 1442 switch (msg->msg[1]) { 1443 /* The following messages are processed but still passed through */ 1444 case CEC_MSG_REPORT_PHYSICAL_ADDR: 1445 adap->phys_addrs[init_laddr] = Here is where the warning gets generated. We would be writing over a struct hole so it's not the end of the world I suppose. 1446 (msg->msg[2] << 8) | msg->msg[3]; 1447 dprintk(1, "Reported physical address %04x for logical address %d\n", 1448 adap->phys_addrs[init_laddr], init_laddr); 1449 break; 1450 1451 case CEC_MSG_USER_CONTROL_PRESSED: regards, dan carpenter -- 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: [PATCH 1/6] [media] s5p-mfc: set capablity bus_info as required by VIDIOC_QUERYCAP
On 06/16/2016 03:40 PM, Javier Martinez Canillas wrote: > The driver doesn't set the struct v4l2_capability bus_info field so the > v4l2-compliance tool reports the following errors for VIDIOC_QUERYCAP: > > Required ioctls: > VIDIOC_QUERYCAP returned 0 (Success) > fail: v4l2-compliance.cpp(304): string empty > fail: v4l2-compliance.cpp(528): check_ustring(vcap.bus_info, > sizeof(vcap.bus_info)) > test VIDIOC_QUERYCAP: FAIL > > This patch fixes by setting the field in VIDIOC_QUERYCAP ioctl handler: > > Required ioctls: > VIDIOC_QUERYCAP returned 0 (Success) > test VIDIOC_QUERYCAP: OK > > Signed-off-by: Javier Martinez CanillasI started making the very same changes. Looks good. Reviewed-by: Shuah Khan -- Shuah > --- > > drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 3 ++- > drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 3 ++- > 2 files changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > index f2d6376ce618..4a40df22fd63 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > @@ -267,7 +267,8 @@ static int vidioc_querycap(struct file *file, void *priv, > > strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); > strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); > - cap->bus_info[0] = 0; > + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", > + dev_name(>plat_dev->dev)); > /* >* This is only a mem-to-mem video device. The capture and output >* device capability flags are left only for backward compatibility > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > index 034b5c1d35a1..dd466ea6429e 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > @@ -945,7 +945,8 @@ static int vidioc_querycap(struct file *file, void *priv, > > strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); > strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); > - cap->bus_info[0] = 0; > + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", > + dev_name(>plat_dev->dev)); > /* >* This is only a mem-to-mem video device. The capture and output >* device capability flags are left only for backward compatibility > -- 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: [PATCH 3/6] [media] s5p-jpeg: set capablity bus_info as required by VIDIOC_QUERYCAP
On 06/16/2016 03:40 PM, Javier Martinez Canillas wrote: > The driver doesn't set the struct v4l2_capability cap_info field so the > v4l2-compliance tool reports the following errors for VIDIOC_QUERYCAP: > > Required ioctls: > VIDIOC_QUERYCAP returned 0 (Success) > fail: v4l2-compliance.cpp(304): string empty > fail: v4l2-compliance.cpp(528): check_ustring(vcap.bus_info, > sizeof(vcap.bus_info)) > test VIDIOC_QUERYCAP: FAIL > > This patch fixes by setting the field in VIDIOC_QUERYCAP ioctl handler: > > Required ioctls: > VIDIOC_QUERYCAP returned 0 (Success) > test VIDIOC_QUERYCAP: OK > > Signed-off-by: Javier Martinez Canillas> --- > > drivers/media/platform/s5p-jpeg/jpeg-core.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c > b/drivers/media/platform/s5p-jpeg/jpeg-core.c > index 17bc94092864..e3ff3d4bd72e 100644 > --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c > +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c > @@ -1256,7 +1256,8 @@ static int s5p_jpeg_querycap(struct file *file, void > *priv, > strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder", > sizeof(cap->card)); > } > - cap->bus_info[0] = 0; > + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", > + dev_name(ctx->jpeg->dev)); > cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; > cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; > return 0; > Looks good. Reviewed-by: Shuah Khan -- Shuah -- 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: [PATCH 2/6] [media] s5p-mfc: improve v4l2_capability driver and card fields
On 06/16/2016 03:40 PM, Javier Martinez Canillas wrote: > According to the V4L2 documentation the driver and card fields should be > used to identify the driver and the device but the s5p-mfc driver fills > those field using the platform device name, which in turn is the name of > the device DT node. > > So not only the filled information isn't correct but also the same values > are used in all the fields for both the encoder and decoder video devices. > > Before this patch: > > Driver Info (not using libv4l2): > Driver name : 1100.codec > Card type : 1100.codec > Bus info : platform:1100.codec > Driver version: 4.7.0 > > Driver Info (not using libv4l2): > Driver name : 1100.codec > Card type : 1100.codec > Bus info : platform:1100.codec > Driver version: 4.7.0 > > After this patch: > > Driver Info (not using libv4l2): > Driver name : s5p-mfc > Card type : s5p-mfc-dec > Bus info : platform:1100.codec > Driver version: 4.7.0 > > Driver Info (not using libv4l2): > Driver name : s5p-mfc > Card type : s5p-mfc-enc > Bus info : platform:1100.codec > Driver version: 4.7.0 > > Signed-off-by: Javier Martinez CanillasLooks good. Reviewed-by: Shuah Khan -- Shuah > --- > > drivers/media/platform/s5p-mfc/s5p_mfc.c| 1 - > drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 2 ++ > drivers/media/platform/s5p-mfc/s5p_mfc_dec.c| 4 ++-- > drivers/media/platform/s5p-mfc/s5p_mfc_enc.c| 4 ++-- > 4 files changed, 6 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c > b/drivers/media/platform/s5p-mfc/s5p_mfc.c > index 6ee620ee8cd5..a936f89fa54a 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c > @@ -35,7 +35,6 @@ > #include "s5p_mfc_cmd.h" > #include "s5p_mfc_pm.h" > > -#define S5P_MFC_NAME "s5p-mfc" > #define S5P_MFC_DEC_NAME "s5p-mfc-dec" > #define S5P_MFC_ENC_NAME "s5p-mfc-enc" > > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > index 9eb2481ec292..a10dcd244ff0 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > @@ -25,6 +25,8 @@ > #include "regs-mfc.h" > #include "regs-mfc-v8.h" > > +#define S5P_MFC_NAME "s5p-mfc" > + > /* Definitions related to MFC memory */ > > /* Offset base used to differentiate between CAPTURE and OUTPUT > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > index 4a40df22fd63..5793b0d8ee0c 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c > @@ -265,8 +265,8 @@ static int vidioc_querycap(struct file *file, void *priv, > { > struct s5p_mfc_dev *dev = video_drvdata(file); > > - strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); > - strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); > + strncpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver) - 1); > + strncpy(cap->card, dev->vfd_dec->name, sizeof(cap->card) - 1); > snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", >dev_name(>plat_dev->dev)); > /* > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > index dd466ea6429e..1220559d4874 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > @@ -943,8 +943,8 @@ static int vidioc_querycap(struct file *file, void *priv, > { > struct s5p_mfc_dev *dev = video_drvdata(file); > > - strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); > - strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); > + strncpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver) - 1); > + strncpy(cap->card, dev->vfd_enc->name, sizeof(cap->card) - 1); > snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", >dev_name(>plat_dev->dev)); > /* > -- 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: [PATCH 4/6] [media] s5p-jpeg: only fill driver's name in capabilities driver field
On 06/16/2016 03:40 PM, Javier Martinez Canillas wrote: > The driver fills in both the struct v4l2_capability driver and card fields > the same values, that is the driver's name plus the information if the dev > is a decoder or an encoder. > > But the driver field has a fixed length of 16 bytes so the filled data is > truncated: > > Driver Info (not using libv4l2): > Driver name : s5p-jpeg decode > Card type : s5p-jpeg decoder > Bus info : platform:11f5.jpeg > Driver version: 4.7.0 > > Also, this field should only contain the driver's name so use just that. > The information if the device is a decoder or an encoder is in the card > type field anyways. > > Signed-off-by: Javier Martinez Canillas> --- > > drivers/media/platform/s5p-jpeg/jpeg-core.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c > b/drivers/media/platform/s5p-jpeg/jpeg-core.c > index e3ff3d4bd72e..f9fb52a53e79 100644 > --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c > +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c > @@ -1246,12 +1246,12 @@ static int s5p_jpeg_querycap(struct file *file, void > *priv, > struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); > > if (ctx->mode == S5P_JPEG_ENCODE) { > - strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder", > + strlcpy(cap->driver, S5P_JPEG_M2M_NAME, > sizeof(cap->driver)); > strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder", > sizeof(cap->card)); > } else { > - strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder", > + strlcpy(cap->driver, S5P_JPEG_M2M_NAME, > sizeof(cap->driver)); > strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder", > sizeof(cap->card)); > Looks good. Reviewed-by: Shuah Khan -- Shuah -- 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 2/3] [media] cec: add MEDIA_SUPPORT dependency
The MEDIA_CEC_EDID option is guarded by MEDIA_SUPPORT, so selecting it from MEDIA_CEC produces a warning: warning: (MEDIA_CEC) selects MEDIA_CEC_EDID which has unmet direct dependencies (MEDIA_SUPPORT) The warning is harmless, but it's better to add an explicit dependency to shut it up, to reduce the noise during randconfig builds. Signed-off-by: Arnd BergmannFixes: ca684386e6e2 ("[media] cec: add HDMI CEC framework (api)") --- drivers/staging/media/cec/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/cec/Kconfig b/drivers/staging/media/cec/Kconfig index 8a7aceeac815..cd523590ea6f 100644 --- a/drivers/staging/media/cec/Kconfig +++ b/drivers/staging/media/cec/Kconfig @@ -1,5 +1,6 @@ config MEDIA_CEC tristate "CEC API (EXPERIMENTAL)" + depends on MEDIA_SUPPORT select MEDIA_CEC_EDID ---help--- Enable the CEC API. -- 2.9.0 -- 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 3/3] [media] cec: add RC_CORE dependency
We cannot build the cec driver when the RC core is a module and cec is built-in: drivers/staging/built-in.o: In function `cec_allocate_adapter': :(.text+0x134): undefined reference to `rc_allocate_device' drivers/staging/built-in.o: In function `cec_register_adapter': :(.text+0x304): undefined reference to `rc_register_device' This adds an explicit dependency to avoid this case. We still allow building when CONFIG_RC_CORE is disabled completely, as the driver has checks for this case itself. Signed-off-by: Arnd Bergmann--- drivers/staging/media/cec/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/cec/Kconfig b/drivers/staging/media/cec/Kconfig index cd523590ea6f..b83b4d83946d 100644 --- a/drivers/staging/media/cec/Kconfig +++ b/drivers/staging/media/cec/Kconfig @@ -1,6 +1,7 @@ config MEDIA_CEC tristate "CEC API (EXPERIMENTAL)" depends on MEDIA_SUPPORT + depends on RC_CORE || !RC_CORE select MEDIA_CEC_EDID ---help--- Enable the CEC API. -- 2.9.0 -- 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 1/3] [media] s5p_cec: mark suspend/resume as __maybe_unused
The suspend/resume functions in the s5p-cec driver are only referenced when CONFIG_PM is enabled, so we get a warning about unused functions otherwise: drivers/staging/media/s5p-cec/s5p_cec.c:260:12: error: 's5p_cec_resume' defined but not used [-Werror=unused-function] static int s5p_cec_resume(struct device *dev) ^~ drivers/staging/media/s5p-cec/s5p_cec.c:253:12: error: 's5p_cec_suspend' defined but not used [-Werror=unused-function] static int s5p_cec_suspend(struct device *dev) This marks them as __maybe_unused to avoid the warning without having to introduce an extra #ifdef. Signed-off-by: Arnd Bergmann--- drivers/staging/media/s5p-cec/s5p_cec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index f90b7c4e48fe..78333273c4e5 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -250,14 +250,14 @@ static int s5p_cec_runtime_resume(struct device *dev) return 0; } -static int s5p_cec_suspend(struct device *dev) +static int __maybe_unused s5p_cec_suspend(struct device *dev) { if (pm_runtime_suspended(dev)) return 0; return s5p_cec_runtime_suspend(dev); } -static int s5p_cec_resume(struct device *dev) +static int __maybe_unused s5p_cec_resume(struct device *dev) { if (pm_runtime_suspended(dev)) return 0; -- 2.9.0 -- 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 04/15] lirc_dev: replace printk with pr_* or dev_*
This patch mutes also all the checkpatch warnings related to printk. Reword all the printouts so that the string doesn't need to be split, which fixes the following checkpatch warning: WARNING: quoted string split across lines Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 76 +++-- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index ee997ab..b11ab5c 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -240,59 +240,51 @@ static int lirc_allocate_driver(struct lirc_driver *d) int err; if (!d) { - printk(KERN_ERR "lirc_dev: lirc_register_driver: " - "driver pointer must be not NULL!\n"); + pr_err("lirc_dev: driver pointer must be not NULL!\n"); err = -EBADRQC; goto out; } if (!d->dev) { - printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__); + pr_err("%s: dev pointer not filled in!\n", __func__); err = -EINVAL; goto out; } if (MAX_IRCTL_DEVICES <= d->minor) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "\"minor\" must be between 0 and %d (%d)!\n", - MAX_IRCTL_DEVICES - 1, d->minor); + dev_err(d->dev, "minor must be between 0 and %d!\n", + MAX_IRCTL_DEVICES - 1); err = -EBADRQC; goto out; } if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "code length in bits for minor (%d) " - "must be less than %d!\n", - d->minor, BUFLEN * 8); + dev_err(d->dev, "code length must be less than %d bits\n", + BUFLEN * 8); err = -EBADRQC; goto out; } if (d->sample_rate) { if (2 > d->sample_rate || HZ < d->sample_rate) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "sample_rate must be between 2 and %d!\n", HZ); + dev_err(d->dev, "invalid %d sample rate\n", + d->sample_rate); err = -EBADRQC; goto out; } if (!d->add_to_buf) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "add_to_buf cannot be NULL when " - "sample_rate is set\n"); + dev_err(d->dev, "add_to_buf not set\n"); err = -EBADRQC; goto out; } } else if (!(d->fops && d->fops->read) && !d->rbuf) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "fops->read and rbuf cannot all be NULL!\n"); + dev_err(d->dev, "fops->read and rbuf are NULL!\n"); err = -EBADRQC; goto out; } else if (!d->rbuf) { if (!(d->fops && d->fops->read && d->fops->poll && d->fops->unlocked_ioctl)) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "neither read, poll nor unlocked_ioctl can be NULL!\n"); + dev_err(d->dev, "undefined read, poll, ioctl\n"); err = -EBADRQC; goto out; } @@ -308,14 +300,12 @@ static int lirc_allocate_driver(struct lirc_driver *d) if (!irctls[minor]) break; if (MAX_IRCTL_DEVICES == minor) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "no free slots for drivers!\n"); + dev_err(d->dev, "no free slots for drivers!\n"); err = -ENOMEM; goto out_lock; } } else if (irctls[minor]) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "minor (%d) just registered!\n", minor); + dev_err(d->dev, "minor (%d) just registered!\n", minor); err = -EBUSY; goto out_lock; } @@ -352,9 +342,8 @@ static int lirc_allocate_driver(struct lirc_driver *d) /* try to fire up polling thread */ ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); if (IS_ERR(ir->task)) { - dev_err(d->dev, "lirc_dev:
[PATCH 05/15] lirc_dev: simplify goto paths
The code can be rearranged so that some goto paths can be removed Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 34 -- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index b11ab5c..400ab80 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -241,52 +241,44 @@ static int lirc_allocate_driver(struct lirc_driver *d) if (!d) { pr_err("lirc_dev: driver pointer must be not NULL!\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (!d->dev) { pr_err("%s: dev pointer not filled in!\n", __func__); - err = -EINVAL; - goto out; + return -EINVAL; } if (MAX_IRCTL_DEVICES <= d->minor) { dev_err(d->dev, "minor must be between 0 and %d!\n", MAX_IRCTL_DEVICES - 1); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { dev_err(d->dev, "code length must be less than %d bits\n", BUFLEN * 8); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (d->sample_rate) { if (2 > d->sample_rate || HZ < d->sample_rate) { dev_err(d->dev, "invalid %d sample rate\n", d->sample_rate); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (!d->add_to_buf) { dev_err(d->dev, "add_to_buf not set\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } } else if (!(d->fops && d->fops->read) && !d->rbuf) { dev_err(d->dev, "fops->read and rbuf are NULL!\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } else if (!d->rbuf) { if (!(d->fops && d->fops->read && d->fops->poll && d->fops->unlocked_ioctl)) { dev_err(d->dev, "undefined read, poll, ioctl\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } } @@ -364,7 +356,7 @@ out_sysfs: device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); out_lock: mutex_unlock(_dev_lock); -out: + return err; } @@ -793,9 +785,8 @@ static int __init lirc_dev_init(void) lirc_class = class_create(THIS_MODULE, "lirc"); if (IS_ERR(lirc_class)) { - retval = PTR_ERR(lirc_class); pr_err("lirc_dev: class_create failed\n"); - goto error; + return PTR_ERR(lirc_class); } retval = alloc_chrdev_region(_base_dev, 0, MAX_IRCTL_DEVICES, @@ -803,15 +794,14 @@ static int __init lirc_dev_init(void) if (retval) { class_destroy(lirc_class); pr_err("lirc_dev: alloc_chrdev_region failed\n"); - goto error; + return retval; } pr_info("lirc_dev: IR Remote Control driver registered, major %d\n", MAJOR(lirc_base_dev)); -error: - return retval; + return 0; } -- 2.8.1 -- 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 11/15] lirc_dev: fix variable constant comparisons
When comparing a variable with a constant, the comparison should start from the variable and not from the constant. It's also written in the human DNA. Swap the terms of comparisons whenever the constant comes first and fix the following checkpatch warning: WARNING: Comparisons should place the constant on the right side of the test Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index c11cfc0..7e5cb85 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -245,13 +245,13 @@ static int lirc_allocate_driver(struct lirc_driver *d) return -EINVAL; } - if (MAX_IRCTL_DEVICES <= d->minor) { + if (d->minor >= MAX_IRCTL_DEVICES) { dev_err(d->dev, "minor must be between 0 and %d!\n", MAX_IRCTL_DEVICES - 1); return -EBADRQC; } - if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { + if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) { dev_err(d->dev, "code length must be less than %d bits\n", BUFLEN * 8); return -EBADRQC; @@ -282,7 +282,7 @@ static int lirc_allocate_driver(struct lirc_driver *d) for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) if (!irctls[minor]) break; - if (MAX_IRCTL_DEVICES == minor) { + if (minor == MAX_IRCTL_DEVICES) { dev_err(d->dev, "no free slots for drivers!\n"); err = -ENOMEM; goto out_lock; -- 2.8.1 -- 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 01/15] lirc_dev: place buffer allocation on separate function
During the driver registration, move the buffer allocation on a separate function. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 57 +++-- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 92ae190..5716978 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -203,13 +203,41 @@ err_out: return retval; } -int lirc_register_driver(struct lirc_driver *d) +static int lirc_allocate_buffer(struct irctl *ir) { - struct irctl *ir; - int minor; + int err; int bytes_in_key; unsigned int chunk_size; unsigned int buffer_size; + struct lirc_driver *d = >d; + + bytes_in_key = BITS_TO_LONGS(d->code_length) + + (d->code_length % 8 ? 1 : 0); + buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; + chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; + + if (d->rbuf) { + ir->buf = d->rbuf; + } else { + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!ir->buf) + return -ENOMEM; + + err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); + if (err) { + kfree(ir->buf); + return err; + } + } + ir->chunk_size = ir->buf->chunk_size; + + return 0; +} + +int lirc_register_driver(struct lirc_driver *d) +{ + struct irctl *ir; + int minor; int err; if (!d) { @@ -314,26 +342,9 @@ int lirc_register_driver(struct lirc_driver *d) /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; - bytes_in_key = BITS_TO_LONGS(d->code_length) + - (d->code_length % 8 ? 1 : 0); - buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; - chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; - - if (d->rbuf) { - ir->buf = d->rbuf; - } else { - ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!ir->buf) { - err = -ENOMEM; - goto out_lock; - } - err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); - if (err) { - kfree(ir->buf); - goto out_lock; - } - } - ir->chunk_size = ir->buf->chunk_size; + err = lirc_allocate_buffer(ir); + if (err) + goto out_lock; if (d->features == 0) d->features = LIRC_CAN_REC_LIRCCODE; -- 2.8.1 -- 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 00/15] lirc_dev fixes and beautification
Hi, because I wanted to add three ioctl commands in lirc, I ended up with the patchset below. This is a collection of fixes, added functionality, coding rework and trivial coding style fixes. The first patch is preparatory to the second, which allows the user to create a lirc driver without receiver buffer, which is obvious for transmitters. Besides, even though that buffer could have been used also by transmitters, drivers might have the need to handle it separately. The rest of the patches is a series of coding style and code rework, as I said, some of them are very trivial, but I sent them anyway because I was on fire. Patch 14 is a segfault fix, while the last patch adds the possibility to send to ioctl the set frequency, get frequency and set length command. Thanks, Andi Andi Shyti (15): lirc_dev: place buffer allocation on separate function lirc_dev: allow bufferless driver registration lirc_dev: remove unnecessary debug prints lirc_dev: replace printk with pr_* or dev_* lirc_dev: simplify goto paths lirc_dev: do not use goto to create loops lirc_dev: simplify if statement in lirc_add_to_buf lirc_dev: remove double if ... else statement lirc_dev: merge three if statements in only one lirc_dev: remove CONFIG_COMPAT precompiler check lirc_dev: fix variable constant comparisons lirc_dev: fix error return value lirc_dev: extremely trivial comment style fix lirc_dev: fix potential segfault include: lirc: add set length and frequency ioctl options drivers/media/rc/lirc_dev.c | 297 +--- include/media/lirc_dev.h| 12 ++ include/uapi/linux/lirc.h | 4 + 3 files changed, 156 insertions(+), 157 deletions(-) -- 2.8.1 -- 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 02/15] lirc_dev: allow bufferless driver registration
Some drivers don't necessarily need to have a FIFO managed buffer for their transfers. Drivers now should call lirc_register_bufferless_driver in order to handle the buffer themselves. The function works exaclty like lirc_register_driver except of the buffer allocation. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 44 ++-- include/media/lirc_dev.h| 12 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 5716978..fa562a3 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -205,12 +205,14 @@ err_out: static int lirc_allocate_buffer(struct irctl *ir) { - int err; + int err = 0; int bytes_in_key; unsigned int chunk_size; unsigned int buffer_size; struct lirc_driver *d = >d; + mutex_lock(_dev_lock); + bytes_in_key = BITS_TO_LONGS(d->code_length) + (d->code_length % 8 ? 1 : 0); buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; @@ -220,21 +222,26 @@ static int lirc_allocate_buffer(struct irctl *ir) ir->buf = d->rbuf; } else { ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!ir->buf) - return -ENOMEM; + if (!ir->buf) { + err = -ENOMEM; + goto out; + } err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); if (err) { kfree(ir->buf); - return err; + goto out; } } ir->chunk_size = ir->buf->chunk_size; - return 0; +out: + mutex_unlock(_dev_lock); + + return err; } -int lirc_register_driver(struct lirc_driver *d) +static int lirc_allocate_driver(struct lirc_driver *d) { struct irctl *ir; int minor; @@ -342,10 +349,6 @@ int lirc_register_driver(struct lirc_driver *d) /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; - err = lirc_allocate_buffer(ir); - if (err) - goto out_lock; - if (d->features == 0) d->features = LIRC_CAN_REC_LIRCCODE; @@ -385,8 +388,29 @@ out_lock: out: return err; } + +int lirc_register_driver(struct lirc_driver *d) +{ + int err, minor; + + minor = lirc_allocate_driver(d); + if (minor < 0) + return minor; + + err = lirc_allocate_buffer(irctls[minor]); + if (err) + lirc_unregister_driver(minor); + + return err ? err : minor; +} EXPORT_SYMBOL(lirc_register_driver); +int lirc_register_bufferless_driver(struct lirc_driver *d) +{ + return lirc_allocate_driver(d); +} +EXPORT_SYMBOL(lirc_register_bufferless_driver); + int lirc_unregister_driver(int minor) { struct irctl *ir; diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index 0ab59a5..8bed57a 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h @@ -214,6 +214,18 @@ struct lirc_driver { */ extern int lirc_register_driver(struct lirc_driver *d); +/* int lirc_register_bufferless_driver - allocates a lirc bufferless driver + * @d: reference to the lirc_driver to initialize + * + * The difference between lirc_register_driver and + * lirc_register_bufferless_driver is that the latter doesn't allocate any + * buffer, which means that the driver using the lirc_driver should take care of + * it by itself. + * + * returns 0 on success or a the negative errno number in case of failure. + */ +extern int lirc_register_bufferless_driver(struct lirc_driver *d); + /* returns negative value on error or 0 if success */ extern int lirc_unregister_driver(int minor); -- 2.8.1 -- 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 13/15] lirc_dev: extremely trivial comment style fix
Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 6f3402c..0a3d65d 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -692,7 +692,8 @@ ssize_t lirc_dev_fop_read(struct file *file, /* According to the read(2) man page, 'written' can be * returned as less than 'length', instead of blocking * again, returning -EWOULDBLOCK, or returning -* -ERESTARTSYS */ +* -ERESTARTSYS +*/ if (written) break; if (file->f_flags & O_NONBLOCK) { -- 2.8.1 -- 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 06/15] lirc_dev: do not use goto to create loops
... use "do .. while" instead. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 400ab80..cc00b9a 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -103,12 +103,11 @@ static int lirc_add_to_buf(struct irctl *ir) * service the device as long as it is returning * data and we have space */ -get_data: - res = ir->d.add_to_buf(ir->d.data, ir->buf); - if (res == 0) { - got_data++; - goto get_data; - } + do { + res = ir->d.add_to_buf(ir->d.data, ir->buf); + if (!res) + got_data++; + } while (!res); if (res == -ENODEV) kthread_stop(ir->task); -- 2.8.1 -- 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 03/15] lirc_dev: remove unnecessary debug prints
Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 25 - 1 file changed, 25 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index fa562a3..ee997ab 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -80,8 +80,6 @@ static void lirc_irctl_init(struct irctl *ir) static void lirc_irctl_cleanup(struct irctl *ir) { - dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); - device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); if (ir->buf != ir->d.rbuf) { @@ -127,9 +125,6 @@ static int lirc_thread(void *irctl) { struct irctl *ir = irctl; - dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n", - ir->d.name, ir->d.minor); - do { if (ir->open) { if (ir->jiffies_to_wait) { @@ -146,9 +141,6 @@ static int lirc_thread(void *irctl) } } while (!kthread_should_stop()); - dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n", - ir->d.name, ir->d.minor); - return 0; } @@ -277,8 +269,6 @@ static int lirc_allocate_driver(struct lirc_driver *d) goto out; } - dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n", - d->sample_rate); if (d->sample_rate) { if (2 > d->sample_rate || HZ < d->sample_rate) { dev_err(d->dev, "lirc_dev: lirc_register_driver: " @@ -525,10 +515,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) } error: - if (ir) - dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n", - ir->d.name, ir->d.minor, retval); - mutex_unlock(_dev_lock); nonseekable_open(inode, file); @@ -550,8 +536,6 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) cdev = ir->cdev; - dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); - ret = mutex_lock_killable(_dev_lock); WARN_ON(ret); @@ -586,8 +570,6 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) return POLLERR; } - dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); - if (!ir->attached) return POLLERR; @@ -683,9 +665,6 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) result = -EINVAL; } - dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n", - ir->d.name, ir->d.minor, result); - mutex_unlock(>irctl_lock); return result; @@ -790,8 +769,6 @@ out_locked: out_unlocked: kfree(buf); - dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", - ir->d.name, ir->d.minor, ret ? "" : "", ret); return ret ? ret : written; } @@ -814,8 +791,6 @@ ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer, return -ENODEV; } - dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); - if (!ir->attached) return -ENODEV; -- 2.8.1 -- 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 07/15] lirc_dev: simplify if statement in lirc_add_to_buf
The whole function is inside an 'if' statement ("if (ir->d.add_to_buf)"). Check the opposite of that statement at the beginning and exit, this way we can have one level less of indentation. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 33 - 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index cc00b9a..d63ff85 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -95,27 +95,26 @@ static void lirc_irctl_cleanup(struct irctl *ir) */ static int lirc_add_to_buf(struct irctl *ir) { - if (ir->d.add_to_buf) { - int res = -ENODATA; - int got_data = 0; + int res; + int got_data = 0; - /* -* service the device as long as it is returning -* data and we have space -*/ - do { - res = ir->d.add_to_buf(ir->d.data, ir->buf); - if (!res) - got_data++; - } while (!res); + if (!ir->d.add_to_buf) + return 0; - if (res == -ENODEV) - kthread_stop(ir->task); + /* +* service the device as long as it is returning +* data and we have space +*/ + do { + res = ir->d.add_to_buf(ir->d.data, ir->buf); + if (!res) + got_data++; + } while (!res); - return got_data ? 0 : res; - } + if (res == -ENODEV) + kthread_stop(ir->task); - return 0; + return got_data ? 0 : res; } /* main function of the polling thread -- 2.8.1 -- 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 09/15] lirc_dev: merge three if statements in only one
The three if statements check the same thing, merge them in only one statement. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 7dff92c..0c26609 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -269,15 +269,10 @@ static int lirc_allocate_driver(struct lirc_driver *d) dev_err(d->dev, "add_to_buf not set\n"); return -EBADRQC; } - } else if (!(d->fops && d->fops->read) && !d->rbuf) { - dev_err(d->dev, "fops->read and rbuf are NULL!\n"); + } else if (!d->rbuf && !(d->fops && d->fops->read && + d->fops->poll && d->fops->unlocked_ioctl)) { + dev_err(d->dev, "undefined read, poll, ioctl\n"); return -EBADRQC; - } else if (!d->rbuf) { - if (!(d->fops && d->fops->read && d->fops->poll && - d->fops->unlocked_ioctl)) { - dev_err(d->dev, "undefined read, poll, ioctl\n"); - return -EBADRQC; - } } mutex_lock(_dev_lock); -- 2.8.1 -- 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 10/15] lirc_dev: remove CONFIG_COMPAT precompiler check
There is no need to check in precompilation whether the ioctl is compat or unlocked, depending on the configuration it will be called the correct one. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 0c26609..c11cfc0 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -149,9 +149,7 @@ static const struct file_operations lirc_dev_fops = { .write = lirc_dev_fop_write, .poll = lirc_dev_fop_poll, .unlocked_ioctl = lirc_dev_fop_ioctl, -#ifdef CONFIG_COMPAT .compat_ioctl = lirc_dev_fop_ioctl, -#endif .open = lirc_dev_fop_open, .release= lirc_dev_fop_close, .llseek = noop_llseek, -- 2.8.1 -- 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 15/15] include: lirc: add set length and frequency ioctl options
The Lirc framework works mainly with receivers, but there is nothing that prevents us from using it for transmitters as well. For that we need to have more control on the device frequency to set (which is a new concept fro LIRC) and we also need to provide to userspace, as feedback, the values of the used frequency and length. Add the LIRC_SET_LENGTH, LIRC_GET_FREQUENCY and LIRC_SET_FREQUENCY ioctl commands in order to allow the above mentioned operations. Signed-off-by: Andi Shyti--- include/uapi/linux/lirc.h | 4 1 file changed, 4 insertions(+) diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index 4b3ab29..94a0d8c 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h @@ -106,6 +106,7 @@ /* code length in bits, currently only for LIRC_MODE_LIRCCODE */ #define LIRC_GET_LENGTH_IOR('i', 0x000f, __u32) +#define LIRC_SET_LENGTH_IOW('i', 0x0010, __u32) #define LIRC_SET_SEND_MODE _IOW('i', 0x0011, __u32) #define LIRC_SET_REC_MODE _IOW('i', 0x0012, __u32) @@ -165,4 +166,7 @@ #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x0023, __u32) +#define LIRC_GET_FREQUENCY _IOR('i', 0x0024, __u32) +#define LIRC_SET_FREQUENCY _IOW('i', 0x0025, __u32) + #endif -- 2.8.1 -- 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 08/15] lirc_dev: remove double if ... else statement
There are two if ... else which check the same thing in different part of the code, they can be merged in a single check. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index d63ff85..7dff92c 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -309,13 +309,6 @@ static int lirc_allocate_driver(struct lirc_driver *d) irctls[minor] = ir; d->minor = minor; - if (d->sample_rate) { - ir->jiffies_to_wait = HZ / d->sample_rate; - } else { - /* it means - wait for external event in task queue */ - ir->jiffies_to_wait = 0; - } - /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; @@ -329,6 +322,8 @@ static int lirc_allocate_driver(struct lirc_driver *d) "lirc%u", ir->d.minor); if (d->sample_rate) { + ir->jiffies_to_wait = HZ / d->sample_rate; + /* try to fire up polling thread */ ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); if (IS_ERR(ir->task)) { @@ -337,6 +332,9 @@ static int lirc_allocate_driver(struct lirc_driver *d) err = -ECHILD; goto out_sysfs; } + } else { + /* it means - wait for external event in task queue */ + ir->jiffies_to_wait = 0; } err = lirc_cdev_add(ir); -- 2.8.1 -- 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 14/15] lirc_dev: fix potential segfault
When opening or closing a lirc character device, the framework provides to the user the possibility to keep track of opening or closing of the device by calling two functions: - set_use_inc() when opening the device - set_use_dec() when closing the device if those are not set by the lirc user, the system segfaults. Check the pointer value before calling the above functions. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 0a3d65d..58dabdc 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -412,7 +412,10 @@ int lirc_unregister_driver(int minor) ir->d.name, ir->d.minor); wake_up_interruptible(>buf->wait_poll); mutex_lock(>irctl_lock); - ir->d.set_use_dec(ir->d.data); + + if (ir->d.set_use_dec) + ir->d.set_use_dec(ir->d.data); + module_put(cdev->owner); mutex_unlock(>irctl_lock); } else { @@ -471,7 +474,8 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) cdev = ir->cdev; if (try_module_get(cdev->owner)) { ir->open++; - retval = ir->d.set_use_inc(ir->d.data); + if (ir->d.set_use_inc) + retval = ir->d.set_use_inc(ir->d.data); if (retval) { module_put(cdev->owner); @@ -512,7 +516,8 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) ir->open--; if (ir->attached) { - ir->d.set_use_dec(ir->d.data); + if (ir->d.set_use_dec) + ir->d.set_use_dec(ir->d.data); module_put(cdev->owner); } else { lirc_irctl_cleanup(ir); -- 2.8.1 -- 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 12/15] lirc_dev: fix error return value
If ioctl is called, it cannot be a case of invalid system call number (ENOSYS), that is an operation not permitted (EPERM). Replace ENOSYS with EPERM. Signed-off-by: Andi Shyti--- drivers/media/rc/lirc_dev.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 7e5cb85..6f3402c 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -587,7 +587,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case LIRC_GET_REC_MODE: if (!(ir->d.features & LIRC_CAN_REC_MASK)) { - result = -ENOSYS; + result = -EPERM; break; } @@ -597,7 +597,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case LIRC_SET_REC_MODE: if (!(ir->d.features & LIRC_CAN_REC_MASK)) { - result = -ENOSYS; + result = -EPERM; break; } @@ -615,7 +615,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LIRC_GET_MIN_TIMEOUT: if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ir->d.min_timeout == 0) { - result = -ENOSYS; + result = -EPERM; break; } @@ -624,7 +624,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LIRC_GET_MAX_TIMEOUT: if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ir->d.max_timeout == 0) { - result = -ENOSYS; + result = -EPERM; break; } -- 2.8.1 -- 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] exynos4-is: Fix buffer release issue on fimc m2m video nodes
This fixes dropping ownership of buffers in the driver's stop_streaming callback, so buffers on the memory-to-memory video nodes are properly released, also in case when the driver has a buffer only on one of the queues (OUTPUT, CAPTURE) before the video node close. The issue was being reported by videobuf2 with a following warning while checking q->owned_by_drv_count: [ 2498.310766] WARNING: CPU: 0 PID: 9358 at drivers/media/v4l2-core/videobuf2-core.c:1818 __vb2_queue_cancel+0xe8/0x14c [ 2498.320258] Modules linked in: [ 2498.323212] CPU: 0 PID: 9358 Comm: v4l2_decode Not tainted 4.7.0-rc4-next-20160627 #1210 [ 2498.331284] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 2498.331327] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 2498.331344] [] (show_stack) from [] (dump_stack+0x74/0x94) [ 2498.331358] [] (dump_stack) from [] (__warn+0xd4/0x100) [ 2498.331369] [] (__warn) from [] (warn_slowpath_null+0x20/0x28) [ 2498.331381] [] (warn_slowpath_null) from [] (__vb2_queue_cancel+0xe8/0x14c) [ 2498.331395] [] (__vb2_queue_cancel) from [] (vb2_core_queue_release+0x18/0x38) [ 2498.331406] [] (vb2_core_queue_release) from [] (v4l2_m2m_ctx_release+0x1c/0x28) [ 2498.331420] [] (v4l2_m2m_ctx_release) from [] (fimc_m2m_release+0x24/0x78) [ 2498.331437] [] (fimc_m2m_release) from [] (v4l2_release+0x34/0x74) [ 2498.331455] [] (v4l2_release) from [] (__fput+0x80/0x1bc) [ 2498.331469] [] (__fput) from [] (task_work_run+0xc0/0xe4) [ 2498.331482] [] (task_work_run) from [] (do_exit+0x304/0xa24) [ 2498.331493] [] (do_exit) from [] (do_group_exit+0x3c/0xbc) [ 2498.331505] [] (do_group_exit) from [] (get_signal+0x200/0x65c) [ 2498.331517] [] (get_signal) from [] (do_signal+0x84/0x3c4) [ 2498.331532] [] (do_signal) from [] (do_work_pending+0xa4/0xb4) [ 2498.331545] [] (do_work_pending) from [] (slow_work_pending+0xc/0x20) Reported-by: Marek SzyprowskiSigned-off-by: Sylwester Nawrocki --- drivers/media/platform/exynos4-is/fimc-m2m.c | 24 ++-- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 55ec4c9..ec1c762 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -50,30 +50,28 @@ void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state) src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - if (src_vb && dst_vb) { + if (src_vb) v4l2_m2m_buf_done(src_vb, vb_state); + if (dst_vb) v4l2_m2m_buf_done(dst_vb, vb_state); + if (src_vb && dst_vb) v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev, ctx->fh.m2m_ctx); - } } /* Complete the transaction which has been scheduled for execution. */ -static int fimc_m2m_shutdown(struct fimc_ctx *ctx) +static void fimc_m2m_shutdown(struct fimc_ctx *ctx) { struct fimc_dev *fimc = ctx->fimc_dev; - int ret; if (!fimc_m2m_pending(fimc)) - return 0; + return; fimc_ctx_state_set(FIMC_CTX_SHUT, ctx); - ret = wait_event_timeout(fimc->irq_queue, - !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx), - FIMC_SHUTDOWN_TIMEOUT); - - return ret == 0 ? -ETIMEDOUT : ret; + wait_event_timeout(fimc->irq_queue, + !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx), + FIMC_SHUTDOWN_TIMEOUT); } static int start_streaming(struct vb2_queue *q, unsigned int count) @@ -88,12 +86,10 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) static void stop_streaming(struct vb2_queue *q) { struct fimc_ctx *ctx = q->drv_priv; - int ret; - ret = fimc_m2m_shutdown(ctx); - if (ret == -ETIMEDOUT) - fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); + fimc_m2m_shutdown(ctx); + fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); pm_runtime_put(>fimc_dev->pdev->dev); } -- 1.9.1 -- 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] media: platform/xilinx: Set VTC VSYNC/VBLANK values
This patch sets the values of VSYNC and VBLANK in Xilinx VTC. The patch was tested using a modified version of this driver and using an HDMI compliance equipment. There is still missing the polarity settings for H/V which would require a change in the interface of this driver. Signed-off-by: Jose AbreuCc: Carlos Palminha Cc: Hyun Kwon Cc: Laurent Pinchart Cc: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org --- drivers/media/platform/xilinx/xilinx-vtc.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c index 01c750e..49e82f2 100644 --- a/drivers/media/platform/xilinx/xilinx-vtc.c +++ b/drivers/media/platform/xilinx/xilinx-vtc.c @@ -211,11 +211,15 @@ int xvtc_generator_start(struct xvtc_device *xvtc, xvtc_gen_write(xvtc, XVTC_HSYNC, (config->hsync_end << XVTC_HSYNC_END_SHIFT) | (config->hsync_start << XVTC_HSYNC_START_SHIFT)); - xvtc_gen_write(xvtc, XVTC_F0_VBLANK_H, 0); + xvtc_gen_write(xvtc, XVTC_F0_VBLANK_H, + (config->hsync_start << XVTC_F0_VBLANK_HEND_SHIFT) | + (config->hsync_start << XVTC_F0_VBLANK_HSTART_SHIFT)); xvtc_gen_write(xvtc, XVTC_F0_VSYNC_V, (config->vsync_end << XVTC_F0_VSYNC_VEND_SHIFT) | (config->vsync_start << XVTC_F0_VSYNC_VSTART_SHIFT)); - xvtc_gen_write(xvtc, XVTC_F0_VSYNC_H, 0); + xvtc_gen_write(xvtc, XVTC_F0_VSYNC_H, + (config->hsync_start << XVTC_F0_VSYNC_HEND_SHIFT) | + (config->hsync_start << XVTC_F0_VSYNC_HSTART_SHIFT)); /* Enable the generator. Set the source of all generator parameters to * generator registers. -- 2.1.4 -- 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: si2157 driver
Hi Olli, thanks for fast reply. It's possible to improve driver to support analog mode? I try to find datasheet for this chip, but looks like only short version is a public. On 29.06.16 07:42, Olli Salonen wrote: > Hi Oleg, > > Correct, only digital TV is supported currently by the driver. > > Cheers, > -olli > > On 28 June 2016 at 23:22, Oleh Kravchenkowrote: >> Hello linux media developers! >> >> I try add support for usb hybrid tuner, it based on: >> CX23102-112, Si2158, Si2168 >> >> I updated cx231xx-cards.c with valid ids, but I don't have idea how to >> use Si2158. >> It is not listed in tuner-types.c >> >> Why si2157.c is absent in tuner-types.c? >> Or at the current state si2157.c don't have analog support? >> -- >> 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 -- 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