Browse Source

- hd60: fix kernel build

master
vanhofen 2 years ago
parent
commit
9e52512b6a
  1. 1
      package/kernel/files/kernel-hd6x.defconfig
  2. 0
      package/kernel/patches/gfutures/0001-remote.patch
  3. 0
      package/kernel/patches/gfutures/0002-log2-give-up-on-gcc-constant-optimizations.patch
  4. 0
      package/kernel/patches/gfutures/0003-dont-mark-register-as-const.patch
  5. 24
      package/kernel/patches/gfutures/0004-linux-fix-buffer-size-warning-error.patch
  6. 238
      package/kernel/patches/gfutures/0005-xbox-one-tuner-4.4.patch
  7. 1192
      package/kernel/patches/gfutures/0006-dvb-media-tda18250-support-for-new-silicon-tuner.patch
  8. 834
      package/kernel/patches/gfutures/0007-dvb-mn88472-staging.patch
  9. 629
      package/kernel/patches/gfutures/0008-HauppaugeWinTV-dualHD.patch
  10. 158
      package/kernel/patches/gfutures/0009-dib7000-linux_4.4.179.patch
  11. 67
      package/kernel/patches/gfutures/0010-dvb-usb-linux_4.4.179.patch
  12. 8663
      package/kernel/patches/gfutures/0011-wifi-linux_4.4.183.patch
  13. 36
      package/kernel/patches/gfutures/0012-move-default-dialect-to-SMB3.patch
  14. 50
      package/kernel/patches/gfutures/0013-modules_mark__inittest__exittest_as__maybe_unused.patch
  15. 84
      package/kernel/patches/gfutures/0014-includelinuxmodule_h_copy__init__exit_attrs_to_initcleanup_module.patch
  16. 51
      package/kernel/patches/gfutures/0015-Backport_minimal_compiler_attributes_h_to_support_GCC_9.patch
  17. 33
      package/kernel/patches/gfutures/0016-mn88472_reset_stream_ID_reg_if_no_PLP_given.patch
  18. 11
      package/kernel/patches/gfutures/4_4_ieee80211-increase-scan-result-expire-time.patch

1
package/kernel/files/kernel-hd6x.defconfig

@ -2773,6 +2773,7 @@ CONFIG_MEDIA_TUNER=y
# Customize TV tuners
#
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA18250=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA827X=y
CONFIG_MEDIA_TUNER_TDA18271=y

0
package/kernel/patches/gfutures/4_4_0001-remote.patch → package/kernel/patches/gfutures/0001-remote.patch

0
package/kernel/patches/gfutures/4_4_0002-log2-give-up-on-gcc-constant-optimizations.patch → package/kernel/patches/gfutures/0002-log2-give-up-on-gcc-constant-optimizations.patch

0
package/kernel/patches/gfutures/4_4_0003-dont-mark-register-as-const.patch → package/kernel/patches/gfutures/0003-dont-mark-register-as-const.patch

24
package/kernel/patches/gfutures/0004-linux-fix-buffer-size-warning-error.patch

@ -0,0 +1,24 @@
--- a/drivers/hisilicon/atags/tag-chiptrim.c
+++ b/drivers/hisilicon/atags/tag-chiptrim.c
@@ -59,7 +59,7 @@ static int __init parse_chiptrim(const struct tag *tag, void *fdt)
int ix;
int ret;
int node;
- char buf[12];
+ char buf[20];
if (tag->hdr.size <= (sizeof(struct tag_header) >> 2)) {
pr_err("%s: bad tag format.\n", __func__);
--- a/drivers/hisilicon/atags/tag-net.c 2020-03-25 11:27:19.138225245 +0000
+++ b/drivers/hisilicon/atags/tag-net.c 2020-03-25 11:27:02.498266476 +0000
@@ -91,7 +91,7 @@
{
int err;
int node, index = 0;
- char path[16];
+ char path[20];
char phy_intf[16];
char *str, *nxt;
int count;
--
2.17.1

238
package/kernel/patches/gfutures/0005-xbox-one-tuner-4.4.patch

@ -0,0 +1,238 @@
---
drivers/media/dvb-core/dvb-usb-ids.h | 2 +
drivers/media/usb/dvb-usb/Kconfig | 2 +
drivers/media/usb/dvb-usb/dib0700.h | 2 +
drivers/media/usb/dvb-usb/dib0700_core.c | 25 ++++-
drivers/media/usb/dvb-usb/dib0700_devices.c | 105 ++++++++++++++++++++
5 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 0a46580b..512275c7 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -70,6 +70,7 @@
#define USB_VID_EVOLUTEPC 0x1e59
#define USB_VID_AZUREWAVE 0x13d3
#define USB_VID_TECHNISAT 0x14f7
+#define USB_VID_MICROSOFT 0x045e
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -389,4 +390,5 @@
#define USB_PID_PCTV_2002E_SE 0x025d
#define USB_PID_SVEON_STV27 0xd3af
#define USB_PID_TURBOX_DTT_2000 0xd3a4
+#define USB_PID_XBOX_ONE_TUNER 0x02d5
#endif
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index 128eee61..d8e3106d 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -75,6 +75,7 @@ config DVB_USB_DIB0700
select DVB_DIB3000MC if MEDIA_SUBDRV_AUTOSELECT
select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TUNER_DIB0090 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
@@ -83,6 +84,7 @@ config DVB_USB_DIB0700
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC4000 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18250 if MEDIA_SUBDRV_AUTOSELECT
help
Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
USB bridge is also present in devices having the DiB7700 DVB-T-USB
diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
index 8fd8f5b4..5f291284 100644
--- a/drivers/media/usb/dvb-usb/dib0700.h
+++ b/drivers/media/usb/dvb-usb/dib0700.h
@@ -51,6 +51,8 @@ struct dib0700_state {
int (*read_status)(struct dvb_frontend *, enum fe_status *);
int (*sleep)(struct dvb_frontend* fe);
u8 buf[255];
+ struct i2c_client *i2c_client_demod;
+ struct i2c_client *i2c_client_tuner;
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 49dd3ea2..e4f3793a 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -872,10 +872,33 @@ static int dib0700_probe(struct usb_interface *intf,
return -ENODEV;
}
+static void dib0700_disconnect(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ struct dib0700_state *st = d->priv;
+ struct i2c_client *client;
+
+ /* remove I2C client for tuner */
+ client = st->i2c_client_tuner;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ /* remove I2C client for demodulator */
+ client = st->i2c_client_demod;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ dvb_usb_device_exit(intf);
+}
+
static struct usb_driver dib0700_driver = {
.name = "dvb_usb_dib0700",
.probe = dib0700_probe,
- .disconnect = dvb_usb_device_exit,
+ .disconnect = dib0700_disconnect,
.id_table = dib0700_usb_id_table,
};
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index e1316c7b..2b6c9d3c 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -23,6 +23,8 @@
#include "dib0090.h"
#include "lgdt3305.h"
#include "mxl5007t.h"
+#include "mn88472.h"
+#include "tda18250.h"
static int force_lna_activation;
module_param(force_lna_activation, int, 0644);
@@ -3705,6 +3708,89 @@
&hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
}
+static int xbox_one_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_state *st = adap->dev->priv;
+ struct i2c_client *client_demod, *client_tuner;
+ struct dvb_usb_device *d = adap->dev;
+ struct mn88472_config mn88472_config = { };
+ struct tda18250_config tda18250_config;
+ struct i2c_board_info info;
+
+ st->fw_use_new_i2c_api = 1;
+ st->disable_streaming_master_mode = 1;
+
+ /* fe power enable */
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(30);
+
+ /* demod reset */
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+
+ /* attach demod */
+ mn88472_config.fe = &adap->fe_adap[0].fe;
+ mn88472_config.i2c_wr_max = 22;
+ mn88472_config.xtal = 20500000;
+ mn88472_config.ts_mode = PARALLEL_TS_MODE;
+ mn88472_config.ts_clock = FIXED_TS_CLOCK;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
+ info.addr = 0x18;
+ info.platform_data = &mn88472_config;
+ request_module(info.type);
+ client_demod = i2c_new_device(&d->i2c_adap, &info);
+ if (client_demod == NULL || client_demod->dev.driver == NULL)
+ goto fail_demod_device;
+ if (!try_module_get(client_demod->dev.driver->owner))
+ goto fail_demod_module;
+
+ st->i2c_client_demod = client_demod;
+
+ adap->fe_adap[0].fe = mn88472_config.get_dvb_frontend(client_demod);
+
+ /* attach tuner */
+ memset(&tda18250_config, 0, sizeof(tda18250_config));
+ tda18250_config.if_dvbt_6 = 3950;
+ tda18250_config.if_dvbt_7 = 4450;
+ tda18250_config.if_dvbt_8 = 4950;
+ tda18250_config.if_dvbc_6 = 4950;
+ tda18250_config.if_dvbc_8 = 4950;
+ tda18250_config.if_atsc = 4079;
+ tda18250_config.loopthrough = true;
+ tda18250_config.xtal_freq = TDA18250_XTAL_FREQ_27MHZ;
+ tda18250_config.fe = adap->fe_adap[0].fe;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "tda18250", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &tda18250_config;
+
+ request_module(info.type);
+ client_tuner = i2c_new_device(&adap->dev->i2c_adap, &info);
+ if (client_tuner == NULL || client_tuner->dev.driver == NULL)
+ goto fail_tuner_device;
+ if (!try_module_get(client_tuner->dev.driver->owner))
+ goto fail_tuner_module;
+
+ st->i2c_client_tuner = client_tuner;
+ return 0;
+
+fail_tuner_module:
+ i2c_unregister_device(client_tuner);
+fail_tuner_device:
+ module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+ i2c_unregister_device(client_demod);
+fail_demod_device:
+ return -ENODEV;
+}
/* DVB-USB and USB stuff follows */
struct usb_device_id dib0700_usb_id_table[] = {
@@ -3794,6 +3880,7 @@
/* 80 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_2) },
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E) },
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E_SE) },
+ { USB_DEVICE(USB_VID_MICROSOFT, USB_PID_XBOX_ONE_TUNER) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -4959,6 +5046,25 @@
RC_BIT_NEC,
.change_protocol = dib0700_change_protocol,
},
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .num_frontends = 1,
+ .fe = {{
+ .frontend_attach = xbox_one_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x82),
+ } },
+ },
+ },
+ .num_device_descs = 1,
+ .devices = {
+ { "Microsoft Xbox One Digital TV Tuner",
+ { &dib0700_usb_id_table[83], NULL },
+ { NULL },
+ },
+ },
},
};
--
2.17.1

1192
package/kernel/patches/gfutures/0006-dvb-media-tda18250-support-for-new-silicon-tuner.patch

File diff suppressed because it is too large

834
package/kernel/patches/gfutures/0007-dvb-mn88472-staging.patch

@ -0,0 +1,834 @@
---
drivers/media/dvb-frontends/mn88472.h | 45 +-
drivers/staging/media/mn88472/mn88472.c | 525 ++++++++++---------
drivers/staging/media/mn88472/mn88472_priv.h | 11 +-
3 files changed, 310 insertions(+), 271 deletions(-)
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
index 095294d2..32363252 100644
--- a/drivers/media/dvb-frontends/mn88472.h
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -19,23 +19,33 @@
#include <linux/dvb/frontend.h>
-enum ts_clock {
- VARIABLE_TS_CLOCK,
- FIXED_TS_CLOCK,
-};
+/**
+ * struct mn88472_config - Platform data for the mn88472 driver
+ * @xtal: Clock frequency.
+ * @ts_mode: TS mode.
+ * @ts_clock: TS clock config.
+ * @i2c_wr_max: Max number of bytes driver writes to I2C at once.
+ * @get_dvb_frontend: Get DVB frontend.
+ */
-enum ts_mode {
- SERIAL_TS_MODE,
- PARALLEL_TS_MODE,
-};
+/* Define old names for backward compatibility */
+#define VARIABLE_TS_CLOCK MN88472_TS_CLK_VARIABLE
+#define FIXED_TS_CLOCK MN88472_TS_CLK_FIXED
+#define SERIAL_TS_MODE MN88472_TS_MODE_SERIAL
+#define PARALLEL_TS_MODE MN88472_TS_MODE_PARALLEL
struct mn88472_config {
- /*
- * Max num of bytes given I2C adapter could write at once.
- * Default: none
- */
- u16 i2c_wr_max;
+ unsigned int xtal;
+
+#define MN88472_TS_MODE_SERIAL 0
+#define MN88472_TS_MODE_PARALLEL 1
+ int ts_mode;
+#define MN88472_TS_CLK_FIXED 0
+#define MN88472_TS_CLK_VARIABLE 1
+ int ts_clock;
+
+ u16 i2c_wr_max;
/* Everything after that is returned by the driver. */
@@ -43,14 +53,7 @@ struct mn88472_config {
* DVB frontend.
*/
struct dvb_frontend **fe;
-
- /*
- * Xtal frequency.
- * Hz
- */
- u32 xtal;
- int ts_mode;
- int ts_clock;
+ struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
};
#endif
diff --git a/drivers/staging/media/mn88472/mn88472.c b/drivers/staging/media/mn88472/mn88472.c
index cf2e96bc..18fb2df1 100644
--- a/drivers/staging/media/mn88472/mn88472.c
+++ b/drivers/staging/media/mn88472/mn88472.c
@@ -17,28 +17,90 @@
#include "mn88472_priv.h"
static int mn88472_get_tune_settings(struct dvb_frontend *fe,
- struct dvb_frontend_tune_settings *s)
+ struct dvb_frontend_tune_settings *s)
{
- s->min_delay_ms = 800;
+ s->min_delay_ms = 1000;
return 0;
}
+static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct i2c_client *client = fe->demodulator_priv;
+ struct mn88472_dev *dev = i2c_get_clientdata(client);
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret;
+ unsigned int utmp;
+
+ if (!dev->active) {
+ ret = -EAGAIN;
+ goto err;
+ }
+
+ switch (c->delivery_system) {
+ case SYS_DVBT:
+ ret = regmap_read(dev->regmap[0], 0x7f, &utmp);
+ if (ret)
+ goto err;
+ if ((utmp & 0x0f) >= 0x09)
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ else
+ *status = 0;
+ break;
+ case SYS_DVBT2:
+ ret = regmap_read(dev->regmap[2], 0x92, &utmp);
+ if (ret)
+ goto err;
+ if ((utmp & 0x0f) >= 0x0d)
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ else if ((utmp & 0x0f) >= 0x0a)
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI;
+ else if ((utmp & 0x0f) >= 0x07)
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ else
+ *status = 0;
+ break;
+ case SYS_DVBC_ANNEX_A:
+ ret = regmap_read(dev->regmap[1], 0x84, &utmp);
+ if (ret)
+ goto err;
+ if ((utmp & 0x0f) >= 0x08)
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ else
+ *status = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+
+ return 0;
+err:
+ dev_dbg(&client->dev, "failed=%d\n", ret);
+ return ret;
+}
+
static int mn88472_set_frontend(struct dvb_frontend *fe)
{
struct i2c_client *client = fe->demodulator_priv;
struct mn88472_dev *dev = i2c_get_clientdata(client);
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i;
- u32 if_frequency = 0;
- u64 tmp;
- u8 delivery_system_val, if_val[3], bw_val[7], bw_val2;
+ unsigned int utmp;
+ u32 if_frequency;
+ u8 buf[3], delivery_system_val, bandwidth_val, *bandwidth_vals_ptr;
+ u8 reg_bank0_b4_val, reg_bank0_cd_val, reg_bank0_d4_val;
+ u8 reg_bank0_d6_val;
dev_dbg(&client->dev,
- "delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
- c->delivery_system, c->modulation,
- c->frequency, c->symbol_rate, c->inversion);
+ "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n",
+ c->delivery_system, c->modulation, c->frequency,
+ c->bandwidth_hz, c->symbol_rate, c->inversion, c->stream_id);
- if (!dev->warm) {
+ if (!dev->active) {
ret = -EAGAIN;
goto err;
}
@@ -46,39 +108,64 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
switch (c->delivery_system) {
case SYS_DVBT:
delivery_system_val = 0x02;
+ reg_bank0_b4_val = 0x00;
+ reg_bank0_cd_val = 0x1f;
+ reg_bank0_d4_val = 0x0a;
+ reg_bank0_d6_val = 0x48;
break;
case SYS_DVBT2:
delivery_system_val = 0x03;
+ reg_bank0_b4_val = 0xf6;
+ reg_bank0_cd_val = 0x01;
+ reg_bank0_d4_val = 0x09;
+ reg_bank0_d6_val = 0x46;
break;
case SYS_DVBC_ANNEX_A:
delivery_system_val = 0x04;
+ reg_bank0_b4_val = 0x00;
+ reg_bank0_cd_val = 0x17;
+ reg_bank0_d4_val = 0x09;
+ reg_bank0_d6_val = 0x48;
break;
default:
ret = -EINVAL;
goto err;
}
- if (c->bandwidth_hz <= 5000000) {
- memcpy(bw_val, "\xe5\x99\x9a\x1b\xa9\x1b\xa9", 7);
- bw_val2 = 0x03;
- } else if (c->bandwidth_hz <= 6000000) {
- /* IF 3570000 Hz, BW 6000000 Hz */
- memcpy(bw_val, "\xbf\x55\x55\x15\x6b\x15\x6b", 7);
- bw_val2 = 0x02;
- } else if (c->bandwidth_hz <= 7000000) {
- /* IF 4570000 Hz, BW 7000000 Hz */
- memcpy(bw_val, "\xa4\x00\x00\x0f\x2c\x0f\x2c", 7);
- bw_val2 = 0x01;
- } else if (c->bandwidth_hz <= 8000000) {
- /* IF 4570000 Hz, BW 8000000 Hz */
- memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
- bw_val2 = 0x00;
- } else {
- ret = -EINVAL;
- goto err;
+ switch (c->delivery_system) {
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ switch (c->bandwidth_hz) {
+ case 5000000:
+ bandwidth_vals_ptr = "\xe5\x99\x9a\x1b\xa9\x1b\xa9";
+ bandwidth_val = 0x03;
+ break;
+ case 6000000:
+ bandwidth_vals_ptr = "\xbf\x55\x55\x15\x6b\x15\x6b";
+ bandwidth_val = 0x02;
+ break;
+ case 7000000:
+ bandwidth_vals_ptr = "\xa4\x00\x00\x0f\x2c\x0f\x2c";
+ bandwidth_val = 0x01;
+ break;
+ case 8000000:
+ bandwidth_vals_ptr = "\x8f\x80\x00\x08\xee\x08\xee";
+ bandwidth_val = 0x00;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+ break;
+ case SYS_DVBC_ANNEX_A:
+ bandwidth_vals_ptr = NULL;
+ bandwidth_val = 0x00;
+ break;
+ default:
+ break;
}
- /* program tuner */
+ /* Program tuner */
if (fe->ops.tuner_ops.set_params) {
ret = fe->ops.tuner_ops.set_params(fe);
if (ret)
@@ -91,20 +178,10 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
goto err;
dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
- }
-
- /* Calculate IF registers ( (1<<24)*IF / Xtal ) */
- tmp = div_u64(if_frequency * (u64)(1<<24) + (dev->xtal / 2),
- dev->xtal);
- if_val[0] = ((tmp >> 16) & 0xff);
- if_val[1] = ((tmp >> 8) & 0xff);
- if_val[2] = ((tmp >> 0) & 0xff);
-
- ret = regmap_write(dev->regmap[2], 0xfb, 0x13);
- ret = regmap_write(dev->regmap[2], 0xef, 0x13);
- ret = regmap_write(dev->regmap[2], 0xf9, 0x13);
- if (ret)
+ } else {
+ ret = -EINVAL;
goto err;
+ }
ret = regmap_write(dev->regmap[2], 0x00, 0x66);
if (ret)
@@ -118,157 +195,81 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
if (ret)
goto err;
- ret = regmap_write(dev->regmap[2], 0x04, bw_val2);
+ ret = regmap_write(dev->regmap[2], 0x04, bandwidth_val);
if (ret)
goto err;
- for (i = 0; i < sizeof(if_val); i++) {
- ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[i]);
+ /* IF */
+ utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, dev->clk);
+ buf[0] = (utmp >> 16) & 0xff;
+ buf[1] = (utmp >> 8) & 0xff;
+ buf[2] = (utmp >> 0) & 0xff;
+ for (i = 0; i < 3; i++) {
+ ret = regmap_write(dev->regmap[2], 0x10 + i, buf[i]);
if (ret)
goto err;
}
- for (i = 0; i < sizeof(bw_val); i++) {
- ret = regmap_write(dev->regmap[2], 0x13 + i, bw_val[i]);
- if (ret)
- goto err;
+ /* Bandwidth */
+ if (bandwidth_vals_ptr) {
+ for (i = 0; i < 7; i++) {
+ ret = regmap_write(dev->regmap[2], 0x13 + i,
+ bandwidth_vals_ptr[i]);
+ if (ret)
+ goto err;
+ }
}
+ ret = regmap_write(dev->regmap[0], 0xb4, reg_bank0_b4_val);
+ if (ret)
+ goto err;
+ ret = regmap_write(dev->regmap[0], 0xcd, reg_bank0_cd_val);
+ if (ret)
+ goto err;
+ ret = regmap_write(dev->regmap[0], 0xd4, reg_bank0_d4_val);
+ if (ret)
+ goto err;
+ ret = regmap_write(dev->regmap[0], 0xd6, reg_bank0_d6_val);
+ if (ret)
+ goto err;
+
switch (c->delivery_system) {
case SYS_DVBT:
ret = regmap_write(dev->regmap[0], 0x07, 0x26);
- ret = regmap_write(dev->regmap[0], 0xb0, 0x0a);
- ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
- ret = regmap_write(dev->regmap[0], 0xcd, 0x1f);
- ret = regmap_write(dev->regmap[0], 0xd4, 0x0a);
- ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
+ if (ret)
+ goto err;
ret = regmap_write(dev->regmap[0], 0x00, 0xba);
+ if (ret)
+ goto err;
ret = regmap_write(dev->regmap[0], 0x01, 0x13);
if (ret)
goto err;
break;
case SYS_DVBT2:
ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
+ if (ret)
+ goto err;
ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
+ if (ret)
+ goto err;
ret = regmap_write(dev->regmap[1], 0xf6, 0x05);
- ret = regmap_write(dev->regmap[0], 0xb0, 0x0a);
- ret = regmap_write(dev->regmap[0], 0xb4, 0xf6);
- ret = regmap_write(dev->regmap[0], 0xcd, 0x01);
- ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
- ret = regmap_write(dev->regmap[0], 0xd6, 0x46);
- ret = regmap_write(dev->regmap[2], 0x30, 0x80);
- ret = regmap_write(dev->regmap[2], 0x32, 0x00);
if (ret)
goto err;
- break;
- case SYS_DVBC_ANNEX_A:
- ret = regmap_write(dev->regmap[0], 0xb0, 0x0b);
- ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
- ret = regmap_write(dev->regmap[0], 0xcd, 0x17);
- ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
- ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
- ret = regmap_write(dev->regmap[1], 0x00, 0xb0);
+ ret = regmap_write(dev->regmap[2], 0x32, c->stream_id);
if (ret)
goto err;
break;
- default:
- ret = -EINVAL;
- goto err;
- }
-
- ret = regmap_write(dev->regmap[0], 0x46, 0x00);
- ret = regmap_write(dev->regmap[0], 0xae, 0x00);
-
- switch (dev->ts_mode) {
- case SERIAL_TS_MODE:
- ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
- break;
- case PARALLEL_TS_MODE:
- ret = regmap_write(dev->regmap[2], 0x08, 0x00);
+ case SYS_DVBC_ANNEX_A:
break;
default:
- dev_dbg(&client->dev, "ts_mode error: %d\n", dev->ts_mode);
- ret = -EINVAL;
- goto err;
- }
-
- switch (dev->ts_clock) {
- case VARIABLE_TS_CLOCK:
- ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
break;
- case FIXED_TS_CLOCK:
- ret = regmap_write(dev->regmap[0], 0xd9, 0xe1);
- break;
- default:
- dev_dbg(&client->dev, "ts_clock error: %d\n", dev->ts_clock);
- ret = -EINVAL;
- goto err;
}
- /* Reset demod */
+ /* Reset FSM */
ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
if (ret)
goto err;
- dev->delivery_system = c->delivery_system;
-
- return 0;
-err:
- dev_dbg(&client->dev, "failed=%d\n", ret);
- return ret;
-}
-
-static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
-{
- struct i2c_client *client = fe->demodulator_priv;
- struct mn88472_dev *dev = i2c_get_clientdata(client);
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret;
- unsigned int utmp;
- int lock = 0;
-
- *status = 0;
-
- if (!dev->warm) {
- ret = -EAGAIN;
- goto err;
- }
-
- switch (c->delivery_system) {
- case SYS_DVBT:
- ret = regmap_read(dev->regmap[0], 0x7F, &utmp);
- if (ret)
- goto err;
- if ((utmp & 0xF) >= 0x09)
- lock = 1;
- break;
- case SYS_DVBT2:
- ret = regmap_read(dev->regmap[2], 0x92, &utmp);
- if (ret)
- goto err;
- if ((utmp & 0xF) >= 0x07)
- *status |= FE_HAS_SIGNAL;
- if ((utmp & 0xF) >= 0x0a)
- *status |= FE_HAS_CARRIER;
- if ((utmp & 0xF) >= 0x0d)
- *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
- break;
- case SYS_DVBC_ANNEX_A:
- ret = regmap_read(dev->regmap[1], 0x84, &utmp);
- if (ret)
- goto err;
- if ((utmp & 0xF) >= 0x08)
- lock = 1;
- break;
- default:
- ret = -EINVAL;
- goto err;
- }
-
- if (lock)
- *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
- FE_HAS_SYNC | FE_HAS_LOCK;
-
return 0;
err:
dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -279,93 +280,107 @@ static int mn88472_init(struct dvb_frontend *fe)
{
struct i2c_client *client = fe->demodulator_priv;
struct mn88472_dev *dev = i2c_get_clientdata(client);
- int ret, len, remaining;
- const struct firmware *fw = NULL;
- u8 *fw_file = MN88472_FIRMWARE;
- unsigned int tmp;
+ int ret, len, rem;
+ unsigned int utmp;
+ const struct firmware *firmware;
+ const char *name = MN88472_FIRMWARE;
dev_dbg(&client->dev, "\n");
- /* set cold state by default */
- dev->warm = false;
-
- /* power on */
+ /* Power up */
ret = regmap_write(dev->regmap[2], 0x05, 0x00);
if (ret)
goto err;
-
- ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2);
+ ret = regmap_write(dev->regmap[2], 0x0b, 0x00);
if (ret)
goto err;
-
- /* check if firmware is already running */
- ret = regmap_read(dev->regmap[0], 0xf5, &tmp);
+ ret = regmap_write(dev->regmap[2], 0x0c, 0x00);
if (ret)
goto err;
- if (!(tmp & 0x1)) {
- dev_info(&client->dev, "firmware already running\n");
- dev->warm = true;
- return 0;
- }
+ /* Check if firmware is already running */
+ ret = regmap_read(dev->regmap[0], 0xf5, &utmp);
+ if (ret)
+ goto err;
+ if (!(utmp & 0x01))
+ goto warm;
- /* request the firmware, this will block and timeout */
- ret = request_firmware(&fw, fw_file, &client->dev);
+ ret = request_firmware(&firmware, name, &client->dev);
if (ret) {
- dev_err(&client->dev, "firmare file '%s' not found\n",
- fw_file);
+ dev_err(&client->dev, "firmware file '%s' not found\n", name);
goto err;
}
- dev_info(&client->dev, "downloading firmware from file '%s'\n",
- fw_file);
+ dev_info(&client->dev, "downloading firmware from file '%s'\n", name);
ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
if (ret)
- goto firmware_release;
-
- for (remaining = fw->size; remaining > 0;
- remaining -= (dev->i2c_wr_max - 1)) {
- len = remaining;
- if (len > (dev->i2c_wr_max - 1))
- len = dev->i2c_wr_max - 1;
+ goto err_release_firmware;
+ for (rem = firmware->size; rem > 0; rem -= (dev->i2c_write_max - 1)) {
+ len = min(dev->i2c_write_max - 1, rem);
ret = regmap_bulk_write(dev->regmap[0], 0xf6,
- &fw->data[fw->size - remaining], len);
+ &firmware->data[firmware->size - rem],
+ len);
if (ret) {
- dev_err(&client->dev,
- "firmware download failed=%d\n", ret);
- goto firmware_release;
+ dev_err(&client->dev, "firmware download failed %d\n",
+ ret);
+ goto err_release_firmware;
}
}
- /* parity check of firmware */
- ret = regmap_read(dev->regmap[0], 0xf8, &tmp);
- if (ret) {
- dev_err(&client->dev,
- "parity reg read failed=%d\n", ret);
- goto firmware_release;
- }
- if (tmp & 0x10) {
- dev_err(&client->dev,
- "firmware parity check failed=0x%x\n", tmp);
- goto firmware_release;
+ /* Parity check of firmware */
+ ret = regmap_read(dev->regmap[0], 0xf8, &utmp);
+ if (ret)
+ goto err_release_firmware;
+ if (utmp & 0x10) {
+ ret = -EINVAL;
+ dev_err(&client->dev, "firmware did not run\n");
+ goto err_release_firmware;
}
- dev_err(&client->dev, "firmware parity check succeeded=0x%x\n", tmp);
ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
if (ret)
- goto firmware_release;
+ goto err_release_firmware;
+
+ release_firmware(firmware);
+warm:
+ /* TS config */
+ switch (dev->ts_mode) {
+ case SERIAL_TS_MODE:
+ utmp = 0x1d;
+ break;
+ case PARALLEL_TS_MODE:
+ utmp = 0x00;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = regmap_write(dev->regmap[2], 0x08, utmp);
+ if (ret)
+ goto err;
- release_firmware(fw);
- fw = NULL;
+ switch (dev->ts_clk) {
+ case VARIABLE_TS_CLOCK:
+ utmp = 0xe3;
+ break;
+ case FIXED_TS_CLOCK:
+ utmp = 0xe1;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = regmap_write(dev->regmap[0], 0xd9, utmp);
+ if (ret)
+ goto err;
- /* warm state */
- dev->warm = true;
+ dev->active = true;
return 0;
-firmware_release:
- release_firmware(fw);
+err_release_firmware:
+ release_firmware(firmware);
err:
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
@@ -379,18 +394,17 @@ static int mn88472_sleep(struct dvb_frontend *fe)
dev_dbg(&client->dev, "\n");
- /* power off */
+ /* Power down */
+ ret = regmap_write(dev->regmap[2], 0x0c, 0x30);
+ if (ret)
+ goto err;
ret = regmap_write(dev->regmap[2], 0x0b, 0x30);
-
if (ret)
goto err;
-
ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
if (ret)
goto err;
- dev->delivery_system = SYS_UNDEFINED;
-
return 0;
err:
dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -434,10 +448,19 @@ static struct dvb_frontend_ops mn88472_ops = {
.read_status = mn88472_read_status,
};
+static struct dvb_frontend *mn88472_get_dvb_frontend(struct i2c_client *client)
+{
+ struct mn88472_dev *dev = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "\n");
+
+ return &dev->fe;
+}
+
static int mn88472_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
- struct mn88472_config *config = client->dev.platform_data;
+ struct mn88472_config *pdata = client->dev.platform_data;
struct mn88472_dev *dev;
int ret;
unsigned int utmp;
@@ -448,23 +471,16 @@ static int mn88472_probe(struct i2c_client *client,
dev_dbg(&client->dev, "\n");
- /* Caller really need to provide pointer for frontend we create. */
- if (config->fe == NULL) {
- dev_err(&client->dev, "frontend pointer not defined\n");
- ret = -EINVAL;
- goto err;
- }
-
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
+ if (!dev) {
ret = -ENOMEM;
goto err;
}
- dev->i2c_wr_max = config->i2c_wr_max;
- dev->xtal = config->xtal;
- dev->ts_mode = config->ts_mode;
- dev->ts_clock = config->ts_clock;
+ dev->i2c_write_max = pdata->i2c_wr_max ? pdata->i2c_wr_max : ~0;
+ dev->clk = pdata->xtal;
+ dev->ts_mode = pdata->ts_mode;
+ dev->ts_clk = pdata->ts_clock;
dev->client[0] = client;
dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);
if (IS_ERR(dev->regmap[0])) {
@@ -472,18 +488,28 @@ static int mn88472_probe(struct i2c_client *client,
goto err_kfree;
}
- /* check demod answers to I2C */
- ret = regmap_read(dev->regmap[0], 0x00, &utmp);
+ /* Check demod answers with correct chip id */
+ ret = regmap_read(dev->regmap[0], 0xff, &utmp);
if (ret)
goto err_regmap_0_regmap_exit;
+ dev_dbg(&client->dev, "chip id=%02x\n", utmp);
+
+ if (utmp != 0x02) {
+ ret = -ENODEV;
+ goto err_regmap_0_regmap_exit;
+ }
+
/*
- * Chip has three I2C addresses for different register pages. Used
+ * Chip has three I2C addresses for different register banks. Used
* addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
- * 0x1a and 0x1c, in order to get own I2C client for each register page.
+ * 0x1a and 0x1c, in order to get own I2C client for each register bank.
+ *
+ * Also, register bank 2 do not support sequential I/O. Only single
+ * register write or read is allowed to that bank.
*/
dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
- if (dev->client[1] == NULL) {
+ if (!dev->client[1]) {
ret = -ENODEV;
dev_err(&client->dev, "I2C registration failed\n");
if (ret)
@@ -497,7 +523,7 @@ static int mn88472_probe(struct i2c_client *client,
i2c_set_clientdata(dev->client[1], dev);
dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
- if (dev->client[2] == NULL) {
+ if (!dev->client[2]) {
ret = -ENODEV;
dev_err(&client->dev, "2nd I2C registration failed\n");
if (ret)
@@ -510,15 +536,25 @@ static int mn88472_probe(struct i2c_client *client,
}
i2c_set_clientdata(dev->client[2], dev);
- /* create dvb_frontend */
+ /* Sleep because chip is active by default */
+ ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
+ if (ret)
+ goto err_regmap_2_regmap_exit;
+
+ /* Create dvb frontend */
memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
dev->fe.demodulator_priv = client;
- *config->fe = &dev->fe;
+ *pdata->fe = &dev->fe;
i2c_set_clientdata(client, dev);
- dev_info(&client->dev, "Panasonic MN88472 successfully attached\n");
- return 0;
+ /* Setup callbacks */
+ pdata->get_dvb_frontend = mn88472_get_dvb_frontend;
+ dev_info(&client->dev, "Panasonic MN88472 successfully identified\n");
+
+ return 0;
+err_regmap_2_regmap_exit:
+ regmap_exit(dev->regmap[2]);
err_client_2_i2c_unregister_device:
i2c_unregister_device(dev->client[2]);
err_regmap_1_regmap_exit:
@@ -561,11 +597,12 @@ MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
static struct i2c_driver mn88472_driver = {
.driver = {
- .name = "mn88472",
+ .name = "mn88472",
+ .suppress_bind_attrs = true,
},
- .probe = mn88472_probe,
- .remove = mn88472_remove,
- .id_table = mn88472_id_table,
+ .probe = mn88472_probe,
+ .remove = mn88472_remove,
+ .id_table = mn88472_id_table,
};
module_i2c_driver(mn88472_driver);
diff --git a/drivers/staging/media/mn88472/mn88472_priv.h b/drivers/staging/media/mn88472/mn88472_priv.h
index 1a0de9e4..cdf2597a 100644
--- a/drivers/staging/media/mn88472/mn88472_priv.h
+++ b/drivers/staging/media/mn88472/mn88472_priv.h
@@ -28,12 +28,11 @@ struct mn88472_dev {
struct i2c_client *client[3];
struct regmap *regmap[3];
struct dvb_frontend fe;
- u16 i2c_wr_max;
- enum fe_delivery_system delivery_system;
- bool warm; /* FW running */
- u32 xtal;
- int ts_mode;
- int ts_clock;
+ u16 i2c_write_max;
+ unsigned int clk;
+ unsigned int active:1;
+ unsigned int ts_mode:1;
+ unsigned int ts_clk:1;
};
#endif
--
2.17.1

629
package/kernel/patches/gfutures/0008-HauppaugeWinTV-dualHD.patch

@ -0,0 +1,629 @@
diff -Nur a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
--- a/Documentation/video4linux/CARDLIST.em28xx 2017-07-31 15:25:12.000000000 +0200
+++ b/Documentation/video4linux/CARDLIST.em28xx 2019-04-02 08:35:00.919204500 +0200
@@ -96,3 +96,5 @@
95 -> Leadtek VC100 (em2861) [0413:6f07]
96 -> Terratec Cinergy T2 Stick HD (em28178)
97 -> Elgato EyeTV Hybrid 2008 INT (em2884) [0fd9:0018]
+ 98 -> Hauppauge WinTV-dualHD DVB (em28174) [2040:0265]
+
diff -Nur a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
--- a/drivers/media/usb/em28xx/em28xx.h 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/em28xx/em28xx.h 2019-04-02 08:30:40.196114900 +0200
@@ -145,6 +145,7 @@
#define EM2861_BOARD_LEADTEK_VC100 95
#define EM28178_BOARD_TERRATEC_T2_STICK_HD 96
#define EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 97
+#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB 98
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -213,6 +214,9 @@
/* max. number of button state polling addresses */
#define EM28XX_NUM_BUTTON_ADDRESSES_MAX 5
+#define PRIMARY_TS 0
+#define SECONDARY_TS 1
+
enum em28xx_mode {
EM28XX_SUSPEND,
EM28XX_ANALOG_MODE,
@@ -412,6 +416,7 @@
enum em28xx_led_role {
EM28XX_LED_ANALOG_CAPTURING = 0,
EM28XX_LED_DIGITAL_CAPTURING,
+ EM28XX_LED_DIGITAL_CAPTURING_TS2,
EM28XX_LED_ILLUMINATION,
EM28XX_NUM_LED_ROLES, /* must be the last */
};
@@ -458,6 +463,7 @@
unsigned int mts_firmware:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
+ unsigned int has_dual_ts:1;
unsigned int is_webcam:1;
unsigned int valid:1;
unsigned int has_ir_i2c:1;
@@ -608,7 +614,6 @@
struct em28xx_IR *ir;
/* generic device properties */
- char name[30]; /* name (including minor) of the device */
int model; /* index in the device_data struct */
int devno; /* marks the number of this device */
enum em28xx_chip_id chip_id;
@@ -619,6 +624,7 @@
unsigned int is_audio_only:1;
enum em28xx_int_audio_type int_audio_type;
enum em28xx_usb_audio_type usb_audio_type;
+ unsigned char name[32];
struct em28xx_board board;
@@ -677,9 +683,12 @@
/* usb transfer */
struct usb_device *udev; /* the usb device */
+ struct usb_interface *intf; // the usb interface
u8 ifnum; /* number of the assigned usb interface */
u8 analog_ep_isoc; /* address of isoc endpoint for analog */
u8 analog_ep_bulk; /* address of bulk endpoint for analog */
+ u8 dvb_ep_isoc_ts2; /* address of isoc endpoint for DVB TS2*/
+ u8 dvb_ep_bulk_ts2; /* address of bulk endpoint for DVB TS2*/
u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */
u8 dvb_ep_bulk; /* address of bulk endpoint for DVB */
int alt; /* alternate setting */
@@ -693,6 +702,8 @@
int dvb_alt_isoc; /* alternate setting for DVB isoc transfers */
unsigned int dvb_max_pkt_size_isoc; /* isoc max packet size of the
selected DVB ep at dvb_alt */
+ unsigned int dvb_max_pkt_size_isoc_ts2; /* isoc max packet size of the
+ selected DVB ep at dvb_alt */
unsigned int dvb_xfer_bulk:1; /* use bulk instead of isoc
transfers for DVB */
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
@@ -718,6 +729,15 @@
/* Snapshot button input device */
char snapshot_button_path[30]; /* path of the input dev */
struct input_dev *sbutton_input_dev;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+ struct media_device *media_dev;
+ struct media_entity input_ent[MAX_EM28XX_INPUT];
+ struct media_pad input_pad[MAX_EM28XX_INPUT];
+#endif
+
+ struct em28xx *dev_next;
+ int ts;
};
#define kref_to_dev(d) container_of(d, struct em28xx, ref)
diff -Nur a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
--- a/drivers/media/usb/em28xx/em28xx-cards.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/em28xx/em28xx-cards.c 2019-04-02 08:43:27.288403900 +0200
@@ -491,6 +491,30 @@
{-1, -1, -1, -1},
};
+/* 2040:0265 Hauppauge WinTV-dualHD DVB Isoc
+ * 2040:8265 Hauppauge WinTV-dualHD DVB Bulk
+ * reg 0x80/0x84:
+ * GPIO_0: Yellow LED tuner 1, 0=on, 1=off
+ * GPIO_1: Green LED tuner 1, 0=on, 1=off
+ * GPIO_2: Yellow LED tuner 2, 0=on, 1=off
+ * GPIO_3: Green LED tuner 2, 0=on, 1=off
+ * GPIO_5: Reset #2, 0=active
+ * GPIO_6: Reset #1, 0=active
+ */
+static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = {
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0},
+ {0x0d, 0xff, 0xff, 200},
+ {0x50, 0x04, 0xff, 300},
+ {EM2874_R80_GPIO_P0_CTRL, 0xbf, 0xff, 100}, /* demod 1 reset */
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xdf, 0xff, 100}, /* demod 2 reset */
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100},
+ {EM2874_R5F_TS_ENABLE, 0x44, 0xff, 50},
+ {EM2874_R5D_TS1_PKT_SIZE, 0x05, 0xff, 50},
+ {EM2874_R5E_TS2_PKT_SIZE, 0x05, 0xff, 50},
+ {-1, -1, -1, -1},
+};
+
/*
* Button definitions
*/
@@ -560,6 +584,22 @@
{-1, 0, 0, 0},
};
+static struct em28xx_led hauppauge_dualhd_leds[] = {
+ {
+ .role = EM28XX_LED_DIGITAL_CAPTURING,
+ .gpio_reg = EM2874_R80_GPIO_P0_CTRL,
+ .gpio_mask = EM_GPIO_1,
+ .inverted = 1,
+ },
+ {
+ .role = EM28XX_LED_DIGITAL_CAPTURING_TS2,
+ .gpio_reg = EM2874_R80_GPIO_P0_CTRL,
+ .gpio_mask = EM_GPIO_3,
+ .inverted = 1,
+ },
+ {-1, 0, 0, 0},
+};
+
/*
* Board definitions
*/
@@ -2288,6 +2328,20 @@
.has_dvb = 1,
.ir_codes = RC_MAP_TERRATEC_SLIM_2,
},
+ /* 2040:0265 Hauppauge WinTV-dualHD (DVB version) Isoc.
+ * 2040:8265 Hauppauge WinTV-dualHD (DVB version) Bulk.
+ * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 */
+ [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = {
+ .name = "Hauppauge WinTV-dualHD DVB",
+ .def_i2c_bus = 1,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_gpio = hauppauge_dualhd_dvb,
+ .has_dvb = 1,
+ .has_dual_ts = 1,
+ .ir_codes = RC_MAP_HAUPPAUGE,
+ .leds = hauppauge_dualhd_leds,
+ },
};
EXPORT_SYMBOL_GPL(em28xx_boards);
@@ -2411,6 +2465,10 @@
.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x651f),
.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
+ { USB_DEVICE(0x2040, 0x0265),
+ .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
+ { USB_DEVICE(0x2040, 0x8265),
+ .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
{ USB_DEVICE(0x0438, 0xb002),
.driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
{ USB_DEVICE(0x2001, 0xf112),
@@ -2804,6 +2862,7 @@
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
+ case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
{
struct tveeprom tv;
@@ -3013,6 +3072,8 @@
*/
static void em28xx_release_resources(struct em28xx *dev)
{
+ struct usb_device *udev = interface_to_usbdev(dev->intf);
+
/*FIXME: I2C IR should be disconnected */
mutex_lock(&dev->lock);
@@ -3021,7 +3082,8 @@
em28xx_i2c_unregister(dev, 1);
em28xx_i2c_unregister(dev, 0);
- usb_put_dev(dev->udev);
+ if (dev->ts == PRIMARY_TS)
+ usb_put_dev(udev);
/* Mark device as unused */
clear_bit(dev->devno, em28xx_devused);
@@ -3063,6 +3125,7 @@
const char *chip_name = default_chip_name;
dev->udev = udev;
+ dev->intf = interface;
mutex_init(&dev->ctrl_urb_lock);
spin_lock_init(&dev->slock);
@@ -3220,6 +3283,35 @@
return 0;
}
+int em28xx_duplicate_dev(struct em28xx *dev)
+{
+ int nr;
+ struct em28xx *sec_dev = kzalloc(sizeof(*sec_dev), GFP_KERNEL);
+
+ if (sec_dev == NULL) {
+ dev->dev_next = NULL;
+ return -ENOMEM;
+ }
+ memcpy(sec_dev, dev, sizeof(sizeof(*sec_dev)));
+ /* Check to see next free device and mark as used */
+ do {
+ nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
+ if (nr >= EM28XX_MAXBOARDS) {
+ /* No free device slots */
+ printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
+ EM28XX_MAXBOARDS);
+ kfree(sec_dev);
+ dev->dev_next = NULL;
+ return -ENOMEM;
+ }
+ } while (test_and_set_bit(nr, em28xx_devused));
+ sec_dev->devno = nr;
+ snprintf(sec_dev->name, 28, "em28xx #%d", nr);
+ sec_dev->dev_next = NULL;
+ dev->dev_next = sec_dev;
+ return 0;
+}
+
/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
@@ -3340,6 +3432,17 @@
}
}
break;
+ case 0x85:
+ if (usb_endpoint_xfer_isoc(e)) {
+ if (size > dev->dvb_max_pkt_size_isoc_ts2) {
+ dev->dvb_ep_isoc_ts2 = e->bEndpointAddress;
+ dev->dvb_max_pkt_size_isoc_ts2 = size;
+ dev->dvb_alt_isoc = i;
+ }
+ } else {
+ dev->dvb_ep_bulk_ts2 = e->bEndpointAddress;
+ }
+ break;
}
}
/* NOTE:
@@ -3354,6 +3457,8 @@
* 0x83 isoc* => audio
* 0x84 isoc => digital
* 0x84 bulk => analog or digital**
+ * 0x85 isoc => digital TS2
+ * 0x85 bulk => digital TS2
* (*: audio should always be isoc)
* (**: analog, if ep 0x82 is isoc, otherwise digital)
*
@@ -3422,6 +3527,10 @@
dev->has_video = has_video;
dev->ifnum = ifnum;
+ dev->ts = PRIMARY_TS;
+ snprintf(dev->name, 28, "em28xx");
+ dev->dev_next = NULL;
+
if (has_vendor_audio) {
printk(KERN_INFO DRIVER_NAME ": Audio interface %i found %s\n",
ifnum, "(Vendor Class)");
@@ -3491,6 +3600,65 @@
dev->dvb_xfer_bulk ? "bulk" : "isoc");
}
+ if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) {
+ dev->dev_next->ts = SECONDARY_TS;
+ dev->dev_next->alt = -1;
+ dev->dev_next->is_audio_only = has_vendor_audio &&
+ !(has_video || has_dvb);
+ dev->dev_next->has_video = false;
+ dev->dev_next->ifnum = ifnum;
+ dev->dev_next->model = id->driver_info;
+
+ mutex_init(&dev->dev_next->lock);
+ retval = em28xx_init_dev(dev->dev_next, udev, interface,
+ dev->dev_next->devno);
+ if (retval)
+ goto err_free;
+
+ dev->dev_next->board.ir_codes = NULL; /* No IR for 2nd tuner */
+ dev->dev_next->board.has_ir_i2c = 0; /* No IR for 2nd tuner */
+
+ if (usb_xfer_mode < 0) {
+ if (dev->dev_next->board.is_webcam)
+ try_bulk = 1;
+ else
+ try_bulk = 0;
+ } else {
+ try_bulk = usb_xfer_mode > 0;
+ }
+
+ /* Select USB transfer types to use */
+ if (has_dvb) {
+ if (!dev->dvb_ep_isoc_ts2 ||
+ (try_bulk && dev->dvb_ep_bulk_ts2))
+ dev->dev_next->dvb_xfer_bulk = 1;
+ printk(DRIVER_NAME "dvb ts2 set to %s mode.\n",
+ dev->dev_next->dvb_xfer_bulk ? "bulk" : "isoc");
+ }
+
+ dev->dev_next->dvb_ep_isoc = dev->dvb_ep_isoc_ts2;
+ dev->dev_next->dvb_ep_bulk = dev->dvb_ep_bulk_ts2;
+ dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2;
+ dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc;
+
+ /* Configuare hardware to support TS2*/
+ if (dev->dvb_xfer_bulk) {
+ /* The ep4 and ep5 are configuared for BULK */
+ em28xx_write_reg(dev, 0x0b, 0x96);
+ mdelay(100);
+ em28xx_write_reg(dev, 0x0b, 0x80);
+ mdelay(100);
+ } else {
+ /* The ep4 and ep5 are configuared for ISO */
+ em28xx_write_reg(dev, 0x0b, 0x96);
+ mdelay(100);
+ em28xx_write_reg(dev, 0x0b, 0x82);
+ mdelay(100);
+ }
+
+ kref_init(&dev->dev_next->ref);
+ }
+
kref_init(&dev->ref);
request_modules(dev);
@@ -3528,6 +3696,13 @@
if (!dev)
return;
+ if (dev->dev_next != NULL) {
+ dev->dev_next->disconnected = 1;
+ printk(DRIVER_NAME "Disconnecting %s\n",
+ dev->dev_next->name);
+ flush_request_modules(dev->dev_next);
+ }
+
dev->disconnected = 1;
em28xx_info("Disconnecting %s\n", dev->name);
@@ -3536,7 +3711,14 @@
em28xx_close_extension(dev);
+ if (dev->dev_next != NULL)
+ em28xx_release_resources(dev->dev_next);
em28xx_release_resources(dev);
+
+ if (dev->dev_next != NULL) {
+ kref_put(&dev->dev_next->ref, em28xx_free_device);
+ dev->dev_next = NULL;
+ }
kref_put(&dev->ref, em28xx_free_device);
}
diff -Nur a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
--- a/drivers/media/usb/em28xx/em28xx-core.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/em28xx/em28xx-core.c 2019-04-02 08:30:40.204091800 +0200
@@ -636,10 +636,19 @@
dev->chip_id == CHIP_ID_EM28174 ||
dev->chip_id == CHIP_ID_EM28178) {
/* The Transport Stream Enable Register moved in em2874 */
- rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
- start ?
- EM2874_TS1_CAPTURE_ENABLE : 0x00,
- EM2874_TS1_CAPTURE_ENABLE);
+ if (dev->ts == PRIMARY_TS) {
+ rc = em28xx_write_reg_bits(dev,
+ EM2874_R5F_TS_ENABLE,
+ start ?
+ EM2874_TS1_CAPTURE_ENABLE : 0x00,
+ EM2874_TS1_CAPTURE_ENABLE);
+ } else {
+ rc = em28xx_write_reg_bits(dev,
+ EM2874_R5F_TS_ENABLE,
+ start ?
+ EM2874_TS2_CAPTURE_ENABLE : 0x00,
+ EM2874_TS2_CAPTURE_ENABLE);
+ }
} else {
/* FIXME: which is the best order? */
/* video registers are sampled by VREF */
@@ -1073,7 +1082,11 @@
mutex_lock(&em28xx_devlist_mutex);
list_add_tail(&ops->next, &em28xx_extension_devlist);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
- ops->init(dev);
+ if (ops->init) {
+ ops->init(dev);
+ if (dev->dev_next != NULL)
+ ops->init(dev->dev_next);
+ }
}
mutex_unlock(&em28xx_devlist_mutex);
printk(KERN_INFO "em28xx: Registered (%s) extension\n", ops->name);
@@ -1087,7 +1100,11 @@
mutex_lock(&em28xx_devlist_mutex);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
- ops->fini(dev);
+ if (ops->fini) {
+ if (dev->dev_next != NULL)
+ ops->fini(dev->dev_next);
+ ops->fini(dev);
+ }
}
list_del(&ops->next);
mutex_unlock(&em28xx_devlist_mutex);
@@ -1102,8 +1119,11 @@
mutex_lock(&em28xx_devlist_mutex);
list_add_tail(&dev->devlist, &em28xx_devlist);
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
- if (ops->init)
- ops->init(dev);
+ if (ops->init) {
+ ops->init(dev);
+ if (dev->dev_next != NULL)
+ ops->init(dev->dev_next);
+ }
}
mutex_unlock(&em28xx_devlist_mutex);
}
@@ -1114,8 +1134,11 @@
mutex_lock(&em28xx_devlist_mutex);
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
- if (ops->fini)
- ops->fini(dev);
+ if (ops->fini) {
+ if (dev->dev_next != NULL)
+ ops->fini(dev->dev_next);
+ ops->fini(dev);
+ }
}
list_del(&dev->devlist);
mutex_unlock(&em28xx_devlist_mutex);
@@ -1130,6 +1153,8 @@
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->suspend)
ops->suspend(dev);
+ if (dev->dev_next != NULL)
+ ops->suspend(dev->dev_next);
}
mutex_unlock(&em28xx_devlist_mutex);
return 0;
@@ -1144,6 +1169,8 @@
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->resume)
ops->resume(dev);
+ if (dev->dev_next != NULL)
+ ops->resume(dev->dev_next);
}
mutex_unlock(&em28xx_devlist_mutex);
return 0;
diff -Nur a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
--- a/drivers/media/usb/em28xx/em28xx-dvb.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c 2019-04-02 08:30:40.206087100 +0200
@@ -211,7 +211,6 @@
dvb_alt = dev->dvb_alt_isoc;
}
- usb_set_interface(dev->udev, dev->ifnum, dvb_alt);
rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
if (rc < 0)
return rc;
@@ -1031,8 +1030,9 @@
static int em28xx_dvb_init(struct em28xx *dev)
{
- int result = 0;
+ int result = 0, dvb_alt = 0;
struct em28xx_dvb *dvb;
+ struct usb_device *udev;
if (dev->is_audio_only) {
/* Shouldn't initialize IR for this interface */
@@ -1726,6 +1726,76 @@
dvb->i2c_client_tuner = client;
}
break;
+ case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
+ {
+ struct i2c_adapter *adapter;
+ struct i2c_client *client;
+ struct i2c_board_info info;
+ struct si2168_config si2168_config;
+ struct si2157_config si2157_config;
+
+ /* attach demod */
+ memset(&si2168_config, 0, sizeof(si2168_config));
+ si2168_config.i2c_adapter = &adapter;
+ si2168_config.fe = &dvb->fe[0];
+ si2168_config.ts_mode = SI2168_TS_SERIAL;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+ if (dev->ts == PRIMARY_TS)
+ info.addr = 0x64;
+ else
+ info.addr = 0x67;
+ info.platform_data = &si2168_config;
+ request_module(info.type);
+ client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+ if (client == NULL || client->dev.driver == NULL) {
+ result = -ENODEV;
+ goto out_free;
+ }
+
+ if (!try_module_get(client->dev.driver->owner)) {
+ i2c_unregister_device(client);
+ result = -ENODEV;
+ goto out_free;
+ }
+
+ dvb->i2c_client_demod = client;
+
+ /* attach tuner */
+ memset(&si2157_config, 0, sizeof(si2157_config));
+ si2157_config.fe = dvb->fe[0];
+ si2157_config.if_port = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+ si2157_config.mdev = dev->media_dev;
+#endif
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+ if (dev->ts == PRIMARY_TS)
+ info.addr = 0x60;
+ else
+ info.addr = 0x63;
+ info.platform_data = &si2157_config;
+ request_module(info.type);
+ client = i2c_new_device(adapter, &info);
+ if (client == NULL || client->dev.driver == NULL) {
+ module_put(dvb->i2c_client_demod->dev.driver->owner);
+ i2c_unregister_device(dvb->i2c_client_demod);
+ result = -ENODEV;
+ goto out_free;
+ }
+
+ if (!try_module_get(client->dev.driver->owner)) {
+ i2c_unregister_device(client);
+ module_put(dvb->i2c_client_demod->dev.driver->owner);
+ i2c_unregister_device(dvb->i2c_client_demod);
+ result = -ENODEV;
+ goto out_free;
+ }
+
+ dvb->i2c_client_tuner = client;
+
+ }
+ break;
default:
em28xx_errdev("/2: The frontend of your DVB/ATSC card"
" isn't supported yet\n");
@@ -1747,6 +1817,14 @@
if (result < 0)
goto out_free;
+ if (dev->dvb_xfer_bulk) {
+ dvb_alt = 0;
+ } else { /* isoc */
+ dvb_alt = dev->dvb_alt_isoc;
+ }
+
+ udev = interface_to_usbdev(dev->intf);
+ usb_set_interface(udev, dev->ifnum, dvb_alt);
em28xx_info("DVB extension successfully initialized\n");
kref_get(&dev->ref);
diff -Nur a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
--- a/drivers/media/usb/em28xx/em28xx-reg.h 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/em28xx/em28xx-reg.h 2019-04-02 08:30:40.209080400 +0200
@@ -193,6 +193,19 @@
/* em2874 registers */
#define EM2874_R50_IR_CONFIG 0x50
#define EM2874_R51_IR 0x51
+#define EM2874_R5D_TS1_PKT_SIZE 0x5d
+#define EM2874_R5E_TS2_PKT_SIZE 0x5e
+ /*
+ * For both TS1 and TS2, In isochronous mode:
+ * 0x01 188 bytes
+ * 0x02 376 bytes
+ * 0x03 564 bytes
+ * 0x04 752 bytes
+ * 0x05 940 bytes
+ * In bulk mode:
+ * 0x01..0xff total packet count in 188-byte
+ */
+
#define EM2874_R5F_TS_ENABLE 0x5f
/* em2874/174/84, em25xx, em276x/7x/8x GPIO registers */

158
package/kernel/patches/gfutures/0009-dib7000-linux_4.4.179.patch

@ -0,0 +1,158 @@
diff -Nur a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
--- a/drivers/media/usb/dvb-usb/dib0700_core.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c 2019-02-23 09:05:14.000000000 +0100
@@ -783,6 +783,9 @@
/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
+ if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1)
+ return -ENODEV;
+
purb = usb_alloc_urb(0, GFP_KERNEL);
if (purb == NULL) {
err("rc usb alloc urb failed");
diff -Nur a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c 2019-02-23 09:05:14.000000000 +0100
@@ -294,7 +294,7 @@
stk7700d_dib7000p_mt2266_config)
!= 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
}
@@ -328,7 +328,7 @@
stk7700d_dib7000p_mt2266_config)
!= 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
}
@@ -433,6 +433,7 @@
state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
break;
case XC2028_RESET_CLK:
+ case XC2028_I2C_FLUSH:
break;
default:
err("%s: unknown command %d, arg %d\n", __func__,
@@ -481,7 +482,7 @@
&stk7700ph_dib7700_xc3028_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -1012,7 +1013,7 @@
&dib7070p_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -1070,7 +1071,7 @@
&dib7770p_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3038,7 +3039,7 @@
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
@@ -3091,7 +3092,7 @@
/* initialize IC 0 */
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3121,7 +3122,7 @@
i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3196,7 +3197,7 @@
1, 0x10, &tfe7790p_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
@@ -3291,7 +3292,7 @@
stk7070pd_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3366,7 +3367,7 @@
stk7070pd_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
}
@@ -3602,7 +3603,7 @@
if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
/* Demodulator not found for some reason? */
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
diff -Nur a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
--- a/drivers/media/usb/dvb-usb/dibusb-common.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c 2019-02-23 09:05:14.000000000 +0100
@@ -179,8 +179,20 @@
int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
{
- u8 wbuf[1] = { offs };
- return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
+ u8 *buf;
+ int rc;
+
+ buf = kmalloc(2, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ buf[0] = offs;
+
+ rc = dibusb_i2c_msg(d, 0x50, &buf[0], 1, &buf[1], 1);
+ *val = buf[1];
+ kfree(buf);
+
+ return rc;
}
EXPORT_SYMBOL(dibusb_read_eeprom_byte);

67
package/kernel/patches/gfutures/0010-dvb-usb-linux_4.4.179.patch

@ -0,0 +1,67 @@
diff -Nur a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 2017-07-31 15:25:15.000000000 +0200
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 2019-02-23 09:05:14.000000000 +0100
@@ -35,42 +35,51 @@
int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
{
- struct hexline hx;
- u8 reset;
- int ret,pos=0;
+ struct hexline *hx;
+ u8 *buf;
+ int ret, pos = 0;
+ u16 cpu_cs_register = cypress[type].cpu_cs_register;
+
+ buf = kmalloc(sizeof(*hx), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ hx = (struct hexline *)buf;
/* stop the CPU */
- reset = 1;
- if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+ buf[0] = 1;
+ if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
err("could not stop the USB controller CPU.");
- while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
- deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
- ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
+ while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
+ deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk);
+ ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
- if (ret != hx.len) {
+ if (ret != hx->len) {
err("error while transferring firmware "
"(transferred size: %d, block size: %d)",
- ret,hx.len);
+ ret, hx->len);
ret = -EINVAL;
break;
}
}
if (ret < 0) {
err("firmware download failed at %d with %d",pos,ret);
+ kfree(buf);
return ret;
}
if (ret == 0) {
/* restart the CPU */
- reset = 0;
- if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
+ buf[0] = 0;
+ if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
} else
ret = -EIO;
+ kfree(buf);
+
return ret;
}
EXPORT_SYMBOL(usb_cypress_load_firmware);

8663
package/kernel/patches/gfutures/0011-wifi-linux_4.4.183.patch

File diff suppressed because it is too large

36
package/kernel/patches/gfutures/0012-move-default-dialect-to-SMB3.patch

@ -0,0 +1,36 @@
[SMB3] Improve security, move default dialect to SMB3 from old CIFS
Due to recent publicity about security vulnerabilities in the
much older CIFS dialect, move the default dialect to the
widely accepted (and quite secure) SMB3.0 dialect from the
old default of the CIFS dialect.
We do not want to be encouraging use of less secure dialects,
and both Microsoft and CERT now strongly recommend not using the
older CIFS dialect (SMB Security Best Practices
"recommends disabling SMBv1").
SMB3 is both secure and widely available: in Windows 8 and later,
Samba and Macs.
Users can still choose to explicitly mount with the less secure
dialect (for old servers) by choosing "vers=1.0" on the cifs
mount
Signed-off-by: Steve French <smfrench@gmail.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
--- a/fs/cifs/connect.c 2019-10-19 09:34:13.448215659 +0200
+++ b/fs/cifs/connect.c 2019-10-19 09:41:22.938494534 +0200
@@ -1274,9 +1274,9 @@
vol->actimeo = CIFS_DEF_ACTIMEO;
- /* FIXME: add autonegotiation -- for now, SMB1 is default */
- vol->ops = &smb1_operations;
- vol->vals = &smb1_values;
+ /* FIXME: add autonegotiation for SMB3 or later rather than just SMB3 */
+ vol->ops = &smb30_operations; /* both secure and accepted widely */
+ vol->vals = &smb302_values;
if (!mountdata)
goto cifs_parse_mount_err;

50
package/kernel/patches/gfutures/0013-modules_mark__inittest__exittest_as__maybe_unused.patch

@ -0,0 +1,50 @@
From 89134f0918ec3bf4614ac2f9258543940e611f01 Mon Sep 17 00:00:00 2001
From: Arnd Bergmann <arnd@arndb.de>
Date: Wed, 1 Feb 2017 18:00:14 +0100
Subject: modules: mark __inittest/__exittest as __maybe_unused
commit 1f318a8bafcfba9f0d623f4870c4e890fd22e659 upstream.
clang warns about unused inline functions by default:
arch/arm/crypto/aes-cipher-glue.c:68:1: warning: unused function '__inittest' [-Wunused-function]
arch/arm/crypto/aes-cipher-glue.c:69:1: warning: unused function '__exittest' [-Wunused-function]
As these appear in every single module, let's just disable the warnings by marking the
two functions as __maybe_unused.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Acked-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Jessica Yu <jeyu@redhat.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/module.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'include/linux/module.h')
diff --git a/include/linux/module.h b/include/linux/module.h
index c9f2f85017ad..dfe5c2e25ba1 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -125,13 +125,13 @@ extern void cleanup_module(void);
/* Each module must use one module_init(). */
#define module_init(initfn) \
- static inline initcall_t __inittest(void) \
+ static inline initcall_t __maybe_unused __inittest(void) \
{ return initfn; } \
int init_module(void) __attribute__((alias(#initfn)));
/* This is only required if you want to be unloadable. */
#define module_exit(exitfn) \
- static inline exitcall_t __exittest(void) \
+ static inline exitcall_t __maybe_unused __exittest(void) \
{ return exitfn; } \
void cleanup_module(void) __attribute__((alias(#exitfn)));
--
cgit 1.2-0.3.lf.el7

84
package/kernel/patches/gfutures/0014-includelinuxmodule_h_copy__init__exit_attrs_to_initcleanup_module.patch

@ -0,0 +1,84 @@
From 170051d60cf08f9ae2cf296fb8410afdf56a911f Mon Sep 17 00:00:00 2001
From: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
Date: Sat, 19 Jan 2019 20:59:34 +0100
Subject: include/linux/module.h: copy __init/__exit attrs to
init/cleanup_module
[ Upstream commit a6e60d84989fa0e91db7f236eda40453b0e44afa ]
The upcoming GCC 9 release extends the -Wmissing-attributes warnings
(enabled by -Wall) to C and aliases: it warns when particular function
attributes are missing in the aliases but not in their target.
In particular, it triggers for all the init/cleanup_module
aliases in the kernel (defined by the module_init/exit macros),
ending up being very noisy.
These aliases point to the __init/__exit functions of a module,
which are defined as __cold (among other attributes). However,
the aliases themselves do not have the __cold attribute.
Since the compiler behaves differently when compiling a __cold
function as well as when compiling paths leading to calls
to __cold functions, the warning is trying to point out
the possibly-forgotten attribute in the alias.
In order to keep the warning enabled, we decided to silence
this case. Ideally, we would mark the aliases directly
as __init/__exit. However, there are currently around 132 modules
in the kernel which are missing __init/__exit in their init/cleanup
functions (either because they are missing, or for other reasons,
e.g. the functions being called from somewhere else); and
a section mismatch is a hard error.
A conservative alternative was to mark the aliases as __cold only.
However, since we would like to eventually enforce __init/__exit
to be always marked, we chose to use the new __copy function
attribute (introduced by GCC 9 as well to deal with this).
With it, we copy the attributes used by the target functions
into the aliases. This way, functions that were not marked
as __init/__exit won't have their aliases marked either,
and therefore there won't be a section mismatch.
Note that the warning would go away marking either the extern
declaration, the definition, or both. However, we only mark
the definition of the alias, since we do not want callers
(which only see the declaration) to be compiled as if the function
was __cold (and therefore the paths leading to those calls
would be assumed to be unlikely).
Link: https://lore.kernel.org/lkml/20190123173707.GA16603@gmail.com/
Link: https://lore.kernel.org/lkml/20190206175627.GA20399@gmail.com/
Suggested-by: Martin Sebor <msebor@gcc.gnu.org>
Acked-by: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/module.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'include/linux/module.h')
diff --git a/include/linux/module.h b/include/linux/module.h
index dfe5c2e25ba1..d237d0574179 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -127,13 +127,13 @@ extern void cleanup_module(void);
#define module_init(initfn) \
static inline initcall_t __maybe_unused __inittest(void) \
{ return initfn; } \
- int init_module(void) __attribute__((alias(#initfn)));
+ int init_module(void) __copy(initfn) __attribute__((alias(#initfn)));
/* This is only required if you want to be unloadable. */
#define module_exit(exitfn) \
static inline exitcall_t __maybe_unused __exittest(void) \
{ return exitfn; } \
- void cleanup_module(void) __attribute__((alias(#exitfn)));
+ void cleanup_module(void) __copy(exitfn) __attribute__((alias(#exitfn)));
#endif
--
cgit 1.2-0.3.lf.el7

51
package/kernel/patches/gfutures/0015-Backport_minimal_compiler_attributes_h_to_support_GCC_9.patch

@ -0,0 +1,51 @@
From edc966de8725f9186cc9358214da89d335f0e0bd Mon Sep 17 00:00:00 2001
From: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
Date: Fri, 2 Aug 2019 12:37:56 +0200
Subject: Backport minimal compiler_attributes.h to support GCC 9
This adds support for __copy to v4.9.y so that we can use it in
init/exit_module to avoid -Werror=missing-attributes errors on GCC 9.
Link: https://lore.kernel.org/lkml/259986242.BvXPX32bHu@devpool35/
Cc: <stable@vger.kernel.org>
Suggested-by: Rolf Eike Beer <eb@emlix.com>
Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/compiler.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
(limited to 'include/linux')
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index ed772311ec1f..5508011cc0c7 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -52,6 +52,22 @@ extern void __chk_io_ptr(const volatile void __iomem *);
#ifdef __KERNEL__
+/*
+ * Minimal backport of compiler_attributes.h to add support for __copy
+ * to v4.9.y so that we can use it in init/exit_module to avoid
+ * -Werror=missing-attributes errors on GCC 9.
+ */
+#ifndef __has_attribute
+# define __has_attribute(x) __GCC4_has_attribute_##x
+# define __GCC4_has_attribute___copy__ 0
+#endif
+
+#if __has_attribute(__copy__)
+# define __copy(symbol) __attribute__((__copy__(symbol)))
+#else
+# define __copy(symbol)
+#endif
+
#ifdef __GNUC__
#include <linux/compiler-gcc.h>
#endif
--
cgit 1.2-0.3.lf.el7

33
package/kernel/patches/gfutures/0016-mn88472_reset_stream_ID_reg_if_no_PLP_given.patch

@ -0,0 +1,33 @@
From 07d45a42fa21b54d83e563565699d25bde9f8cbe Mon Sep 17 00:00:00 2001
From: Olli Salonen <olli.salonen@iki.fi>
Date: Sun, 30 Jul 2017 08:34:48 -0400
Subject: media: mn88472: reset stream ID reg if no PLP given
If the PLP given is NO_STREAM_ID_FILTER (~0u) don't try to set that into the PLP register. Set PLP to 0 instead.
Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
drivers/media/dvb-frontends/mn88472.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'drivers/media/dvb-frontends/mn88472.c')
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index f6938f9607ac..5e8fd63832e9 100644
--- a/drivers/staging/media/mn88472/mn88472.c
+++ b/drivers/staging/media/mn88472/mn88472.c
@@ -255,7 +255,9 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
ret = regmap_write(dev->regmap[1], 0xf6, 0x05);
if (ret)
goto err;
- ret = regmap_write(dev->regmap[2], 0x32, c->stream_id);
+ ret = regmap_write(dev->regmap[2], 0x32,
+ (c->stream_id == NO_STREAM_ID_FILTER) ? 0 :
+ c->stream_id );
if (ret)
goto err;
break;
--
cgit 1.2.3-1.el7

11
package/kernel/patches/gfutures/4_4_ieee80211-increase-scan-result-expire-time.patch

@ -1,11 +0,0 @@
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -56,7 +56,7 @@
* also linked into the probe response struct.
*/
-#define IEEE80211_SCAN_RESULT_EXPIRE (7 * HZ)
+#define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ)
static void bss_free(struct cfg80211_internal_bss *bss)
{
Loading…
Cancel
Save