dvb/pci/pt1: decompose earth-pt1 into sub drivers
Subsystems (3)
[email protected]
maintainerv3 cover dvb/pci/pt1: decompose earth-pt1 into sub drivers
From: Akihiro Tsukada <[email protected]>
Changes since v2:
- dvb-pll,pt1: do not #define chip name constants and use string literals
Changes since v1:
- use new style of specifying pll_desc of the terrestrial tuner
Akihiro Tsukada (5):
dvb-frontends/dvb-pll: add tda6651 ISDB-T pll_desc
tuners: add new i2c driver for Sharp qm1d1b0004 ISDB-S tuner
dvb: earth-pt1: decompose pt1 driver into sub drivers
dvb: earth-pt1: add support for suspend/resume
dvb: earth-pt1: replace schedule_timeout with usleep_range
drivers/media/dvb-frontends/dvb-pll.c | 24 + drivers/media/dvb-frontends/dvb-pll.h | 1 + drivers/media/pci/pt1/Kconfig | 3 + drivers/media/pci/pt1/Makefile | 3 +- drivers/media/pci/pt1/pt1.c | 470 ++++++++++++----- drivers/media/pci/pt1/va1j5jf8007s.c | 732 -------------------------- drivers/media/pci/pt1/va1j5jf8007s.h | 42 -- drivers/media/pci/pt1/va1j5jf8007t.c | 532 ------------------- drivers/media/pci/pt1/va1j5jf8007t.h | 42 -- drivers/media/tuners/Kconfig | 7 + drivers/media/tuners/Makefile | 1 + drivers/media/tuners/qm1d1b0004.c | 264 ++++++++++ drivers/media/tuners/qm1d1b0004.h | 24 + 13 files changed, 676 insertions(+), 1469 deletions(-) delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.c delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.h delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.c delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.h create mode 100644 drivers/media/tuners/qm1d1b0004.c create mode 100644 drivers/media/tuners/qm1d1b0004.h
Signature · 1 line
2.17.0
[email protected]
maintainerPATCH v3 1/5 dvb-frontends/dvb-pll: add tda6651 ISDB-T pll_desc
From: Akihiro Tsukada <[email protected]>
This patch adds a PLL "description" of Philips TDA6651 for ISDB-T. It was extracted from (the former) va1j5jf8007t.c of EarthSoft PT1, thus the desc might include PT1 specific configs.
---
Changes since v2:
- do not #define chip name constant
Changes since v1:
- use new style of specifying pll_desc of the tuner
drivers/media/dvb-frontends/dvb-pll.c | 24 ++++++++++++++++++++++++ drivers/media/dvb-frontends/dvb-pll.h | 1 + 2 files changed, 25 insertions(+)
drivers/media/dvb-frontends/dvb-pll.c +24 -0
@@ -550,6 +550,28 @@ static const struct dvb_pll_desc dvb_pll_tua6034_friio = { } }; +/* Philips TDA6651 ISDB-T, used in Earthsoft PT1 */ +static const struct dvb_pll_desc dvb_pll_tda665x_earth_pt1 = { + .name ="Philips TDA6651 ISDB-T (EarthSoft PT1)" , + .min =90000000 , + .max =770000000 , + .iffreq =57000000 , + .initdata = (u8 []){5 ,0x0e ,0x7f ,0xc1 ,0x80 ,0x80 }, + .count =10 , + .entries = { + {140000000 ,142857 ,0xc1 ,0x81 }, + {170000000 ,142857 ,0xc1 ,0xa1 }, + {220000000 ,142857 ,0xc1 ,0x62 }, + {330000000 ,142857 ,0xc1 ,0xa2 }, + {402000000 ,142857 ,0xc1 ,0xe2 }, + {450000000 ,142857 ,0xc1 ,0x64 }, + {550000000 ,142857 ,0xc1 ,0x84 }, + {600000000 ,142857 ,0xc1 ,0xa4 }, + {700000000 ,142857 ,0xc1 ,0xc4 }, + {770000000 ,142857 ,0xc1 ,0xe4 }, + } +}; +/* ----------------------------------------------------------- */ static const struct dvb_pll_desc *pll_list[] = {
@@ -574,6 +596,7 @@ static const struct dvb_pll_desc *pll_list[] = { [DVB_PLL_SAMSUNG_TBDU18132] = &dvb_pll_samsung_tbdu18132, [DVB_PLL_SAMSUNG_TBMU24112] = &dvb_pll_samsung_tbmu24112, [DVB_PLL_TUA6034_FRIIO] = &dvb_pll_tua6034_friio, + [DVB_PLL_TDA665X_EARTH_PT1] = &dvb_pll_tda665x_earth_pt1, };/* ----------------------------------------------------------- */
@@ -896,6 +919,7 @@ static const struct i2c_device_id dvb_pll_id[] = { {"tdee4", DVB_PLL_TDEE4}, {"dtt7520x", DVB_PLL_THOMSON_DTT7520X}, {"tua6034_friio", DVB_PLL_TUA6034_FRIIO}, + {"tda665x_earthpt1", DVB_PLL_TDA665X_EARTH_PT1}, {} };
drivers/media/dvb-frontends/dvb-pll.h +1 -0
@@ -30,6 +30,7 @@#define DVB_PLL_TDEE4 18#define DVB_PLL_THOMSON_DTT7520X 19#define DVB_PLL_TUA6034_FRIIO 20 +#define DVB_PLL_TDA665X_EARTH_PT1 21struct dvb_pll_config {struct dvb_frontend *fe;
Signature · 1 line
2.17.0
[email protected]
maintainerPATCH v3 2/5 tuners: add new i2c driver for Sharp qm1d1b0004 ISDB-S tuner
In reply to [email protected]From: Akihiro Tsukada <[email protected]>
The tuner is used in Earthsoft PT1/PT2 DVB boards,
and the driver was extraced from (the former) va1j5jf8007s.c of PT1. it might contain PT1 specific configs.
---
Changes since v2:
- none
Changes since v1:
- none
drivers/media/tuners/Kconfig | 7 + drivers/media/tuners/Makefile | 1 + drivers/media/tuners/qm1d1b0004.c | 264 ++++++++++++++++++++++++++++++ drivers/media/tuners/qm1d1b0004.h | 24 +++ 4 files changed, 296 insertions(+) create mode 100644 drivers/media/tuners/qm1d1b0004.c create mode 100644 drivers/media/tuners/qm1d1b0004.h
drivers/media/tuners/Kconfig +7 -0
@@ -284,4 +284,11 @@ config MEDIA_TUNER_QM1D1C0042 default m if !MEDIA_SUBDRV_AUTOSELECT help Sharp QM1D1C0042 trellis coded 8PSK tuner driver. + +config MEDIA_TUNER_QM1D1B0004 + tristate "Sharp QM1D1B0004 tuner" + depends on MEDIA_SUPPORT && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Sharp QM1D1B0004 ISDB-S tuner driver. endmenu
drivers/media/tuners/Makefile +1 -0
@@ -41,6 +41,7 @@ obj-$(CONFIG_MEDIA_TUNER_IT913X) += it913x.o obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o +obj-$(CONFIG_MEDIA_TUNER_QM1D1B0004) += qm1d1b0004.o obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o
drivers/media/tuners/qm1d1b0004.c new file +264 -0
264 lines not on this page · raw message
drivers/media/tuners/qm1d1b0004.h new file +24 -0
@@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Sharp QM1D1B0004 satellite tuner +* +* Copyright (C) 2014 Akihiro Tsukada <[email protected]> +*/ + +#ifndef QM1D1B0004_H +#define QM1D1B0004_H + +#include <media/dvb_frontend.h> + +struct qm1d1b0004_config { +struct dvb_frontend *fe; + +u32 lpf_freq;/* LPF frequency[kHz]. Default: symbol rate */ +bool half_step;/* use PLL frequency step of 500Hz istead of 1000Hz */ +}; + +/* special values indicating to use the default in qm1d1b0004_config */ +#define QM1D1B0004_CFG_PLL_DFLT 0 +#define QM1D1B0004_CFG_LPF_DFLT 0 + +#endif
Signature · 1 line
2.17.0
Re: [PATCH v3 2/5] tuners: add new i2c driver for Sharp qm1d1b0004 ISDB-S tuner
Em Mon, 9 Apr 2018 02:39:50 +0900
[email protected] escreveu:
Quoted 7 lines
From: Akihiro Tsukada <[email protected]>
The tuner is used in Earthsoft PT1/PT2 DVB boards,
and the driver was extraced from (the former)va1j5jf8007s.cof PT1. it might contain PT1 specific configs.Signed-off-by Akihiro Tsukada <[email protected]>
Please add yourself to MAINTAINERS file for this driver (and for other drivers you wrote).
Quoted 333 lines
---
Changes since v2:
- noneChanges since v1:
- nonedrivers/media/tuners/Kconfig | 7 + drivers/media/tuners/Makefile | 1 + drivers/media/tuners/qm1d1b0004.c | 264 ++++++++++++++++++++++++++++++ drivers/media/tuners/qm1d1b0004.h | 24 +++ 4 files changed, 296 insertions(+) create mode 100644 drivers/media/tuners/qm1d1b0004.c create mode 100644 drivers/media/tuners/qm1d1b0004.hdrivers/media/tuners/Kconfig +7
-0@@ -284,4 +284,11 @@ config MEDIA_TUNER_QM1D1C0042 default m if !MEDIA_SUBDRV_AUTOSELECT help Sharp QM1D1C0042 trellis coded 8PSK tuner driver. + +config MEDIA_TUNER_QM1D1B0004 + tristate "Sharp QM1D1B0004 tuner" + depends on MEDIA_SUPPORT && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Sharp QM1D1B0004 ISDB-S tuner driver. endmenudrivers/media/tuners/Makefile +1
-0@@ -41,6 +41,7 @@ obj-$(CONFIG_MEDIA_TUNER_IT913X) += it913x.o obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o +obj-$(CONFIG_MEDIA_TUNER_QM1D1B0004) += qm1d1b0004.o obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.odrivers/media/tuners/qm1d1b0004.c new file +264
-0@@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Sharp QM1D1B0004 satellite tuner +* +* Copyright (C) 2014 Akihiro Tsukada <[email protected]> +* +* based on (former) drivers/media/pci/pt1/va1j5jf8007s.c. +*/ + +/* +* Note: +* Since the data-sheet of this tuner chip is not available, +* this driver lacks some tuner_ops and config options. +* In addition, the implementation might be dependent on the specific use +* in the FE module: VA1J5JF8007S and/or in the product: Earthsoft PT1/PT2. +*/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <media/dvb_frontend.h> +#include "qm1d1b0004.h" + +/* +* Tuner I/F (copied from the former va1j5jf8007s.c) +* b[0] I2C addr +* b[1] "0":1, BG:2, divider_quotient[7:3]:5 +* b[2] divider_quotient[2:0]:3, divider_remainder:5 +* b[3] "111":3, LPF[3:2]:2, TM:1, "0":1, REF:1 +* b[4] BANDX, PSC:1, LPF[1:0]:2, DIV:1, "0":1 +* +* PLL frequency step := +* REF == 0 -> PLL XTL frequency(4MHz) / 8 +* REF == 1 -> PLL XTL frequency(4MHz) / 4 +* +* PreScaler := +* PSC == 0 -> x32 +* PSC == 1 -> x16 +* +* divider_quotient := (frequency / PLL frequency step) / PreScaler +* divider_remainder := (frequency / PLL frequency step) % PreScaler +* +* LPF := LPF Frequency / 1000 / 2 - 2 +* LPF Frequency @ baudrate=28.86Mbps = 30000 +* +* band (1..9) +* band 1 (freq < 986000) -> DIV:1, BANDX:5, PSC:1 +* band 2 (freq < 1072000) -> DIV:1, BANDX:6, PSC:1 +* band 3 (freq < 1154000) -> DIV:1, BANDX:7, PSC:0 +* band 4 (freq < 1291000) -> DIV:0, BANDX:1, PSC:0 +* band 5 (freq < 1447000) -> DIV:0, BANDX:2, PSC:0 +* band 6 (freq < 1615000) -> DIV:0, BANDX:3, PSC:0 +* band 7 (freq < 1791000) -> DIV:0, BANDX:4, PSC:0 +* band 8 (freq < 1972000) -> DIV:0, BANDX:5, PSC:0 +* band 9 (freq < 2150000) -> DIV:0, BANDX:6, PSC:0 +*/ + +#define QM1D1B0004_PSC_MASK (1 << 4) + +#define QM1D1B0004_XTL_FREQ 4000 +#define QM1D1B0004_LPF_FALLBACK 30000 + +static const struct qm1d1b0004_config default_cfg = { + .lpf_freq =QM1D1B0004_CFG_LPF_DFLT , + .half_step = false, +}; + +struct qm1d1b0004_state { +struct qm1d1b0004_config cfg; +struct i2c_client *i2c; +}; + + +struct qm1d1b0004_cb_map { +u32 frequency; +u8 cb; +}; + +static const struct qm1d1b0004_cb_map cb_maps[] = { + {986000 ,0xb2 }, + {1072000 ,0xd2 }, + {1154000 ,0xe2 }, + {1291000 ,0x20 }, + {1447000 ,0x40 }, + {1615000 ,0x60 }, + {1791000 ,0x80 }, + {1972000 ,0xa0 }, +}; + +static u8 lookup_cb (u32 frequency) +{ +int i; +const struct qm1d1b0004_cb_map *map; + +for (i =0 ; i <ARRAY_SIZE (cb_maps); i++) { + map = &cb_maps[i]; +if (frequency < map->frequency) +return map->cb; + } +return 0xc0 ; +} + +static int qm1d1b0004_set_params (struct dvb_frontend *fe) +{ +struct qm1d1b0004_state *state; +u32 frequency, pll, lpf_freq; +u16 word; +u8 buf[4 ], cb, lpf; +int ret; + + state = fe->tuner_priv; + frequency = fe->dtv_property_cache.frequency; + + pll =QM1D1B0004_XTL_FREQ /4 ; +if (state->cfg.half_step) + pll /=2 ; + word =DIV_ROUND_CLOSEST (frequency, pll); + cb =lookup_cb (frequency); +if (cb &QM1D1B0004_PSC_MASK ) + word = (word <<1 & ~0x1f ) | (word &0x0f ); + +/* step.1: set frequency with BG:2, TM:0(4MHZ), LPF:4MHz */ + buf[0 ] =0x40 | word >>8 ; + buf[1 ] = word; +/* inconsisnten with the above I/F doc. maybe the doc is wrong */ + buf[2 ] =0xe0 | state->cfg.half_step; + buf[3 ] = cb; + ret =i2c_master_send (state->i2c, buf,4 ); +if (ret <0 ) +return ret; + +/* step.2: set TM:1 */ + buf[0 ] =0xe4 | state->cfg.half_step; + ret =i2c_master_send (state->i2c, buf,1 ); +if (ret <0 ) +return ret; +msleep (20 ); + +/* step.3: set LPF */ + lpf_freq = state->cfg.lpf_freq; +if (lpf_freq ==QM1D1B0004_CFG_LPF_DFLT ) + lpf_freq = fe->dtv_property_cache.symbol_rate /1000 ; +if (lpf_freq ==0 ) + lpf_freq =QM1D1B0004_LPF_FALLBACK ; + lpf =DIV_ROUND_UP (lpf_freq,2000 ) -2 ; + buf[0 ] =0xe4 | ((lpf &0x0c ) <<1 ) | state->cfg.half_step; + buf[1 ] = cb | ((lpf &0x03 ) <<2 ); + ret =i2c_master_send (state->i2c, buf,2 ); +if (ret <0 ) +return ret; + +/* step.4: read PLL lock? */ + buf[0 ] =0 ; + ret =i2c_master_recv (state->i2c, buf,1 ); +if (ret <0 ) +return ret; +return 0 ; +} + + +static int qm1d1b0004_set_config (struct dvb_frontend *fe,void *priv_cfg) +{ +struct qm1d1b0004_state *state; + + state = fe->tuner_priv; +memcpy (&state->cfg, priv_cfg,sizeof (state->cfg)); +return 0 ; +} + + +static int qm1d1b0004_init (struct dvb_frontend *fe) +{ +struct qm1d1b0004_state *state; +u8 buf[2 ] = {0xf8 ,0x04 }; + + state = fe->tuner_priv; +if (state->cfg.half_step) + buf[0 ] |=0x01 ; + +return i2c_master_send (state->i2c, buf,2 ); +} + + +static const struct dvb_tuner_ops qm1d1b0004_ops = { + .info = { + .name ="Sharp qm1d1b0004" , + + .frequency_min =950000 , + .frequency_max =2150000 , + }, + + .init = qm1d1b0004_init, + + .set_params = qm1d1b0004_set_params, + .set_config = qm1d1b0004_set_config, +}; + +static int +qm1d1b0004_probe (struct i2c_client *client,const struct i2c_device_id *id) +{ +struct dvb_frontend *fe; +struct qm1d1b0004_config *cfg; +struct qm1d1b0004_state *state; +int ret; + + cfg = client->dev.platform_data; + fe = cfg->fe; +i2c_set_clientdata (client, fe); + + fe->tuner_priv =kzalloc (sizeof (struct qm1d1b0004_state ),GFP_KERNEL ); +if (!fe->tuner_priv) { + ret = -ENOMEM ; + goto err_mem; + } + +memcpy (&fe->ops.tuner_ops, &qm1d1b0004_ops,sizeof (fe->ops.tuner_ops)); + + state = fe->tuner_priv; + state->i2c = client; + ret =qm1d1b0004_set_config (fe, cfg); +if (ret !=0 ) + goto err_priv; + +dev_info (&client->dev,"Sharp QM1D1B0004 attached.\n" ); +return 0 ; + +err_priv: +kfree (fe->tuner_priv); +err_mem: + fe->tuner_priv =NULL ; +return ret; +} + +static int qm1d1b0004_remove (struct i2c_client *client) +{ +struct dvb_frontend *fe; + + fe =i2c_get_clientdata (client); +kfree (fe->tuner_priv); + fe->tuner_priv =NULL ; +return 0 ; +} + + +static const struct i2c_device_id qm1d1b0004_id[] = { + {"qm1d1b0004" ,0 }, + {} +}; + +MODULE_DEVICE_TABLE (i2c, qm1d1b0004_id); + +static struct i2c_driver qm1d1b0004_driver = { + .driver = { + .name ="qm1d1b0004" , + }, + .probe = qm1d1b0004_probe, + .remove = qm1d1b0004_remove, + .id_table = qm1d1b0004_id, +}; + +module_i2c_driver (qm1d1b0004_driver); + +MODULE_DESCRIPTION ("Sharp QM1D1B0004" ); +MODULE_AUTHOR ("Akihiro Tsukada" ); +MODULE_LICENSE ("GPL" );drivers/media/tuners/qm1d1b0004.h new file +14
-0@@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Sharp QM1D1B0004 satellite tuner +* +* Copyright (C) 2014 Akihiro Tsukada <[email protected]> +*/ + +#ifndef QM1D1B0004_H +#define QM1D1B0004_H + +#include <media/dvb_frontend.h> + +struct qm1d1b0004_config { + struct dvb_frontend *fe;
drivers/media/tuners/qm1d1b0004.h line 24
Quoted 10 lines
drivers/media/tuners/qm1d1b0004.h new file +10
-0+ +u32 lpf_freq;/* LPF frequency[kHz]. Default: symbol rate */ + bool half_step; /* use PLL frequency step of 500Hz istead of 1000Hz */ +}; + +/* special values indicating to use the default in qm1d1b0004_config */ +#define QM1D1B0004_CFG_PLL_DFLT 0 +#define QM1D1B0004_CFG_LPF_DFLT 0 + +#endif
Thanks,
Mauro
[email protected]
maintainerPATCH v3 3/5 dvb: earth-pt1: decompose pt1 driver into sub drivers
In reply to [email protected]From: Akihiro Tsukada <[email protected]>
earth-pt1 was a monolithic module and included demod/tuner drivers. This patch removes those FE parts and attach demod/tuner i2c drivers.
---
Changes since v2:
- specify tuner chip name literally
Changes since v1:
- use i2c_board_info.name to specify pll_desc id.
drivers/media/pci/pt1/Kconfig | 3 + drivers/media/pci/pt1/Makefile | 3 +- drivers/media/pci/pt1/pt1.c | 329 ++++++++---- drivers/media/pci/pt1/va1j5jf8007s.c | 732 --------------------------- drivers/media/pci/pt1/va1j5jf8007s.h | 42 -- drivers/media/pci/pt1/va1j5jf8007t.c | 532 ------------------- drivers/media/pci/pt1/va1j5jf8007t.h | 42 -- 7 files changed, 227 insertions(+), 1456 deletions(-) delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.c delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.h delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.c delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.h
drivers/media/pci/pt1/Kconfig +3 -0
@@ -1,6 +1,9 @@ config DVB_PT1 tristate "PT1 cards" depends on DVB_CORE && PCI && I2C + select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT + select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_QM1D1B0004 if MEDIA_SUBDRV_AUTOSELECT help Support for Earthsoft PT1 PCI cards.
drivers/media/pci/pt1/Makefile +2 -1
@@ -1,5 +1,6 @@ -earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o +earth-pt1-objs := pt1.o obj-$(CONFIG_DVB_PT1) += earth-pt1.o ccflags-y += -Idrivers/media/dvb-frontends +ccflags-y += -Idrivers/media/tuners
drivers/media/pci/pt1/pt1.c +222 -107
414 lines not on this page · raw message
drivers/media/pci/pt1/va1j5jf8007s.c deleted +0 -732
732 lines not on this page · raw message
drivers/media/pci/pt1/va1j5jf8007s.h deleted +0 -42
42 lines not on this page · raw message
drivers/media/pci/pt1/va1j5jf8007t.c deleted +0 -532
532 lines not on this page · raw message
drivers/media/pci/pt1/va1j5jf8007t.h deleted +0 -42
42 lines not on this page · raw message
Signature · 1 line
2.17.0
[email protected]
maintainerPATCH v3 4/5 dvb: earth-pt1: add support for suspend/resume
In reply to [email protected]From: Akihiro Tsukada <[email protected]>
Without this patch, re-loading of the module was required after resume.
---
Changes since v2:
- none
Changes since v1:
- none
drivers/media/pci/pt1/pt1.c | 107 +++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-)
drivers/media/pci/pt1/pt1.c +105 -2
@@ -461,12 +461,18 @@ static int pt1_thread(void *data) {struct pt1 *pt1;struct pt1_buffer_page *page; +bool was_frozen; pt1 = data;set_freezable (); -while (!kthread_should_stop ()) { -try_to_freeze (); +while (!kthread_freezable_should_stop (&was_frozen)) { +if (was_frozen) { +int i; + +for (i =0 ; i <PT1_NR_ADAPS ; i++) +pt1_set_stream (pt1, i, !!pt1->adaps[i]->users); + } page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;if (!pt1_filter (pt1, page)) {
@@ -1165,6 +1171,98 @@ static void pt1_i2c_init(struct pt1 *pt1)pt1_i2c_emit (pt1, i,0 ,0 ,1 ,1 ,0 ); } +#ifdef CONFIG_PM_SLEEP + +static int pt1_suspend (struct device *dev) +{ +struct pci_dev *pdev =to_pci_dev (dev); +struct pt1 *pt1 =pci_get_drvdata (pdev); + +pt1_init_streams (pt1); +pt1_disable_ram (pt1); + pt1->power =0 ; + pt1->reset =1 ; +pt1_update_power (pt1); +return 0 ; +} + +static int pt1_resume (struct device *dev) +{ +struct pci_dev *pdev =to_pci_dev (dev); +struct pt1 *pt1 =pci_get_drvdata (pdev); +int ret; +int i; + + pt1->power =0 ; + pt1->reset =1 ; +pt1_update_power (pt1); + +pt1_i2c_init (pt1); +pt1_i2c_wait (pt1); + + ret =pt1_sync (pt1); +if (ret <0 ) + goto resume_err; + +pt1_identify (pt1); + + ret =pt1_unlock (pt1); +if (ret <0 ) + goto resume_err; + + ret =pt1_reset_pci (pt1); +if (ret <0 ) + goto resume_err; + + ret =pt1_reset_ram (pt1); +if (ret <0 ) + goto resume_err; + + ret =pt1_enable_ram (pt1); +if (ret <0 ) + goto resume_err; + +pt1_init_streams (pt1); + + pt1->power =1 ; +pt1_update_power (pt1); +msleep (20 ); + + pt1->reset =0 ; +pt1_update_power (pt1); +usleep_range (1000 ,2000 ); + +for (i =0 ; i <PT1_NR_ADAPS ; i++) +dvb_frontend_reinitialise (pt1->adaps[i]->fe); + +pt1_init_table_count (pt1); +for (i =0 ; i < pt1_nr_tables; i++) { +int j; + +for (j =0 ; j <PT1_NR_BUFS ; j++) + pt1->tables[i].bufs[j].page->upackets[PT1_NR_UPACKETS -1 ] + =0 ; +pt1_increment_table_count (pt1); + } +pt1_register_tables (pt1, pt1->tables[0 ].addr >>PT1_PAGE_SHIFT ); + + pt1->table_index =0 ; + pt1->buf_index =0 ; +for (i =0 ; i <PT1_NR_ADAPS ; i++) { + pt1->adaps[i]->upacket_count =0 ; + pt1->adaps[i]->packet_count =0 ; + pt1->adaps[i]->st_count =-1 ; + } + +return 0 ; + +resume_err: +dev_info (&pt1->pdev->dev,"failed to resume PT1/PT2." ); +return 0 ;/* resume anyway */ +} + +#endif /* CONFIG_PM_SLEEP */ +static void pt1_remove (struct pci_dev *pdev) {struct pt1 *pt1;
@@ -1325,11 +1423,16 @@ static const struct pci_device_id pt1_id_table[] = { };MODULE_DEVICE_TABLE (pci, pt1_id_table); +static SIMPLE_DEV_PM_OPS(pt1_pm_ops, pt1_suspend, pt1_resume); +static struct pci_driver pt1_driver = { .name =DRIVER_NAME , .probe = pt1_probe, .remove = pt1_remove, .id_table = pt1_id_table, +#if CONFIG_PM_SLEEP + .driver.pm = &pt1_pm_ops, +#endif };module_pci_driver (pt1_driver);
Signature · 1 line
2.17.0
[email protected]
maintainerPATCH v3 5/5 dvb: earth-pt1: replace schedule_timeout with usleep_range
In reply to [email protected]From: Akihiro Tsukada <[email protected]>
As described in Document/timers/timers-howto.txt, hrtimer-based delay should be used for small sleeps.
---
Changes since v2:
- none
Changes since v1:
- none
drivers/media/pci/pt1/pt1.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
drivers/media/pci/pt1/pt1.c +23 -11
@@ -18,7 +18,10 @@*/ #include <linux/kernel.h> +#include <linux/sched.h> #include <linux/sched/signal.h> +#include <linux/hrtimer.h> +#include <linux/delay.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/vmalloc.h>
@@ -321,7 +324,7 @@ static int pt1_unlock(struct pt1 *pt1)for (i =0 ; i <3 ; i++) {if (pt1_read_reg (pt1,0 ) &0x80000000 )return 0 ; -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); }dev_err (&pt1->pdev->dev,"could not unlock\n" );return -EIO ;
@@ -335,7 +338,7 @@ static int pt1_reset_pci(struct pt1 *pt1)for (i =0 ; i <10 ; i++) {if (pt1_read_reg (pt1,0 ) &0x00000001 )return 0 ; -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); }dev_err (&pt1->pdev->dev,"could not reset PCI\n" );return -EIO ;
@@ -349,7 +352,7 @@ static int pt1_reset_ram(struct pt1 *pt1)for (i =0 ; i <10 ; i++) {if (pt1_read_reg (pt1,0 ) &0x00000002 )return 0 ; -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); }dev_err (&pt1->pdev->dev,"could not reset RAM\n" );return -EIO ;
@@ -366,7 +369,7 @@ static int pt1_do_enable_ram(struct pt1 *pt1)if ((pt1_read_reg (pt1,0 ) &0x00000004 ) != status)return 0 ; } -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); }dev_err (&pt1->pdev->dev,"could not enable RAM\n" );return -EIO ;
@@ -376,7 +379,7 @@ static int pt1_enable_ram(struct pt1 *pt1) {int i, ret;int phase; -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); phase = pt1->pdev->device ==0x211a ?128 :166 ;for (i =0 ; i < phase; i++) { ret =pt1_do_enable_ram (pt1);
@@ -463,6 +466,9 @@ static int pt1_thread(void *data)struct pt1_buffer_page *page;bool was_frozen; +#define PT1_FETCH_DELAY 10 +#define PT1_FETCH_DELAY_DELTA 2 + pt1 = data;set_freezable ();
@@ -476,7 +482,13 @@ static int pt1_thread(void *data) page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;if (!pt1_filter (pt1, page)) { -schedule_timeout_interruptible ((HZ +999 ) /1000 ); +ktime_t delay; + + delay =PT1_FETCH_DELAY *NSEC_PER_MSEC ; +set_current_state (TASK_INTERRUPTIBLE ); +schedule_hrtimeout_range (&delay, +PT1_FETCH_DELAY_DELTA *NSEC_PER_MSEC , +HRTIMER_MODE_REL );continue ; }
@@ -712,7 +724,7 @@ pt1_update_power(struct pt1 *pt1) adap = pt1->adaps[i];switch (adap->voltage) {case SEC_VOLTAGE_13 :/* actually 11V */ - bits |=1 <<1 ; + bits |=1 <<2 ;break ;case SEC_VOLTAGE_18 :/* actually 15V */ bits |=1 <<1 |1 <<2 ;
@@ -766,7 +778,7 @@ static int pt1_wakeup(struct dvb_frontend *fe) adap = container_of(fe->dvb, struct pt1_adapter, adap); adap->sleep =0 ;pt1_update_power (adap->pt1); -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); ret =config_demod (adap->demod_i2c_client, adap->pt1->fe_clk);if (ret ==0 && adap->orig_init)
@@ -1073,7 +1085,7 @@ static int pt1_i2c_end(struct pt1 *pt1, int addr)do {if (signal_pending (current))return -EINTR ; -schedule_timeout_interruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); }while (pt1_read_reg (pt1,0 ) &0x00000080 );return 0 ; }
@@ -1376,11 +1388,11 @@ static int pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pt1->power =1 ;pt1_update_power (pt1); -schedule_timeout_uninterruptible ((HZ +49 ) /50 ); +msleep (20 ); pt1->reset =0 ;pt1_update_power (pt1); -schedule_timeout_uninterruptible ((HZ +999 ) /1000 ); +usleep_range (1000 ,2000 ); ret =pt1_init_frontends (pt1);if (ret <0 )
Signature · 1 line
2.17.0