linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver
@ 2014-11-12  4:11 Antti Palosaari
  2014-11-12  4:11 ` [PATCH 01/11] mn88472: Panasonic MN88472 demod driver (DVB-C only) Antti Palosaari
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Reverse-engineered driver, which I moved to staging, due to
quality issues. Chip documentation would be nice. Any help to
pressure Panasonic to release documentation is welcome.


MS recently released Xbox One Digital TV Tuner is build upon that same demod chip.
https://tvheadend.org/boards/5/topics/13685


Here is device internals:
http://blog.palosaari.fi/2013/10/naked-hardware-14-dvb-t2-usb-tv-stick.html



Antti Palosaari (11):
  mn88472: Panasonic MN88472 demod driver (DVB-C only)
  mn88472: correct attach symbol name
  mn88472: add small delay to wait DVB-C lock
  mn88472: rename mn88472_c.c => mn88472.c
  mn88472: rename state to dev
  mn88472: convert driver to I2C client
  mn88472: Convert driver to I2C RegMap API
  mn88472: implement DVB-T and DVB-T2
  mn88472: move to staging
  mn88472: add staging TODO
  MAINTAINERS: add mn88472 (Panasonic MN88472)

 MAINTAINERS                                  |  11 +
 drivers/media/dvb-frontends/mn88472.h        |  38 ++
 drivers/staging/media/Kconfig                |   2 +
 drivers/staging/media/Makefile               |   1 +
 drivers/staging/media/mn88472/Kconfig        |   7 +
 drivers/staging/media/mn88472/Makefile       |   5 +
 drivers/staging/media/mn88472/TODO           |  21 ++
 drivers/staging/media/mn88472/mn88472.c      | 523 +++++++++++++++++++++++++++
 drivers/staging/media/mn88472/mn88472_priv.h |  36 ++
 9 files changed, 644 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/mn88472.h
 create mode 100644 drivers/staging/media/mn88472/Kconfig
 create mode 100644 drivers/staging/media/mn88472/Makefile
 create mode 100644 drivers/staging/media/mn88472/TODO
 create mode 100644 drivers/staging/media/mn88472/mn88472.c
 create mode 100644 drivers/staging/media/mn88472/mn88472_priv.h

-- 
http://palosaari.fi/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 01/11] mn88472: Panasonic MN88472 demod driver (DVB-C only)
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 02/11] mn88472: correct attach symbol name Antti Palosaari
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Only DVB-C mode is supported, DVB-T and DVB-T2 are not supported.
Very much feature reduced version, no signal statistics nor normal
chip configuration options.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/Kconfig        |   7 +
 drivers/media/dvb-frontends/Makefile       |   2 +
 drivers/media/dvb-frontends/mn88472.h      |  46 ++++
 drivers/media/dvb-frontends/mn88472_c.c    | 414 +++++++++++++++++++++++++++++
 drivers/media/dvb-frontends/mn88472_priv.h |  36 +++
 5 files changed, 505 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/mn88472.h
 create mode 100644 drivers/media/dvb-frontends/mn88472_c.c
 create mode 100644 drivers/media/dvb-frontends/mn88472_priv.h

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 6c75418..02bada4 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -441,6 +441,13 @@ config DVB_CXD2820R
 	help
 	  Say Y when you want to support this frontend.
 
+config DVB_MN88472
+	tristate "Panasonic MN88472"
+	depends on DVB_CORE && I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  Say Y when you want to support this frontend.
+
 config DVB_RTL2830
 	tristate "Realtek RTL2830 DVB-T"
 	depends on DVB_CORE && I2C
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index ba59df6..27d82b6 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -15,6 +15,7 @@ stv0900-objs := stv0900_core.o stv0900_sw.o
 drxd-objs := drxd_firm.o drxd_hard.o
 cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
 drxk-objs := drxk_hard.o
+mn88472-objs := mn88472_c.o
 
 obj-$(CONFIG_DVB_PLL) += dvb-pll.o
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -103,6 +104,7 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
 obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
 obj-$(CONFIG_DVB_STV0367) += stv0367.o
 obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
+obj-$(CONFIG_DVB_MN88472) += mn88472.o
 obj-$(CONFIG_DVB_DRXK) += drxk.o
 obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
 obj-$(CONFIG_DVB_SI2165) += si2165.o
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
new file mode 100644
index 0000000..29aa485
--- /dev/null
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -0,0 +1,46 @@
+/*
+ * Panasonic MN88472 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef MN88472_H
+#define MN88472_H
+
+#include <linux/dvb/frontend.h>
+
+struct mn88472_c_config {
+	/*
+	 * max bytes I2C client could write
+	 * Value must be set.
+	 */
+	int i2c_wr_max;
+};
+
+#if IS_ENABLED(CONFIG_DVB_MN88472)
+extern struct dvb_frontend *mn88472_c_attach(
+	const struct mn88472_c_config *cfg,
+	struct i2c_adapter *i2c
+);
+#else
+static inline struct dvb_frontend *mn88472_c_attach(
+	const struct mn88472_c_config *cfg,
+	struct i2c_adapter *i2c
+)
+{
+	dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/mn88472_c.c b/drivers/media/dvb-frontends/mn88472_c.c
new file mode 100644
index 0000000..59d48e7
--- /dev/null
+++ b/drivers/media/dvb-frontends/mn88472_c.c
@@ -0,0 +1,414 @@
+/*
+ * Panasonic MN88472 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "mn88472_priv.h"
+
+static struct dvb_frontend_ops mn88472_ops_c;
+
+/* write multiple registers */
+static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len)
+{
+#define MAX_WR_LEN 21
+#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
+	int ret;
+	u8 buf[MAX_WR_XFER_LEN];
+	struct i2c_msg msg[1] = {
+		{
+			.addr = (reg >> 8) & 0xff,
+			.flags = 0,
+			.len = 1 + len,
+			.buf = buf,
+		}
+	};
+
+	if (WARN_ON(len > MAX_WR_LEN))
+		return -EINVAL;
+
+	buf[0] = (reg >> 0) & 0xff;
+	memcpy(&buf[1], val, len);
+
+	ret = i2c_transfer(s->i2c, msg, 1);
+	if (ret == 1) {
+		ret = 0;
+	} else {
+		dev_warn(&s->i2c->dev,
+				"%s: i2c wr failed=%d reg=%02x len=%d\n",
+				KBUILD_MODNAME, ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+
+	return ret;
+}
+
+/* read multiple registers */
+static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len)
+{
+#define MAX_RD_LEN 2
+#define MAX_RD_XFER_LEN (MAX_RD_LEN)
+	int ret;
+	u8 buf[MAX_RD_XFER_LEN];
+	struct i2c_msg msg[2] = {
+		{
+			.addr = (reg >> 8) & 0xff,
+			.flags = 0,
+			.len = 1,
+			.buf = buf,
+		}, {
+			.addr = (reg >> 8) & 0xff,
+			.flags = I2C_M_RD,
+			.len = len,
+			.buf = buf,
+		}
+	};
+
+	if (WARN_ON(len > MAX_RD_LEN))
+		return -EINVAL;
+
+	buf[0] = (reg >> 0) & 0xff;
+
+	ret = i2c_transfer(s->i2c, msg, 2);
+	if (ret == 2) {
+		memcpy(val, buf, len);
+		ret = 0;
+	} else {
+		dev_warn(&s->i2c->dev,
+				"%s: i2c rd failed=%d reg=%02x len=%d\n",
+				KBUILD_MODNAME, ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+
+	return ret;
+}
+
+/* write single register */
+static int mn88472_wreg(struct mn88472_state *s, u16 reg, u8 val)
+{
+	return mn88472_wregs(s, reg, &val, 1);
+}
+
+/* read single register */
+static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val)
+{
+	return mn88472_rregs(s, reg, val, 1);
+}
+
+static int mn88472_set_frontend_c(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	u32 if_frequency = 0;
+	dev_dbg(&s->i2c->dev,
+			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
+			__func__, c->delivery_system, c->modulation,
+			c->frequency, c->symbol_rate, c->inversion);
+
+	if (!s->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params) {
+		ret = fe->ops.tuner_ops.set_params(fe);
+		if (ret)
+			goto err;
+	}
+
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+		if (ret)
+			goto err;
+
+		dev_dbg(&s->i2c->dev, "%s: get_if_frequency=%d\n",
+				__func__, if_frequency);
+	}
+
+	if (if_frequency != 5070000) {
+		dev_err(&s->i2c->dev, "%s: IF frequency %d not supported\n",
+				KBUILD_MODNAME, if_frequency);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = mn88472_wregs(s, 0x1c08, "\x1d", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18d9, "\xe3", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c83, "\x01", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c00, "\x66\x00\x01\x04\x00", 5);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c10,
+			"\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1846, "\x00", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18ae, "\x00", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18b0, "\x0b", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18b4, "\x00", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18cd, "\x17", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18d4, "\x09", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18d6, "\x48", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1a00, "\xb0", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1cf8, "\x9f", 1);
+	if (ret)
+		goto err;
+
+	s->delivery_system = c->delivery_system;
+
+	return 0;
+err:
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int mn88472_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	int ret;
+	u8 u8tmp;
+
+	*status = 0;
+
+	if (!s->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	ret = mn88472_rreg(s, 0x1a84, &u8tmp);
+	if (ret)
+		goto err;
+
+	if (u8tmp == 0x08)
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+				FE_HAS_SYNC | FE_HAS_LOCK;
+
+	return 0;
+err:
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int mn88472_init_c(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	int ret, len, remaining;
+	const struct firmware *fw = NULL;
+	u8 *fw_file = MN88472_FIRMWARE;
+	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
+
+	/* set cold state by default */
+	s->warm = false;
+
+	/* power on */
+	ret = mn88472_wreg(s, 0x1c05, 0x00);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c0b, "\x00\x00", 2);
+	if (ret)
+		goto err;
+
+	/* request the firmware, this will block and timeout */
+	ret = request_firmware(&fw, fw_file, s->i2c->dev.parent);
+	if (ret) {
+		dev_err(&s->i2c->dev, "%s: firmare file '%s' not found\n",
+				KBUILD_MODNAME, fw_file);
+		goto err;
+	}
+
+	dev_info(&s->i2c->dev, "%s: downloading firmware from file '%s'\n",
+			KBUILD_MODNAME, fw_file);
+
+	ret = mn88472_wreg(s, 0x18f5, 0x03);
+	if (ret)
+		goto err;
+
+	for (remaining = fw->size; remaining > 0;
+			remaining -= (s->cfg->i2c_wr_max - 1)) {
+		len = remaining;
+		if (len > (s->cfg->i2c_wr_max - 1))
+			len = (s->cfg->i2c_wr_max - 1);
+
+		ret = mn88472_wregs(s, 0x18f6,
+				&fw->data[fw->size - remaining], len);
+		if (ret) {
+			dev_err(&s->i2c->dev,
+					"%s: firmware download failed=%d\n",
+					KBUILD_MODNAME, ret);
+			goto err;
+		}
+	}
+
+	ret = mn88472_wreg(s, 0x18f5, 0x00);
+	if (ret)
+		goto err;
+
+	release_firmware(fw);
+	fw = NULL;
+
+	/* warm state */
+	s->warm = true;
+
+	return 0;
+err:
+	if (fw)
+		release_firmware(fw);
+
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int mn88472_sleep_c(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	int ret;
+	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
+
+	/* power off */
+	ret = mn88472_wreg(s, 0x1c0b, 0x30);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wreg(s, 0x1c05, 0x3e);
+	if (ret)
+		goto err;
+
+	s->delivery_system = SYS_UNDEFINED;
+
+	return 0;
+err:
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static void mn88472_release_c(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	kfree(s);
+}
+
+struct dvb_frontend *mn88472_attach_c(const struct mn88472_c_config *cfg,
+		struct i2c_adapter *i2c)
+{
+	int ret;
+	struct mn88472_state *s;
+	u8 u8tmp;
+	dev_dbg(&i2c->dev, "%s:\n", __func__);
+
+	/* allocate memory for the internal state */
+	s = kzalloc(sizeof(struct mn88472_state), GFP_KERNEL);
+	if (!s) {
+		ret = -ENOMEM;
+		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+		goto err;
+	}
+
+	s->cfg = cfg;
+	s->i2c = i2c;
+
+	/* check demod responds to I2C */
+	ret = mn88472_rreg(s, 0x1c00, &u8tmp);
+	if (ret)
+		goto err;
+
+	/* create dvb_frontend */
+	memcpy(&s->fe.ops, &mn88472_ops_c, sizeof(struct dvb_frontend_ops));
+	s->fe.demodulator_priv = s;
+
+	return &s->fe;
+err:
+	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+	kfree(s);
+	return NULL;
+}
+EXPORT_SYMBOL(mn88472_attach_c);
+
+static struct dvb_frontend_ops mn88472_ops_c = {
+	.delsys = {SYS_DVBC_ANNEX_A},
+	.info = {
+		.name = "Panasonic MN88472",
+		.caps =	FE_CAN_FEC_1_2			|
+			FE_CAN_FEC_2_3			|
+			FE_CAN_FEC_3_4			|
+			FE_CAN_FEC_5_6			|
+			FE_CAN_FEC_7_8			|
+			FE_CAN_FEC_AUTO			|
+			FE_CAN_QPSK			|
+			FE_CAN_QAM_16			|
+			FE_CAN_QAM_32			|
+			FE_CAN_QAM_64			|
+			FE_CAN_QAM_128			|
+			FE_CAN_QAM_256			|
+			FE_CAN_QAM_AUTO			|
+			FE_CAN_TRANSMISSION_MODE_AUTO	|
+			FE_CAN_GUARD_INTERVAL_AUTO	|
+			FE_CAN_HIERARCHY_AUTO		|
+			FE_CAN_MUTE_TS			|
+			FE_CAN_2G_MODULATION		|
+			FE_CAN_MULTISTREAM
+	},
+
+	.release = mn88472_release_c,
+
+	.init = mn88472_init_c,
+	.sleep = mn88472_sleep_c,
+
+	.set_frontend = mn88472_set_frontend_c,
+/*	.get_frontend = mn88472_get_frontend_c, */
+
+	.read_status = mn88472_read_status_c,
+/*	.read_snr = mn88472_read_snr_c, */
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(MN88472_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
new file mode 100644
index 0000000..ecade84
--- /dev/null
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -0,0 +1,36 @@
+/*
+ * Panasonic MN88472 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef MN88472_PRIV_H
+#define MN88472_PRIV_H
+
+#include "dvb_frontend.h"
+#include "mn88472.h"
+#include "dvb_math.h"
+#include <linux/firmware.h>
+#include <linux/i2c-mux.h>
+
+#define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
+
+struct mn88472_state {
+	struct i2c_adapter *i2c;
+	const struct mn88472_c_config *cfg;
+	struct dvb_frontend fe;
+	fe_delivery_system_t delivery_system;
+	bool warm; /* FW running */
+};
+
+#endif
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 02/11] mn88472: correct attach symbol name
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
  2014-11-12  4:11 ` [PATCH 01/11] mn88472: Panasonic MN88472 demod driver (DVB-C only) Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 03/11] mn88472: add small delay to wait DVB-C lock Antti Palosaari
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Wrong symbol name causes demod attach failure.

Reported-by: Benjamin Larsson <benjamin@southpole.se>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/mn88472.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
index 29aa485..c817bfb 100644
--- a/drivers/media/dvb-frontends/mn88472.h
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -28,12 +28,12 @@ struct mn88472_c_config {
 };
 
 #if IS_ENABLED(CONFIG_DVB_MN88472)
-extern struct dvb_frontend *mn88472_c_attach(
+extern struct dvb_frontend *mn88472_attach_c(
 	const struct mn88472_c_config *cfg,
 	struct i2c_adapter *i2c
 );
 #else
-static inline struct dvb_frontend *mn88472_c_attach(
+static inline struct dvb_frontend *mn88472_attach_c(
 	const struct mn88472_c_config *cfg,
 	struct i2c_adapter *i2c
 )
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 03/11] mn88472: add small delay to wait DVB-C lock
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
  2014-11-12  4:11 ` [PATCH 01/11] mn88472: Panasonic MN88472 demod driver (DVB-C only) Antti Palosaari
  2014-11-12  4:11 ` [PATCH 02/11] mn88472: correct attach symbol name Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 04/11] mn88472: rename mn88472_c.c => mn88472.c Antti Palosaari
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

400ms delay seems to be enough in order to gain DVB-C lock.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/mn88472_c.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/dvb-frontends/mn88472_c.c b/drivers/media/dvb-frontends/mn88472_c.c
index 59d48e7..b5bd326 100644
--- a/drivers/media/dvb-frontends/mn88472_c.c
+++ b/drivers/media/dvb-frontends/mn88472_c.c
@@ -105,6 +105,13 @@ static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val)
 	return mn88472_rregs(s, reg, val, 1);
 }
 
+static int mn88472_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 400;
+	return 0;
+}
+
 static int mn88472_set_frontend_c(struct dvb_frontend *fe)
 {
 	struct mn88472_state *s = fe->demodulator_priv;
@@ -398,6 +405,8 @@ static struct dvb_frontend_ops mn88472_ops_c = {
 
 	.release = mn88472_release_c,
 
+	.get_tune_settings = mn88472_get_tune_settings,
+
 	.init = mn88472_init_c,
 	.sleep = mn88472_sleep_c,
 
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 04/11] mn88472: rename mn88472_c.c => mn88472.c
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (2 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 03/11] mn88472: add small delay to wait DVB-C lock Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 05/11] mn88472: rename state to dev Antti Palosaari
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Original plan was to implement driver as one file per used demod
standard (mn88472_c.c, mn88472_t.c and mn88472_t2.c). However, that
plan was a mistake as driver code differences are so small between
different standards. Due to that rename this file and implement all
the needed functionality to that file.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/Makefile       |   1 -
 drivers/media/dvb-frontends/mn88472.c      | 423 +++++++++++++++++++++++++++++
 drivers/media/dvb-frontends/mn88472.h      |  10 +-
 drivers/media/dvb-frontends/mn88472_c.c    | 423 -----------------------------
 drivers/media/dvb-frontends/mn88472_priv.h |   2 +-
 5 files changed, 429 insertions(+), 430 deletions(-)
 create mode 100644 drivers/media/dvb-frontends/mn88472.c
 delete mode 100644 drivers/media/dvb-frontends/mn88472_c.c

diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index 27d82b6..b82225f6 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -15,7 +15,6 @@ stv0900-objs := stv0900_core.o stv0900_sw.o
 drxd-objs := drxd_firm.o drxd_hard.o
 cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
 drxk-objs := drxk_hard.o
-mn88472-objs := mn88472_c.o
 
 obj-$(CONFIG_DVB_PLL) += dvb-pll.o
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
new file mode 100644
index 0000000..a3c4ae1
--- /dev/null
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -0,0 +1,423 @@
+/*
+ * Panasonic MN88472 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "mn88472_priv.h"
+
+static struct dvb_frontend_ops mn88472_ops;
+
+/* write multiple registers */
+static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len)
+{
+#define MAX_WR_LEN 21
+#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
+	int ret;
+	u8 buf[MAX_WR_XFER_LEN];
+	struct i2c_msg msg[1] = {
+		{
+			.addr = (reg >> 8) & 0xff,
+			.flags = 0,
+			.len = 1 + len,
+			.buf = buf,
+		}
+	};
+
+	if (WARN_ON(len > MAX_WR_LEN))
+		return -EINVAL;
+
+	buf[0] = (reg >> 0) & 0xff;
+	memcpy(&buf[1], val, len);
+
+	ret = i2c_transfer(s->i2c, msg, 1);
+	if (ret == 1) {
+		ret = 0;
+	} else {
+		dev_warn(&s->i2c->dev,
+				"%s: i2c wr failed=%d reg=%02x len=%d\n",
+				KBUILD_MODNAME, ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+
+	return ret;
+}
+
+/* read multiple registers */
+static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len)
+{
+#define MAX_RD_LEN 2
+#define MAX_RD_XFER_LEN (MAX_RD_LEN)
+	int ret;
+	u8 buf[MAX_RD_XFER_LEN];
+	struct i2c_msg msg[2] = {
+		{
+			.addr = (reg >> 8) & 0xff,
+			.flags = 0,
+			.len = 1,
+			.buf = buf,
+		}, {
+			.addr = (reg >> 8) & 0xff,
+			.flags = I2C_M_RD,
+			.len = len,
+			.buf = buf,
+		}
+	};
+
+	if (WARN_ON(len > MAX_RD_LEN))
+		return -EINVAL;
+
+	buf[0] = (reg >> 0) & 0xff;
+
+	ret = i2c_transfer(s->i2c, msg, 2);
+	if (ret == 2) {
+		memcpy(val, buf, len);
+		ret = 0;
+	} else {
+		dev_warn(&s->i2c->dev,
+				"%s: i2c rd failed=%d reg=%02x len=%d\n",
+				KBUILD_MODNAME, ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+
+	return ret;
+}
+
+/* write single register */
+static int mn88472_wreg(struct mn88472_state *s, u16 reg, u8 val)
+{
+	return mn88472_wregs(s, reg, &val, 1);
+}
+
+/* read single register */
+static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val)
+{
+	return mn88472_rregs(s, reg, val, 1);
+}
+
+static int mn88472_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 400;
+	return 0;
+}
+
+static int mn88472_set_frontend(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	u32 if_frequency = 0;
+	dev_dbg(&s->i2c->dev,
+			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
+			__func__, c->delivery_system, c->modulation,
+			c->frequency, c->symbol_rate, c->inversion);
+
+	if (!s->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params) {
+		ret = fe->ops.tuner_ops.set_params(fe);
+		if (ret)
+			goto err;
+	}
+
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+		if (ret)
+			goto err;
+
+		dev_dbg(&s->i2c->dev, "%s: get_if_frequency=%d\n",
+				__func__, if_frequency);
+	}
+
+	if (if_frequency != 5070000) {
+		dev_err(&s->i2c->dev, "%s: IF frequency %d not supported\n",
+				KBUILD_MODNAME, if_frequency);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = mn88472_wregs(s, 0x1c08, "\x1d", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18d9, "\xe3", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c83, "\x01", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c00, "\x66\x00\x01\x04\x00", 5);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c10,
+			"\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1846, "\x00", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18ae, "\x00", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18b0, "\x0b", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18b4, "\x00", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18cd, "\x17", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18d4, "\x09", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x18d6, "\x48", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1a00, "\xb0", 1);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1cf8, "\x9f", 1);
+	if (ret)
+		goto err;
+
+	s->delivery_system = c->delivery_system;
+
+	return 0;
+err:
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	int ret;
+	u8 u8tmp;
+
+	*status = 0;
+
+	if (!s->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	ret = mn88472_rreg(s, 0x1a84, &u8tmp);
+	if (ret)
+		goto err;
+
+	if (u8tmp == 0x08)
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+				FE_HAS_SYNC | FE_HAS_LOCK;
+
+	return 0;
+err:
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int mn88472_init(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	int ret, len, remaining;
+	const struct firmware *fw = NULL;
+	u8 *fw_file = MN88472_FIRMWARE;
+	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
+
+	/* set cold state by default */
+	s->warm = false;
+
+	/* power on */
+	ret = mn88472_wreg(s, 0x1c05, 0x00);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wregs(s, 0x1c0b, "\x00\x00", 2);
+	if (ret)
+		goto err;
+
+	/* request the firmware, this will block and timeout */
+	ret = request_firmware(&fw, fw_file, s->i2c->dev.parent);
+	if (ret) {
+		dev_err(&s->i2c->dev, "%s: firmare file '%s' not found\n",
+				KBUILD_MODNAME, fw_file);
+		goto err;
+	}
+
+	dev_info(&s->i2c->dev, "%s: downloading firmware from file '%s'\n",
+			KBUILD_MODNAME, fw_file);
+
+	ret = mn88472_wreg(s, 0x18f5, 0x03);
+	if (ret)
+		goto err;
+
+	for (remaining = fw->size; remaining > 0;
+			remaining -= (s->cfg->i2c_wr_max - 1)) {
+		len = remaining;
+		if (len > (s->cfg->i2c_wr_max - 1))
+			len = (s->cfg->i2c_wr_max - 1);
+
+		ret = mn88472_wregs(s, 0x18f6,
+				&fw->data[fw->size - remaining], len);
+		if (ret) {
+			dev_err(&s->i2c->dev,
+					"%s: firmware download failed=%d\n",
+					KBUILD_MODNAME, ret);
+			goto err;
+		}
+	}
+
+	ret = mn88472_wreg(s, 0x18f5, 0x00);
+	if (ret)
+		goto err;
+
+	release_firmware(fw);
+	fw = NULL;
+
+	/* warm state */
+	s->warm = true;
+
+	return 0;
+err:
+	if (fw)
+		release_firmware(fw);
+
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int mn88472_sleep(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	int ret;
+	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
+
+	/* power off */
+	ret = mn88472_wreg(s, 0x1c0b, 0x30);
+	if (ret)
+		goto err;
+
+	ret = mn88472_wreg(s, 0x1c05, 0x3e);
+	if (ret)
+		goto err;
+
+	s->delivery_system = SYS_UNDEFINED;
+
+	return 0;
+err:
+	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static void mn88472_release(struct dvb_frontend *fe)
+{
+	struct mn88472_state *s = fe->demodulator_priv;
+	kfree(s);
+}
+
+struct dvb_frontend *mn88472_attach(const struct mn88472_config *cfg,
+		struct i2c_adapter *i2c)
+{
+	int ret;
+	struct mn88472_state *s;
+	u8 u8tmp;
+	dev_dbg(&i2c->dev, "%s:\n", __func__);
+
+	/* allocate memory for the internal state */
+	s = kzalloc(sizeof(struct mn88472_state), GFP_KERNEL);
+	if (!s) {
+		ret = -ENOMEM;
+		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+		goto err;
+	}
+
+	s->cfg = cfg;
+	s->i2c = i2c;
+
+	/* check demod responds to I2C */
+	ret = mn88472_rreg(s, 0x1c00, &u8tmp);
+	if (ret)
+		goto err;
+
+	/* create dvb_frontend */
+	memcpy(&s->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
+	s->fe.demodulator_priv = s;
+
+	return &s->fe;
+err:
+	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+	kfree(s);
+	return NULL;
+}
+EXPORT_SYMBOL(mn88472_attach);
+
+static struct dvb_frontend_ops mn88472_ops = {
+	.delsys = {SYS_DVBC_ANNEX_A},
+	.info = {
+		.name = "Panasonic MN88472",
+		.caps =	FE_CAN_FEC_1_2			|
+			FE_CAN_FEC_2_3			|
+			FE_CAN_FEC_3_4			|
+			FE_CAN_FEC_5_6			|
+			FE_CAN_FEC_7_8			|
+			FE_CAN_FEC_AUTO			|
+			FE_CAN_QPSK			|
+			FE_CAN_QAM_16			|
+			FE_CAN_QAM_32			|
+			FE_CAN_QAM_64			|
+			FE_CAN_QAM_128			|
+			FE_CAN_QAM_256			|
+			FE_CAN_QAM_AUTO			|
+			FE_CAN_TRANSMISSION_MODE_AUTO	|
+			FE_CAN_GUARD_INTERVAL_AUTO	|
+			FE_CAN_HIERARCHY_AUTO		|
+			FE_CAN_MUTE_TS			|
+			FE_CAN_2G_MODULATION		|
+			FE_CAN_MULTISTREAM
+	},
+
+	.release = mn88472_release,
+
+	.get_tune_settings = mn88472_get_tune_settings,
+
+	.init = mn88472_init,
+	.sleep = mn88472_sleep,
+
+	.set_frontend = mn88472_set_frontend,
+/*	.get_frontend = mn88472_get_frontend, */
+
+	.read_status = mn88472_read_status,
+/*	.read_snr = mn88472_read_snr, */
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(MN88472_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
index c817bfb..5ce6ac1 100644
--- a/drivers/media/dvb-frontends/mn88472.h
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -19,7 +19,7 @@
 
 #include <linux/dvb/frontend.h>
 
-struct mn88472_c_config {
+struct mn88472_config {
 	/*
 	 * max bytes I2C client could write
 	 * Value must be set.
@@ -28,13 +28,13 @@ struct mn88472_c_config {
 };
 
 #if IS_ENABLED(CONFIG_DVB_MN88472)
-extern struct dvb_frontend *mn88472_attach_c(
-	const struct mn88472_c_config *cfg,
+extern struct dvb_frontend *mn88472_attach(
+	const struct mn88472_config *cfg,
 	struct i2c_adapter *i2c
 );
 #else
-static inline struct dvb_frontend *mn88472_attach_c(
-	const struct mn88472_c_config *cfg,
+static inline struct dvb_frontend *mn88472_attach(
+	const struct mn88472_config *cfg,
 	struct i2c_adapter *i2c
 )
 {
diff --git a/drivers/media/dvb-frontends/mn88472_c.c b/drivers/media/dvb-frontends/mn88472_c.c
deleted file mode 100644
index b5bd326..0000000
--- a/drivers/media/dvb-frontends/mn88472_c.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Panasonic MN88472 DVB-T/T2/C demodulator driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- */
-
-#include "mn88472_priv.h"
-
-static struct dvb_frontend_ops mn88472_ops_c;
-
-/* write multiple registers */
-static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len)
-{
-#define MAX_WR_LEN 21
-#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
-	int ret;
-	u8 buf[MAX_WR_XFER_LEN];
-	struct i2c_msg msg[1] = {
-		{
-			.addr = (reg >> 8) & 0xff,
-			.flags = 0,
-			.len = 1 + len,
-			.buf = buf,
-		}
-	};
-
-	if (WARN_ON(len > MAX_WR_LEN))
-		return -EINVAL;
-
-	buf[0] = (reg >> 0) & 0xff;
-	memcpy(&buf[1], val, len);
-
-	ret = i2c_transfer(s->i2c, msg, 1);
-	if (ret == 1) {
-		ret = 0;
-	} else {
-		dev_warn(&s->i2c->dev,
-				"%s: i2c wr failed=%d reg=%02x len=%d\n",
-				KBUILD_MODNAME, ret, reg, len);
-		ret = -EREMOTEIO;
-	}
-
-	return ret;
-}
-
-/* read multiple registers */
-static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len)
-{
-#define MAX_RD_LEN 2
-#define MAX_RD_XFER_LEN (MAX_RD_LEN)
-	int ret;
-	u8 buf[MAX_RD_XFER_LEN];
-	struct i2c_msg msg[2] = {
-		{
-			.addr = (reg >> 8) & 0xff,
-			.flags = 0,
-			.len = 1,
-			.buf = buf,
-		}, {
-			.addr = (reg >> 8) & 0xff,
-			.flags = I2C_M_RD,
-			.len = len,
-			.buf = buf,
-		}
-	};
-
-	if (WARN_ON(len > MAX_RD_LEN))
-		return -EINVAL;
-
-	buf[0] = (reg >> 0) & 0xff;
-
-	ret = i2c_transfer(s->i2c, msg, 2);
-	if (ret == 2) {
-		memcpy(val, buf, len);
-		ret = 0;
-	} else {
-		dev_warn(&s->i2c->dev,
-				"%s: i2c rd failed=%d reg=%02x len=%d\n",
-				KBUILD_MODNAME, ret, reg, len);
-		ret = -EREMOTEIO;
-	}
-
-	return ret;
-}
-
-/* write single register */
-static int mn88472_wreg(struct mn88472_state *s, u16 reg, u8 val)
-{
-	return mn88472_wregs(s, reg, &val, 1);
-}
-
-/* read single register */
-static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val)
-{
-	return mn88472_rregs(s, reg, val, 1);
-}
-
-static int mn88472_get_tune_settings(struct dvb_frontend *fe,
-	struct dvb_frontend_tune_settings *s)
-{
-	s->min_delay_ms = 400;
-	return 0;
-}
-
-static int mn88472_set_frontend_c(struct dvb_frontend *fe)
-{
-	struct mn88472_state *s = fe->demodulator_priv;
-	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int ret;
-	u32 if_frequency = 0;
-	dev_dbg(&s->i2c->dev,
-			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
-			__func__, c->delivery_system, c->modulation,
-			c->frequency, c->symbol_rate, c->inversion);
-
-	if (!s->warm) {
-		ret = -EAGAIN;
-		goto err;
-	}
-
-	/* program tuner */
-	if (fe->ops.tuner_ops.set_params) {
-		ret = fe->ops.tuner_ops.set_params(fe);
-		if (ret)
-			goto err;
-	}
-
-	if (fe->ops.tuner_ops.get_if_frequency) {
-		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
-		if (ret)
-			goto err;
-
-		dev_dbg(&s->i2c->dev, "%s: get_if_frequency=%d\n",
-				__func__, if_frequency);
-	}
-
-	if (if_frequency != 5070000) {
-		dev_err(&s->i2c->dev, "%s: IF frequency %d not supported\n",
-				KBUILD_MODNAME, if_frequency);
-		ret = -EINVAL;
-		goto err;
-	}
-
-	ret = mn88472_wregs(s, 0x1c08, "\x1d", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18d9, "\xe3", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1c83, "\x01", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1c00, "\x66\x00\x01\x04\x00", 5);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1c10,
-			"\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1846, "\x00", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18ae, "\x00", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18b0, "\x0b", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18b4, "\x00", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18cd, "\x17", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18d4, "\x09", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x18d6, "\x48", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1a00, "\xb0", 1);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1cf8, "\x9f", 1);
-	if (ret)
-		goto err;
-
-	s->delivery_system = c->delivery_system;
-
-	return 0;
-err:
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
-	return ret;
-}
-
-static int mn88472_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
-{
-	struct mn88472_state *s = fe->demodulator_priv;
-	int ret;
-	u8 u8tmp;
-
-	*status = 0;
-
-	if (!s->warm) {
-		ret = -EAGAIN;
-		goto err;
-	}
-
-	ret = mn88472_rreg(s, 0x1a84, &u8tmp);
-	if (ret)
-		goto err;
-
-	if (u8tmp == 0x08)
-		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
-				FE_HAS_SYNC | FE_HAS_LOCK;
-
-	return 0;
-err:
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
-	return ret;
-}
-
-static int mn88472_init_c(struct dvb_frontend *fe)
-{
-	struct mn88472_state *s = fe->demodulator_priv;
-	int ret, len, remaining;
-	const struct firmware *fw = NULL;
-	u8 *fw_file = MN88472_FIRMWARE;
-	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
-
-	/* set cold state by default */
-	s->warm = false;
-
-	/* power on */
-	ret = mn88472_wreg(s, 0x1c05, 0x00);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wregs(s, 0x1c0b, "\x00\x00", 2);
-	if (ret)
-		goto err;
-
-	/* request the firmware, this will block and timeout */
-	ret = request_firmware(&fw, fw_file, s->i2c->dev.parent);
-	if (ret) {
-		dev_err(&s->i2c->dev, "%s: firmare file '%s' not found\n",
-				KBUILD_MODNAME, fw_file);
-		goto err;
-	}
-
-	dev_info(&s->i2c->dev, "%s: downloading firmware from file '%s'\n",
-			KBUILD_MODNAME, fw_file);
-
-	ret = mn88472_wreg(s, 0x18f5, 0x03);
-	if (ret)
-		goto err;
-
-	for (remaining = fw->size; remaining > 0;
-			remaining -= (s->cfg->i2c_wr_max - 1)) {
-		len = remaining;
-		if (len > (s->cfg->i2c_wr_max - 1))
-			len = (s->cfg->i2c_wr_max - 1);
-
-		ret = mn88472_wregs(s, 0x18f6,
-				&fw->data[fw->size - remaining], len);
-		if (ret) {
-			dev_err(&s->i2c->dev,
-					"%s: firmware download failed=%d\n",
-					KBUILD_MODNAME, ret);
-			goto err;
-		}
-	}
-
-	ret = mn88472_wreg(s, 0x18f5, 0x00);
-	if (ret)
-		goto err;
-
-	release_firmware(fw);
-	fw = NULL;
-
-	/* warm state */
-	s->warm = true;
-
-	return 0;
-err:
-	if (fw)
-		release_firmware(fw);
-
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
-	return ret;
-}
-
-static int mn88472_sleep_c(struct dvb_frontend *fe)
-{
-	struct mn88472_state *s = fe->demodulator_priv;
-	int ret;
-	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
-
-	/* power off */
-	ret = mn88472_wreg(s, 0x1c0b, 0x30);
-	if (ret)
-		goto err;
-
-	ret = mn88472_wreg(s, 0x1c05, 0x3e);
-	if (ret)
-		goto err;
-
-	s->delivery_system = SYS_UNDEFINED;
-
-	return 0;
-err:
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
-	return ret;
-}
-
-static void mn88472_release_c(struct dvb_frontend *fe)
-{
-	struct mn88472_state *s = fe->demodulator_priv;
-	kfree(s);
-}
-
-struct dvb_frontend *mn88472_attach_c(const struct mn88472_c_config *cfg,
-		struct i2c_adapter *i2c)
-{
-	int ret;
-	struct mn88472_state *s;
-	u8 u8tmp;
-	dev_dbg(&i2c->dev, "%s:\n", __func__);
-
-	/* allocate memory for the internal state */
-	s = kzalloc(sizeof(struct mn88472_state), GFP_KERNEL);
-	if (!s) {
-		ret = -ENOMEM;
-		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
-		goto err;
-	}
-
-	s->cfg = cfg;
-	s->i2c = i2c;
-
-	/* check demod responds to I2C */
-	ret = mn88472_rreg(s, 0x1c00, &u8tmp);
-	if (ret)
-		goto err;
-
-	/* create dvb_frontend */
-	memcpy(&s->fe.ops, &mn88472_ops_c, sizeof(struct dvb_frontend_ops));
-	s->fe.demodulator_priv = s;
-
-	return &s->fe;
-err:
-	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
-	kfree(s);
-	return NULL;
-}
-EXPORT_SYMBOL(mn88472_attach_c);
-
-static struct dvb_frontend_ops mn88472_ops_c = {
-	.delsys = {SYS_DVBC_ANNEX_A},
-	.info = {
-		.name = "Panasonic MN88472",
-		.caps =	FE_CAN_FEC_1_2			|
-			FE_CAN_FEC_2_3			|
-			FE_CAN_FEC_3_4			|
-			FE_CAN_FEC_5_6			|
-			FE_CAN_FEC_7_8			|
-			FE_CAN_FEC_AUTO			|
-			FE_CAN_QPSK			|
-			FE_CAN_QAM_16			|
-			FE_CAN_QAM_32			|
-			FE_CAN_QAM_64			|
-			FE_CAN_QAM_128			|
-			FE_CAN_QAM_256			|
-			FE_CAN_QAM_AUTO			|
-			FE_CAN_TRANSMISSION_MODE_AUTO	|
-			FE_CAN_GUARD_INTERVAL_AUTO	|
-			FE_CAN_HIERARCHY_AUTO		|
-			FE_CAN_MUTE_TS			|
-			FE_CAN_2G_MODULATION		|
-			FE_CAN_MULTISTREAM
-	},
-
-	.release = mn88472_release_c,
-
-	.get_tune_settings = mn88472_get_tune_settings,
-
-	.init = mn88472_init_c,
-	.sleep = mn88472_sleep_c,
-
-	.set_frontend = mn88472_set_frontend_c,
-/*	.get_frontend = mn88472_get_frontend_c, */
-
-	.read_status = mn88472_read_status_c,
-/*	.read_snr = mn88472_read_snr_c, */
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(MN88472_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index ecade84..1aaa25f 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -27,7 +27,7 @@
 
 struct mn88472_state {
 	struct i2c_adapter *i2c;
-	const struct mn88472_c_config *cfg;
+	const struct mn88472_config *cfg;
 	struct dvb_frontend fe;
 	fe_delivery_system_t delivery_system;
 	bool warm; /* FW running */
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 05/11] mn88472: rename state to dev
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (3 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 04/11] mn88472: rename mn88472_c.c => mn88472.c Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 06/11] mn88472: convert driver to I2C client Antti Palosaari
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Rename state to dev.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/mn88472.c      | 141 +++++++++++++++--------------
 drivers/media/dvb-frontends/mn88472_priv.h |   2 +-
 2 files changed, 72 insertions(+), 71 deletions(-)

diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index a3c4ae1..1d72e02 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -19,7 +19,7 @@
 static struct dvb_frontend_ops mn88472_ops;
 
 /* write multiple registers */
-static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len)
+static int mn88472_wregs(struct mn88472_dev *dev, u16 reg, const u8 *val, int len)
 {
 #define MAX_WR_LEN 21
 #define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
@@ -40,11 +40,11 @@ static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int le
 	buf[0] = (reg >> 0) & 0xff;
 	memcpy(&buf[1], val, len);
 
-	ret = i2c_transfer(s->i2c, msg, 1);
+	ret = i2c_transfer(dev->i2c, msg, 1);
 	if (ret == 1) {
 		ret = 0;
 	} else {
-		dev_warn(&s->i2c->dev,
+		dev_warn(&dev->i2c->dev,
 				"%s: i2c wr failed=%d reg=%02x len=%d\n",
 				KBUILD_MODNAME, ret, reg, len);
 		ret = -EREMOTEIO;
@@ -54,7 +54,7 @@ static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int le
 }
 
 /* read multiple registers */
-static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len)
+static int mn88472_rregs(struct mn88472_dev *dev, u16 reg, u8 *val, int len)
 {
 #define MAX_RD_LEN 2
 #define MAX_RD_XFER_LEN (MAX_RD_LEN)
@@ -79,12 +79,12 @@ static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len)
 
 	buf[0] = (reg >> 0) & 0xff;
 
-	ret = i2c_transfer(s->i2c, msg, 2);
+	ret = i2c_transfer(dev->i2c, msg, 2);
 	if (ret == 2) {
 		memcpy(val, buf, len);
 		ret = 0;
 	} else {
-		dev_warn(&s->i2c->dev,
+		dev_warn(&dev->i2c->dev,
 				"%s: i2c rd failed=%d reg=%02x len=%d\n",
 				KBUILD_MODNAME, ret, reg, len);
 		ret = -EREMOTEIO;
@@ -94,15 +94,15 @@ static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len)
 }
 
 /* write single register */
-static int mn88472_wreg(struct mn88472_state *s, u16 reg, u8 val)
+static int mn88472_wreg(struct mn88472_dev *dev, u16 reg, u8 val)
 {
-	return mn88472_wregs(s, reg, &val, 1);
+	return mn88472_wregs(dev, reg, &val, 1);
 }
 
 /* read single register */
-static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val)
+static int mn88472_rreg(struct mn88472_dev *dev, u16 reg, u8 *val)
 {
-	return mn88472_rregs(s, reg, val, 1);
+	return mn88472_rregs(dev, reg, val, 1);
 }
 
 static int mn88472_get_tune_settings(struct dvb_frontend *fe,
@@ -114,16 +114,16 @@ static int mn88472_get_tune_settings(struct dvb_frontend *fe,
 
 static int mn88472_set_frontend(struct dvb_frontend *fe)
 {
-	struct mn88472_state *s = fe->demodulator_priv;
+	struct mn88472_dev *dev = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret;
 	u32 if_frequency = 0;
-	dev_dbg(&s->i2c->dev,
+	dev_dbg(&dev->i2c->dev,
 			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
 			__func__, c->delivery_system, c->modulation,
 			c->frequency, c->symbol_rate, c->inversion);
 
-	if (!s->warm) {
+	if (!dev->warm) {
 		ret = -EAGAIN;
 		goto err;
 	}
@@ -140,96 +140,96 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
 		if (ret)
 			goto err;
 
-		dev_dbg(&s->i2c->dev, "%s: get_if_frequency=%d\n",
+		dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n",
 				__func__, if_frequency);
 	}
 
 	if (if_frequency != 5070000) {
-		dev_err(&s->i2c->dev, "%s: IF frequency %d not supported\n",
+		dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n",
 				KBUILD_MODNAME, if_frequency);
 		ret = -EINVAL;
 		goto err;
 	}
 
-	ret = mn88472_wregs(s, 0x1c08, "\x1d", 1);
+	ret = mn88472_wregs(dev, 0x1c08, "\x1d", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18d9, "\xe3", 1);
+	ret = mn88472_wregs(dev, 0x18d9, "\xe3", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1c83, "\x01", 1);
+	ret = mn88472_wregs(dev, 0x1c83, "\x01", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1c00, "\x66\x00\x01\x04\x00", 5);
+	ret = mn88472_wregs(dev, 0x1c00, "\x66\x00\x01\x04\x00", 5);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1c10,
+	ret = mn88472_wregs(dev, 0x1c10,
 			"\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1846, "\x00", 1);
+	ret = mn88472_wregs(dev, 0x1846, "\x00", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18ae, "\x00", 1);
+	ret = mn88472_wregs(dev, 0x18ae, "\x00", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18b0, "\x0b", 1);
+	ret = mn88472_wregs(dev, 0x18b0, "\x0b", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18b4, "\x00", 1);
+	ret = mn88472_wregs(dev, 0x18b4, "\x00", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18cd, "\x17", 1);
+	ret = mn88472_wregs(dev, 0x18cd, "\x17", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18d4, "\x09", 1);
+	ret = mn88472_wregs(dev, 0x18d4, "\x09", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x18d6, "\x48", 1);
+	ret = mn88472_wregs(dev, 0x18d6, "\x48", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1a00, "\xb0", 1);
+	ret = mn88472_wregs(dev, 0x1a00, "\xb0", 1);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1cf8, "\x9f", 1);
+	ret = mn88472_wregs(dev, 0x1cf8, "\x9f", 1);
 	if (ret)
 		goto err;
 
-	s->delivery_system = c->delivery_system;
+	dev->delivery_system = c->delivery_system;
 
 	return 0;
 err:
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
 	return ret;
 }
 
 static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
-	struct mn88472_state *s = fe->demodulator_priv;
+	struct mn88472_dev *dev = fe->demodulator_priv;
 	int ret;
 	u8 u8tmp;
 
 	*status = 0;
 
-	if (!s->warm) {
+	if (!dev->warm) {
 		ret = -EAGAIN;
 		goto err;
 	}
 
-	ret = mn88472_rreg(s, 0x1a84, &u8tmp);
+	ret = mn88472_rreg(dev, 0x1a84, &u8tmp);
 	if (ret)
 		goto err;
 
@@ -239,62 +239,62 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
 	return 0;
 err:
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
 	return ret;
 }
 
 static int mn88472_init(struct dvb_frontend *fe)
 {
-	struct mn88472_state *s = fe->demodulator_priv;
+	struct mn88472_dev *dev = fe->demodulator_priv;
 	int ret, len, remaining;
 	const struct firmware *fw = NULL;
 	u8 *fw_file = MN88472_FIRMWARE;
-	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
+	dev_dbg(&dev->i2c->dev, "%s:\n", __func__);
 
 	/* set cold state by default */
-	s->warm = false;
+	dev->warm = false;
 
 	/* power on */
-	ret = mn88472_wreg(s, 0x1c05, 0x00);
+	ret = mn88472_wreg(dev, 0x1c05, 0x00);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(s, 0x1c0b, "\x00\x00", 2);
+	ret = mn88472_wregs(dev, 0x1c0b, "\x00\x00", 2);
 	if (ret)
 		goto err;
 
 	/* request the firmware, this will block and timeout */
-	ret = request_firmware(&fw, fw_file, s->i2c->dev.parent);
+	ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent);
 	if (ret) {
-		dev_err(&s->i2c->dev, "%s: firmare file '%s' not found\n",
+		dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n",
 				KBUILD_MODNAME, fw_file);
 		goto err;
 	}
 
-	dev_info(&s->i2c->dev, "%s: downloading firmware from file '%s'\n",
+	dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n",
 			KBUILD_MODNAME, fw_file);
 
-	ret = mn88472_wreg(s, 0x18f5, 0x03);
+	ret = mn88472_wreg(dev, 0x18f5, 0x03);
 	if (ret)
 		goto err;
 
 	for (remaining = fw->size; remaining > 0;
-			remaining -= (s->cfg->i2c_wr_max - 1)) {
+			remaining -= (dev->cfg->i2c_wr_max - 1)) {
 		len = remaining;
-		if (len > (s->cfg->i2c_wr_max - 1))
-			len = (s->cfg->i2c_wr_max - 1);
+		if (len > (dev->cfg->i2c_wr_max - 1))
+			len = (dev->cfg->i2c_wr_max - 1);
 
-		ret = mn88472_wregs(s, 0x18f6,
+		ret = mn88472_wregs(dev, 0x18f6,
 				&fw->data[fw->size - remaining], len);
 		if (ret) {
-			dev_err(&s->i2c->dev,
+			dev_err(&dev->i2c->dev,
 					"%s: firmware download failed=%d\n",
 					KBUILD_MODNAME, ret);
 			goto err;
 		}
 	}
 
-	ret = mn88472_wreg(s, 0x18f5, 0x00);
+	ret = mn88472_wreg(dev, 0x18f5, 0x00);
 	if (ret)
 		goto err;
 
@@ -302,78 +302,79 @@ static int mn88472_init(struct dvb_frontend *fe)
 	fw = NULL;
 
 	/* warm state */
-	s->warm = true;
+	dev->warm = true;
 
 	return 0;
 err:
 	if (fw)
 		release_firmware(fw);
 
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
 	return ret;
 }
 
 static int mn88472_sleep(struct dvb_frontend *fe)
 {
-	struct mn88472_state *s = fe->demodulator_priv;
+	struct mn88472_dev *dev = fe->demodulator_priv;
 	int ret;
-	dev_dbg(&s->i2c->dev, "%s:\n", __func__);
+	dev_dbg(&dev->i2c->dev, "%s:\n", __func__);
 
 	/* power off */
-	ret = mn88472_wreg(s, 0x1c0b, 0x30);
+	ret = mn88472_wreg(dev, 0x1c0b, 0x30);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wreg(s, 0x1c05, 0x3e);
+	ret = mn88472_wreg(dev, 0x1c05, 0x3e);
 	if (ret)
 		goto err;
 
-	s->delivery_system = SYS_UNDEFINED;
+	dev->delivery_system = SYS_UNDEFINED;
 
 	return 0;
 err:
-	dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
 	return ret;
 }
 
 static void mn88472_release(struct dvb_frontend *fe)
 {
-	struct mn88472_state *s = fe->demodulator_priv;
-	kfree(s);
+	struct mn88472_dev *dev = fe->demodulator_priv;
+
+	kfree(dev);
 }
 
 struct dvb_frontend *mn88472_attach(const struct mn88472_config *cfg,
 		struct i2c_adapter *i2c)
 {
 	int ret;
-	struct mn88472_state *s;
+	struct mn88472_dev *dev;
 	u8 u8tmp;
 	dev_dbg(&i2c->dev, "%s:\n", __func__);
 
 	/* allocate memory for the internal state */
-	s = kzalloc(sizeof(struct mn88472_state), GFP_KERNEL);
-	if (!s) {
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
 		ret = -ENOMEM;
 		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
 		goto err;
 	}
 
-	s->cfg = cfg;
-	s->i2c = i2c;
+	dev->cfg = cfg;
+	dev->i2c = i2c;
 
 	/* check demod responds to I2C */
-	ret = mn88472_rreg(s, 0x1c00, &u8tmp);
+	ret = mn88472_rreg(dev, 0x1c00, &u8tmp);
 	if (ret)
 		goto err;
 
 	/* create dvb_frontend */
-	memcpy(&s->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
-	s->fe.demodulator_priv = s;
+	memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
+	dev->fe.demodulator_priv = dev;
 
-	return &s->fe;
+	return &dev->fe;
 err:
 	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
-	kfree(s);
+	kfree(dev);
 	return NULL;
 }
 EXPORT_SYMBOL(mn88472_attach);
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index 1aaa25f..be31adb 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -25,7 +25,7 @@
 
 #define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
 
-struct mn88472_state {
+struct mn88472_dev {
 	struct i2c_adapter *i2c;
 	const struct mn88472_config *cfg;
 	struct dvb_frontend fe;
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 06/11] mn88472: convert driver to I2C client
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (4 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 05/11] mn88472: rename state to dev Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 07/11] mn88472: Convert driver to I2C RegMap API Antti Palosaari
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

It uses I2C bus so better to implement it as a standard I2C driver
model. It was using proprietary DVB binding.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/mn88472.c      | 241 ++++++++++++++++++-----------
 drivers/media/dvb-frontends/mn88472.h      |  30 ++--
 drivers/media/dvb-frontends/mn88472_priv.h |   6 +-
 3 files changed, 165 insertions(+), 112 deletions(-)

diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index 1d72e02..a65741a 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -40,13 +40,13 @@ static int mn88472_wregs(struct mn88472_dev *dev, u16 reg, const u8 *val, int le
 	buf[0] = (reg >> 0) & 0xff;
 	memcpy(&buf[1], val, len);
 
-	ret = i2c_transfer(dev->i2c, msg, 1);
+	ret = i2c_transfer(dev->client[0]->adapter, msg, 1);
 	if (ret == 1) {
 		ret = 0;
 	} else {
-		dev_warn(&dev->i2c->dev,
-				"%s: i2c wr failed=%d reg=%02x len=%d\n",
-				KBUILD_MODNAME, ret, reg, len);
+		dev_warn(&dev->client[0]->dev,
+				"i2c wr failed=%d reg=%02x len=%d\n",
+				ret, reg, len);
 		ret = -EREMOTEIO;
 	}
 
@@ -79,14 +79,14 @@ static int mn88472_rregs(struct mn88472_dev *dev, u16 reg, u8 *val, int len)
 
 	buf[0] = (reg >> 0) & 0xff;
 
-	ret = i2c_transfer(dev->i2c, msg, 2);
+	ret = i2c_transfer(dev->client[0]->adapter, msg, 2);
 	if (ret == 2) {
 		memcpy(val, buf, len);
 		ret = 0;
 	} else {
-		dev_warn(&dev->i2c->dev,
-				"%s: i2c rd failed=%d reg=%02x len=%d\n",
-				KBUILD_MODNAME, ret, reg, len);
+		dev_warn(&dev->client[0]->dev,
+				"i2c rd failed=%d reg=%02x len=%d\n",
+				ret, reg, len);
 		ret = -EREMOTEIO;
 	}
 
@@ -114,13 +114,15 @@ static int mn88472_get_tune_settings(struct dvb_frontend *fe,
 
 static int mn88472_set_frontend(struct dvb_frontend *fe)
 {
-	struct mn88472_dev *dev = fe->demodulator_priv;
+	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;
 	u32 if_frequency = 0;
-	dev_dbg(&dev->i2c->dev,
-			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
-			__func__, c->delivery_system, c->modulation,
+
+	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);
 
 	if (!dev->warm) {
@@ -140,13 +142,12 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
 		if (ret)
 			goto err;
 
-		dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n",
-				__func__, if_frequency);
+		dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
 	}
 
 	if (if_frequency != 5070000) {
-		dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n",
-				KBUILD_MODNAME, if_frequency);
+		dev_err(&client->dev, "IF frequency %d not supported\n",
+				if_frequency);
 		ret = -EINVAL;
 		goto err;
 	}
@@ -212,13 +213,14 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
 
 	return 0;
 err:
-	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
 static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
-	struct mn88472_dev *dev = fe->demodulator_priv;
+	struct i2c_client *client = fe->demodulator_priv;
+	struct mn88472_dev *dev = i2c_get_clientdata(client);
 	int ret;
 	u8 u8tmp;
 
@@ -239,17 +241,19 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
 	return 0;
 err:
-	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
 static int mn88472_init(struct dvb_frontend *fe)
 {
-	struct mn88472_dev *dev = fe->demodulator_priv;
+	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;
-	dev_dbg(&dev->i2c->dev, "%s:\n", __func__);
+
+	dev_dbg(&client->dev, "\n");
 
 	/* set cold state by default */
 	dev->warm = false;
@@ -264,32 +268,31 @@ static int mn88472_init(struct dvb_frontend *fe)
 		goto err;
 
 	/* request the firmware, this will block and timeout */
-	ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent);
+	ret = request_firmware(&fw, fw_file, &client->dev);
 	if (ret) {
-		dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n",
-				KBUILD_MODNAME, fw_file);
+		dev_err(&client->dev, "firmare file '%s' not found\n",
+				fw_file);
 		goto err;
 	}
 
-	dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n",
-			KBUILD_MODNAME, fw_file);
+	dev_info(&client->dev, "downloading firmware from file '%s'\n",
+			fw_file);
 
 	ret = mn88472_wreg(dev, 0x18f5, 0x03);
 	if (ret)
 		goto err;
 
 	for (remaining = fw->size; remaining > 0;
-			remaining -= (dev->cfg->i2c_wr_max - 1)) {
+			remaining -= (dev->i2c_wr_max - 1)) {
 		len = remaining;
-		if (len > (dev->cfg->i2c_wr_max - 1))
-			len = (dev->cfg->i2c_wr_max - 1);
+		if (len > (dev->i2c_wr_max - 1))
+			len = (dev->i2c_wr_max - 1);
 
 		ret = mn88472_wregs(dev, 0x18f6,
 				&fw->data[fw->size - remaining], len);
 		if (ret) {
-			dev_err(&dev->i2c->dev,
-					"%s: firmware download failed=%d\n",
-					KBUILD_MODNAME, ret);
+			dev_err(&client->dev,
+					"firmware download failed=%d\n", ret);
 			goto err;
 		}
 	}
@@ -309,15 +312,17 @@ err:
 	if (fw)
 		release_firmware(fw);
 
-	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
 static int mn88472_sleep(struct dvb_frontend *fe)
 {
-	struct mn88472_dev *dev = fe->demodulator_priv;
+	struct i2c_client *client = fe->demodulator_priv;
+	struct mn88472_dev *dev = i2c_get_clientdata(client);
 	int ret;
-	dev_dbg(&dev->i2c->dev, "%s:\n", __func__);
+
+	dev_dbg(&client->dev, "\n");
 
 	/* power off */
 	ret = mn88472_wreg(dev, 0x1c0b, 0x30);
@@ -332,91 +337,149 @@ static int mn88472_sleep(struct dvb_frontend *fe)
 
 	return 0;
 err:
-	dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
-static void mn88472_release(struct dvb_frontend *fe)
-{
-	struct mn88472_dev *dev = fe->demodulator_priv;
+static struct dvb_frontend_ops mn88472_ops = {
+	.delsys = {SYS_DVBC_ANNEX_A},
+	.info = {
+		.name = "Panasonic MN88472",
+		.caps =	FE_CAN_FEC_1_2                 |
+			FE_CAN_FEC_2_3                 |
+			FE_CAN_FEC_3_4                 |
+			FE_CAN_FEC_5_6                 |
+			FE_CAN_FEC_7_8                 |
+			FE_CAN_FEC_AUTO                |
+			FE_CAN_QPSK                    |
+			FE_CAN_QAM_16                  |
+			FE_CAN_QAM_32                  |
+			FE_CAN_QAM_64                  |
+			FE_CAN_QAM_128                 |
+			FE_CAN_QAM_256                 |
+			FE_CAN_QAM_AUTO                |
+			FE_CAN_TRANSMISSION_MODE_AUTO  |
+			FE_CAN_GUARD_INTERVAL_AUTO     |
+			FE_CAN_HIERARCHY_AUTO          |
+			FE_CAN_MUTE_TS                 |
+			FE_CAN_2G_MODULATION           |
+			FE_CAN_MULTISTREAM
+	},
 
-	kfree(dev);
-}
+	.get_tune_settings = mn88472_get_tune_settings,
+
+	.init = mn88472_init,
+	.sleep = mn88472_sleep,
+
+	.set_frontend = mn88472_set_frontend,
+
+	.read_status = mn88472_read_status,
+};
 
-struct dvb_frontend *mn88472_attach(const struct mn88472_config *cfg,
-		struct i2c_adapter *i2c)
+static int mn88472_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
 {
-	int ret;
+	struct mn88472_config *config = client->dev.platform_data;
 	struct mn88472_dev *dev;
+	int ret;
 	u8 u8tmp;
-	dev_dbg(&i2c->dev, "%s:\n", __func__);
 
-	/* allocate memory for the internal state */
+	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) {
 		ret = -ENOMEM;
-		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
 		goto err;
 	}
 
-	dev->cfg = cfg;
-	dev->i2c = i2c;
+	dev->client[0] = client;
+	dev->i2c_wr_max = config->i2c_wr_max;
 
-	/* check demod responds to I2C */
+	/* check demod answers to I2C */
 	ret = mn88472_rreg(dev, 0x1c00, &u8tmp);
 	if (ret)
-		goto err;
+		goto err_kfree;
+
+	/*
+	 * Chip has three I2C addresses for different register pages. 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.
+	 */
+	dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
+	if (dev->client[1] == NULL) {
+		ret = -ENODEV;
+		dev_err(&client->dev, "I2C registration failed\n");
+		if (ret)
+			goto err_kfree;
+	}
+	i2c_set_clientdata(dev->client[1], dev);
+
+	dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
+	if (dev->client[2] == NULL) {
+		ret = -ENODEV;
+		dev_err(&client->dev, "2nd I2C registration failed\n");
+		if (ret)
+			goto err_client_1_i2c_unregister_device;
+	}
+	i2c_set_clientdata(dev->client[2], dev);
 
 	/* create dvb_frontend */
 	memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
-	dev->fe.demodulator_priv = dev;
+	dev->fe.demodulator_priv = client;
+	*config->fe = &dev->fe;
+	i2c_set_clientdata(client, dev);
 
-	return &dev->fe;
-err:
-	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_info(&client->dev, "Panasonic MN88472 successfully attached\n");
+	return 0;
+
+err_client_1_i2c_unregister_device:
+	i2c_unregister_device(dev->client[1]);
+err_kfree:
 	kfree(dev);
-	return NULL;
+err:
+	dev_dbg(&client->dev, "failed=%d\n", ret);
+	return ret;
 }
-EXPORT_SYMBOL(mn88472_attach);
 
-static struct dvb_frontend_ops mn88472_ops = {
-	.delsys = {SYS_DVBC_ANNEX_A},
-	.info = {
-		.name = "Panasonic MN88472",
-		.caps =	FE_CAN_FEC_1_2			|
-			FE_CAN_FEC_2_3			|
-			FE_CAN_FEC_3_4			|
-			FE_CAN_FEC_5_6			|
-			FE_CAN_FEC_7_8			|
-			FE_CAN_FEC_AUTO			|
-			FE_CAN_QPSK			|
-			FE_CAN_QAM_16			|
-			FE_CAN_QAM_32			|
-			FE_CAN_QAM_64			|
-			FE_CAN_QAM_128			|
-			FE_CAN_QAM_256			|
-			FE_CAN_QAM_AUTO			|
-			FE_CAN_TRANSMISSION_MODE_AUTO	|
-			FE_CAN_GUARD_INTERVAL_AUTO	|
-			FE_CAN_HIERARCHY_AUTO		|
-			FE_CAN_MUTE_TS			|
-			FE_CAN_2G_MODULATION		|
-			FE_CAN_MULTISTREAM
-	},
+static int mn88472_remove(struct i2c_client *client)
+{
+	struct mn88472_dev *dev = i2c_get_clientdata(client);
 
-	.release = mn88472_release,
+	dev_dbg(&client->dev, "\n");
 
-	.get_tune_settings = mn88472_get_tune_settings,
+	i2c_unregister_device(dev->client[2]);
 
-	.init = mn88472_init,
-	.sleep = mn88472_sleep,
+	i2c_unregister_device(dev->client[1]);
 
-	.set_frontend = mn88472_set_frontend,
-/*	.get_frontend = mn88472_get_frontend, */
+	kfree(dev);
 
-	.read_status = mn88472_read_status,
-/*	.read_snr = mn88472_read_snr, */
+	return 0;
+}
+
+static const struct i2c_device_id mn88472_id_table[] = {
+	{"mn88472", 0},
+	{}
 };
+MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
+
+static struct i2c_driver mn88472_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "mn88472",
+	},
+	.probe		= mn88472_probe,
+	.remove		= mn88472_remove,
+	.id_table	= mn88472_id_table,
+};
+
+module_i2c_driver(mn88472_driver);
 
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
index 5ce6ac1..da4558b 100644
--- a/drivers/media/dvb-frontends/mn88472.h
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -21,26 +21,18 @@
 
 struct mn88472_config {
 	/*
-	 * max bytes I2C client could write
-	 * Value must be set.
+	 * Max num of bytes given I2C adapter could write at once.
+	 * Default: none
 	 */
-	int i2c_wr_max;
-};
+	u16 i2c_wr_max;
 
-#if IS_ENABLED(CONFIG_DVB_MN88472)
-extern struct dvb_frontend *mn88472_attach(
-	const struct mn88472_config *cfg,
-	struct i2c_adapter *i2c
-);
-#else
-static inline struct dvb_frontend *mn88472_attach(
-	const struct mn88472_config *cfg,
-	struct i2c_adapter *i2c
-)
-{
-	dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
-	return NULL;
-}
-#endif
+
+	/* Everything after that is returned by the driver. */
+
+	/*
+	 * DVB frontend.
+	 */
+	struct dvb_frontend **fe;
+};
 
 #endif
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index be31adb..0fde80c 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -19,16 +19,14 @@
 
 #include "dvb_frontend.h"
 #include "mn88472.h"
-#include "dvb_math.h"
 #include <linux/firmware.h>
-#include <linux/i2c-mux.h>
 
 #define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
 
 struct mn88472_dev {
-	struct i2c_adapter *i2c;
-	const struct mn88472_config *cfg;
+	struct i2c_client *client[3];
 	struct dvb_frontend fe;
+	u16 i2c_wr_max;
 	fe_delivery_system_t delivery_system;
 	bool warm; /* FW running */
 };
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 07/11] mn88472: Convert driver to I2C RegMap API
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (5 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 06/11] mn88472: convert driver to I2C client Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 08/11] mn88472: implement DVB-T and DVB-T2 Antti Palosaari
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Convert driver to I2C RegMap API.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/Kconfig        |   1 +
 drivers/media/dvb-frontends/mn88472.c      | 180 ++++++++++-------------------
 drivers/media/dvb-frontends/mn88472_priv.h |   2 +
 3 files changed, 64 insertions(+), 119 deletions(-)

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 02bada4..207843e 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -444,6 +444,7 @@ config DVB_CXD2820R
 config DVB_MN88472
 	tristate "Panasonic MN88472"
 	depends on DVB_CORE && I2C
+	select REGMAP_I2C
 	default m if !MEDIA_SUBDRV_AUTOSELECT
 	help
 	  Say Y when you want to support this frontend.
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index a65741a..c680154 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -16,95 +16,6 @@
 
 #include "mn88472_priv.h"
 
-static struct dvb_frontend_ops mn88472_ops;
-
-/* write multiple registers */
-static int mn88472_wregs(struct mn88472_dev *dev, u16 reg, const u8 *val, int len)
-{
-#define MAX_WR_LEN 21
-#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
-	int ret;
-	u8 buf[MAX_WR_XFER_LEN];
-	struct i2c_msg msg[1] = {
-		{
-			.addr = (reg >> 8) & 0xff,
-			.flags = 0,
-			.len = 1 + len,
-			.buf = buf,
-		}
-	};
-
-	if (WARN_ON(len > MAX_WR_LEN))
-		return -EINVAL;
-
-	buf[0] = (reg >> 0) & 0xff;
-	memcpy(&buf[1], val, len);
-
-	ret = i2c_transfer(dev->client[0]->adapter, msg, 1);
-	if (ret == 1) {
-		ret = 0;
-	} else {
-		dev_warn(&dev->client[0]->dev,
-				"i2c wr failed=%d reg=%02x len=%d\n",
-				ret, reg, len);
-		ret = -EREMOTEIO;
-	}
-
-	return ret;
-}
-
-/* read multiple registers */
-static int mn88472_rregs(struct mn88472_dev *dev, u16 reg, u8 *val, int len)
-{
-#define MAX_RD_LEN 2
-#define MAX_RD_XFER_LEN (MAX_RD_LEN)
-	int ret;
-	u8 buf[MAX_RD_XFER_LEN];
-	struct i2c_msg msg[2] = {
-		{
-			.addr = (reg >> 8) & 0xff,
-			.flags = 0,
-			.len = 1,
-			.buf = buf,
-		}, {
-			.addr = (reg >> 8) & 0xff,
-			.flags = I2C_M_RD,
-			.len = len,
-			.buf = buf,
-		}
-	};
-
-	if (WARN_ON(len > MAX_RD_LEN))
-		return -EINVAL;
-
-	buf[0] = (reg >> 0) & 0xff;
-
-	ret = i2c_transfer(dev->client[0]->adapter, msg, 2);
-	if (ret == 2) {
-		memcpy(val, buf, len);
-		ret = 0;
-	} else {
-		dev_warn(&dev->client[0]->dev,
-				"i2c rd failed=%d reg=%02x len=%d\n",
-				ret, reg, len);
-		ret = -EREMOTEIO;
-	}
-
-	return ret;
-}
-
-/* write single register */
-static int mn88472_wreg(struct mn88472_dev *dev, u16 reg, u8 val)
-{
-	return mn88472_wregs(dev, reg, &val, 1);
-}
-
-/* read single register */
-static int mn88472_rreg(struct mn88472_dev *dev, u16 reg, u8 *val)
-{
-	return mn88472_rregs(dev, reg, val, 1);
-}
-
 static int mn88472_get_tune_settings(struct dvb_frontend *fe,
 	struct dvb_frontend_tune_settings *s)
 {
@@ -152,60 +63,61 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
 		goto err;
 	}
 
-	ret = mn88472_wregs(dev, 0x1c08, "\x1d", 1);
+	ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18d9, "\xe3", 1);
+	ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1c83, "\x01", 1);
+	ret = regmap_write(dev->regmap[2], 0x83, 0x01);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1c00, "\x66\x00\x01\x04\x00", 5);
+	ret = regmap_bulk_write(dev->regmap[2], 0x00,
+			"\x66\x00\x01\x04\x00", 5);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1c10,
+	ret = regmap_bulk_write(dev->regmap[2], 0x10,
 			"\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1846, "\x00", 1);
+	ret = regmap_write(dev->regmap[0], 0x46, 0x00);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18ae, "\x00", 1);
+	ret = regmap_write(dev->regmap[0], 0xae, 0x00);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18b0, "\x0b", 1);
+	ret = regmap_write(dev->regmap[0], 0xb0, 0x0b);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18b4, "\x00", 1);
+	ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18cd, "\x17", 1);
+	ret = regmap_write(dev->regmap[0], 0xcd, 0x17);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18d4, "\x09", 1);
+	ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x18d6, "\x48", 1);
+	ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1a00, "\xb0", 1);
+	ret = regmap_write(dev->regmap[1], 0x00, 0xb0);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1cf8, "\x9f", 1);
+	ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
 	if (ret)
 		goto err;
 
@@ -222,7 +134,7 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 	struct i2c_client *client = fe->demodulator_priv;
 	struct mn88472_dev *dev = i2c_get_clientdata(client);
 	int ret;
-	u8 u8tmp;
+	unsigned int utmp;
 
 	*status = 0;
 
@@ -231,11 +143,11 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 		goto err;
 	}
 
-	ret = mn88472_rreg(dev, 0x1a84, &u8tmp);
+	ret = regmap_read(dev->regmap[1], 0x84, &utmp);
 	if (ret)
 		goto err;
 
-	if (u8tmp == 0x08)
+	if (utmp == 0x08)
 		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
 				FE_HAS_SYNC | FE_HAS_LOCK;
 
@@ -259,11 +171,11 @@ static int mn88472_init(struct dvb_frontend *fe)
 	dev->warm = false;
 
 	/* power on */
-	ret = mn88472_wreg(dev, 0x1c05, 0x00);
+	ret = regmap_write(dev->regmap[2], 0x05, 0x00);
 	if (ret)
 		goto err;
 
-	ret = mn88472_wregs(dev, 0x1c0b, "\x00\x00", 2);
+	ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2);
 	if (ret)
 		goto err;
 
@@ -278,7 +190,7 @@ static int mn88472_init(struct dvb_frontend *fe)
 	dev_info(&client->dev, "downloading firmware from file '%s'\n",
 			fw_file);
 
-	ret = mn88472_wreg(dev, 0x18f5, 0x03);
+	ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
 	if (ret)
 		goto err;
 
@@ -288,7 +200,7 @@ static int mn88472_init(struct dvb_frontend *fe)
 		if (len > (dev->i2c_wr_max - 1))
 			len = (dev->i2c_wr_max - 1);
 
-		ret = mn88472_wregs(dev, 0x18f6,
+		ret = regmap_bulk_write(dev->regmap[0], 0xf6,
 				&fw->data[fw->size - remaining], len);
 		if (ret) {
 			dev_err(&client->dev,
@@ -297,7 +209,7 @@ static int mn88472_init(struct dvb_frontend *fe)
 		}
 	}
 
-	ret = mn88472_wreg(dev, 0x18f5, 0x00);
+	ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
 	if (ret)
 		goto err;
 
@@ -325,11 +237,12 @@ static int mn88472_sleep(struct dvb_frontend *fe)
 	dev_dbg(&client->dev, "\n");
 
 	/* power off */
-	ret = mn88472_wreg(dev, 0x1c0b, 0x30);
+	ret = regmap_write(dev->regmap[2], 0x0b, 0x30);
+
 	if (ret)
 		goto err;
 
-	ret = mn88472_wreg(dev, 0x1c05, 0x3e);
+	ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
 	if (ret)
 		goto err;
 
@@ -382,7 +295,11 @@ static int mn88472_probe(struct i2c_client *client,
 	struct mn88472_config *config = client->dev.platform_data;
 	struct mn88472_dev *dev;
 	int ret;
-	u8 u8tmp;
+	unsigned int utmp;
+	static const struct regmap_config regmap_config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
 
 	dev_dbg(&client->dev, "\n");
 
@@ -399,13 +316,18 @@ static int mn88472_probe(struct i2c_client *client,
 		goto err;
 	}
 
-	dev->client[0] = client;
 	dev->i2c_wr_max = config->i2c_wr_max;
+	dev->client[0] = client;
+	dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);
+	if (IS_ERR(dev->regmap[0])) {
+		ret = PTR_ERR(dev->regmap[0]);
+		goto err_kfree;
+	}
 
 	/* check demod answers to I2C */
-	ret = mn88472_rreg(dev, 0x1c00, &u8tmp);
+	ret = regmap_read(dev->regmap[0], 0x00, &utmp);
 	if (ret)
-		goto err_kfree;
+		goto err_regmap_0_regmap_exit;
 
 	/*
 	 * Chip has three I2C addresses for different register pages. Used
@@ -417,7 +339,12 @@ static int mn88472_probe(struct i2c_client *client,
 		ret = -ENODEV;
 		dev_err(&client->dev, "I2C registration failed\n");
 		if (ret)
-			goto err_kfree;
+			goto err_regmap_0_regmap_exit;
+	}
+	dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);
+	if (IS_ERR(dev->regmap[1])) {
+		ret = PTR_ERR(dev->regmap[1]);
+		goto err_client_1_i2c_unregister_device;
 	}
 	i2c_set_clientdata(dev->client[1], dev);
 
@@ -426,7 +353,12 @@ static int mn88472_probe(struct i2c_client *client,
 		ret = -ENODEV;
 		dev_err(&client->dev, "2nd I2C registration failed\n");
 		if (ret)
-			goto err_client_1_i2c_unregister_device;
+			goto err_regmap_1_regmap_exit;
+	}
+	dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);
+	if (IS_ERR(dev->regmap[2])) {
+		ret = PTR_ERR(dev->regmap[2]);
+		goto err_client_2_i2c_unregister_device;
 	}
 	i2c_set_clientdata(dev->client[2], dev);
 
@@ -439,8 +371,14 @@ static int mn88472_probe(struct i2c_client *client,
 	dev_info(&client->dev, "Panasonic MN88472 successfully attached\n");
 	return 0;
 
+err_client_2_i2c_unregister_device:
+	i2c_unregister_device(dev->client[2]);
+err_regmap_1_regmap_exit:
+	regmap_exit(dev->regmap[1]);
 err_client_1_i2c_unregister_device:
 	i2c_unregister_device(dev->client[1]);
+err_regmap_0_regmap_exit:
+	regmap_exit(dev->regmap[0]);
 err_kfree:
 	kfree(dev);
 err:
@@ -454,10 +392,14 @@ static int mn88472_remove(struct i2c_client *client)
 
 	dev_dbg(&client->dev, "\n");
 
+	regmap_exit(dev->regmap[2]);
 	i2c_unregister_device(dev->client[2]);
 
+	regmap_exit(dev->regmap[1]);
 	i2c_unregister_device(dev->client[1]);
 
+	regmap_exit(dev->regmap[0]);
+
 	kfree(dev);
 
 	return 0;
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index 0fde80c..1095949 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -20,11 +20,13 @@
 #include "dvb_frontend.h"
 #include "mn88472.h"
 #include <linux/firmware.h>
+#include <linux/regmap.h>
 
 #define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
 
 struct mn88472_dev {
 	struct i2c_client *client[3];
+	struct regmap *regmap[3];
 	struct dvb_frontend fe;
 	u16 i2c_wr_max;
 	fe_delivery_system_t delivery_system;
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 08/11] mn88472: implement DVB-T and DVB-T2
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (6 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 07/11] mn88472: Convert driver to I2C RegMap API Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 09/11] mn88472: move to staging Antti Palosaari
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Implement initial support for DVB-T and DVB-T2 modes. Now driver has
basic support for all the modes, DVB-C/T/T2.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/mn88472.c | 176 ++++++++++++++++++++++++++--------
 1 file changed, 135 insertions(+), 41 deletions(-)

diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index c680154..52de8f8 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -28,8 +28,9 @@ 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;
+	int ret, i;
 	u32 if_frequency = 0;
+	u8 delivery_system_val, if_val[3], bw_val[7], bw_val2;
 
 	dev_dbg(&client->dev,
 			"delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
@@ -41,6 +42,55 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
 		goto err;
 	}
 
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+		delivery_system_val = 0x02;
+		break;
+	case SYS_DVBT2:
+		delivery_system_val = 0x03;
+		break;
+	case SYS_DVBC_ANNEX_A:
+		delivery_system_val = 0x04;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		if (c->bandwidth_hz <= 6000000) {
+			/* IF 3570000 Hz, BW 6000000 Hz */
+			memcpy(if_val, "\x2c\x94\xdb", 3);
+			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(if_val, "\x39\x11\xbc", 3);
+			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(if_val, "\x39\x11\xbc", 3);
+			memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
+			bw_val2 = 0x00;
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	case SYS_DVBC_ANNEX_A:
+		/* IF 5070000 Hz, BW 8000000 Hz */
+		memcpy(if_val, "\x3f\x50\x2c", 3);
+		memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
+		bw_val2 = 0x00;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
 	/* program tuner */
 	if (fe->ops.tuner_ops.set_params) {
 		ret = fe->ops.tuner_ops.set_params(fe);
@@ -56,67 +106,98 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
 		dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
 	}
 
-	if (if_frequency != 5070000) {
+	switch (if_frequency) {
+	case 3570000:
+	case 4570000:
+	case 5070000:
+		break;
+	default:
 		dev_err(&client->dev, "IF frequency %d not supported\n",
 				if_frequency);
 		ret = -EINVAL;
 		goto err;
 	}
 
-	ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
-	if (ret)
-		goto err;
-
-	ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
-	if (ret)
-		goto err;
-
-	ret = regmap_write(dev->regmap[2], 0x83, 0x01);
+	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)
 		goto err;
 
-	ret = regmap_bulk_write(dev->regmap[2], 0x00,
-			"\x66\x00\x01\x04\x00", 5);
+	ret = regmap_write(dev->regmap[2], 0x00, 0x66);
 	if (ret)
 		goto err;
-
-	ret = regmap_bulk_write(dev->regmap[2], 0x10,
-			"\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10);
+	ret = regmap_write(dev->regmap[2], 0x01, 0x00);
 	if (ret)
 		goto err;
-
-	ret = regmap_write(dev->regmap[0], 0x46, 0x00);
+	ret = regmap_write(dev->regmap[2], 0x02, 0x01);
 	if (ret)
 		goto err;
-
-	ret = regmap_write(dev->regmap[0], 0xae, 0x00);
-	if (ret)
-		goto err;
-
-	ret = regmap_write(dev->regmap[0], 0xb0, 0x0b);
-	if (ret)
-		goto err;
-
-	ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
+	ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
 	if (ret)
 		goto err;
-
-	ret = regmap_write(dev->regmap[0], 0xcd, 0x17);
+	ret = regmap_write(dev->regmap[2], 0x04, bw_val2);
 	if (ret)
 		goto err;
 
-	ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
-	if (ret)
-		goto err;
+	for (i = 0; i < sizeof(if_val); i++) {
+		ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[i]);
+		if (ret)
+			goto err;
+	}
 
-	ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
-	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;
+	}
 
-	ret = regmap_write(dev->regmap[1], 0x00, 0xb0);
-	if (ret)
+	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);
+		ret = regmap_write(dev->regmap[0], 0x00, 0xba);
+		ret = regmap_write(dev->regmap[0], 0x01, 0x13);
+		if (ret)
+			goto err;
+		break;
+	case SYS_DVBT2:
+		ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
+		ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
+		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);
+		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);
+	ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
+	ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
 	ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
 	if (ret)
 		goto err;
@@ -133,6 +214,7 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *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;
 
@@ -143,9 +225,21 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
 		goto err;
 	}
 
-	ret = regmap_read(dev->regmap[1], 0x84, &utmp);
-	if (ret)
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		/* FIXME: implement me */
+		utmp = 0x08; /* DVB-C lock value */
+		break;
+	case SYS_DVBC_ANNEX_A:
+		ret = regmap_read(dev->regmap[1], 0x84, &utmp);
+		if (ret)
+			goto err;
+		break;
+	default:
+		ret = -EINVAL;
 		goto err;
+	}
 
 	if (utmp == 0x08)
 		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
@@ -255,7 +349,7 @@ err:
 }
 
 static struct dvb_frontend_ops mn88472_ops = {
-	.delsys = {SYS_DVBC_ANNEX_A},
+	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
 	.info = {
 		.name = "Panasonic MN88472",
 		.caps =	FE_CAN_FEC_1_2                 |
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 09/11] mn88472: move to staging
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (7 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 08/11] mn88472: implement DVB-T and DVB-T2 Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 10/11] mn88472: add staging TODO Antti Palosaari
  2014-11-12  4:11 ` [PATCH 11/11] MAINTAINERS: add mn88472 (Panasonic MN88472) Antti Palosaari
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

It is not ready enough to be released on mainline.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/Kconfig          |   8 -
 drivers/media/dvb-frontends/Makefile         |   1 -
 drivers/media/dvb-frontends/mn88472.c        | 523 ---------------------------
 drivers/media/dvb-frontends/mn88472_priv.h   |  36 --
 drivers/staging/media/Kconfig                |   2 +
 drivers/staging/media/Makefile               |   1 +
 drivers/staging/media/mn88472/Kconfig        |   7 +
 drivers/staging/media/mn88472/Makefile       |   5 +
 drivers/staging/media/mn88472/mn88472.c      | 523 +++++++++++++++++++++++++++
 drivers/staging/media/mn88472/mn88472_priv.h |  36 ++
 10 files changed, 574 insertions(+), 568 deletions(-)
 delete mode 100644 drivers/media/dvb-frontends/mn88472.c
 delete mode 100644 drivers/media/dvb-frontends/mn88472_priv.h
 create mode 100644 drivers/staging/media/mn88472/Kconfig
 create mode 100644 drivers/staging/media/mn88472/Makefile
 create mode 100644 drivers/staging/media/mn88472/mn88472.c
 create mode 100644 drivers/staging/media/mn88472/mn88472_priv.h

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 207843e..6c75418 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -441,14 +441,6 @@ config DVB_CXD2820R
 	help
 	  Say Y when you want to support this frontend.
 
-config DVB_MN88472
-	tristate "Panasonic MN88472"
-	depends on DVB_CORE && I2C
-	select REGMAP_I2C
-	default m if !MEDIA_SUBDRV_AUTOSELECT
-	help
-	  Say Y when you want to support this frontend.
-
 config DVB_RTL2830
 	tristate "Realtek RTL2830 DVB-T"
 	depends on DVB_CORE && I2C
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index b82225f6..ba59df6 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -103,7 +103,6 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
 obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
 obj-$(CONFIG_DVB_STV0367) += stv0367.o
 obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
-obj-$(CONFIG_DVB_MN88472) += mn88472.o
 obj-$(CONFIG_DVB_DRXK) += drxk.o
 obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
 obj-$(CONFIG_DVB_SI2165) += si2165.o
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
deleted file mode 100644
index 52de8f8..0000000
--- a/drivers/media/dvb-frontends/mn88472.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Panasonic MN88472 DVB-T/T2/C demodulator driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- */
-
-#include "mn88472_priv.h"
-
-static int mn88472_get_tune_settings(struct dvb_frontend *fe,
-	struct dvb_frontend_tune_settings *s)
-{
-	s->min_delay_ms = 400;
-	return 0;
-}
-
-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;
-	u8 delivery_system_val, if_val[3], bw_val[7], bw_val2;
-
-	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);
-
-	if (!dev->warm) {
-		ret = -EAGAIN;
-		goto err;
-	}
-
-	switch (c->delivery_system) {
-	case SYS_DVBT:
-		delivery_system_val = 0x02;
-		break;
-	case SYS_DVBT2:
-		delivery_system_val = 0x03;
-		break;
-	case SYS_DVBC_ANNEX_A:
-		delivery_system_val = 0x04;
-		break;
-	default:
-		ret = -EINVAL;
-		goto err;
-	}
-
-	switch (c->delivery_system) {
-	case SYS_DVBT:
-	case SYS_DVBT2:
-		if (c->bandwidth_hz <= 6000000) {
-			/* IF 3570000 Hz, BW 6000000 Hz */
-			memcpy(if_val, "\x2c\x94\xdb", 3);
-			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(if_val, "\x39\x11\xbc", 3);
-			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(if_val, "\x39\x11\xbc", 3);
-			memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
-			bw_val2 = 0x00;
-		} else {
-			ret = -EINVAL;
-			goto err;
-		}
-		break;
-	case SYS_DVBC_ANNEX_A:
-		/* IF 5070000 Hz, BW 8000000 Hz */
-		memcpy(if_val, "\x3f\x50\x2c", 3);
-		memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
-		bw_val2 = 0x00;
-		break;
-	default:
-		ret = -EINVAL;
-		goto err;
-	}
-
-	/* program tuner */
-	if (fe->ops.tuner_ops.set_params) {
-		ret = fe->ops.tuner_ops.set_params(fe);
-		if (ret)
-			goto err;
-	}
-
-	if (fe->ops.tuner_ops.get_if_frequency) {
-		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
-		if (ret)
-			goto err;
-
-		dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
-	}
-
-	switch (if_frequency) {
-	case 3570000:
-	case 4570000:
-	case 5070000:
-		break;
-	default:
-		dev_err(&client->dev, "IF frequency %d not supported\n",
-				if_frequency);
-		ret = -EINVAL;
-		goto err;
-	}
-
-	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)
-		goto err;
-
-	ret = regmap_write(dev->regmap[2], 0x00, 0x66);
-	if (ret)
-		goto err;
-	ret = regmap_write(dev->regmap[2], 0x01, 0x00);
-	if (ret)
-		goto err;
-	ret = regmap_write(dev->regmap[2], 0x02, 0x01);
-	if (ret)
-		goto err;
-	ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
-	if (ret)
-		goto err;
-	ret = regmap_write(dev->regmap[2], 0x04, bw_val2);
-	if (ret)
-		goto err;
-
-	for (i = 0; i < sizeof(if_val); i++) {
-		ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[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;
-	}
-
-	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);
-		ret = regmap_write(dev->regmap[0], 0x00, 0xba);
-		ret = regmap_write(dev->regmap[0], 0x01, 0x13);
-		if (ret)
-			goto err;
-		break;
-	case SYS_DVBT2:
-		ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
-		ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
-		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);
-		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);
-	ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
-	ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
-	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, fe_status_t *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;
-
-	*status = 0;
-
-	if (!dev->warm) {
-		ret = -EAGAIN;
-		goto err;
-	}
-
-	switch (c->delivery_system) {
-	case SYS_DVBT:
-	case SYS_DVBT2:
-		/* FIXME: implement me */
-		utmp = 0x08; /* DVB-C lock value */
-		break;
-	case SYS_DVBC_ANNEX_A:
-		ret = regmap_read(dev->regmap[1], 0x84, &utmp);
-		if (ret)
-			goto err;
-		break;
-	default:
-		ret = -EINVAL;
-		goto err;
-	}
-
-	if (utmp == 0x08)
-		*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);
-	return ret;
-}
-
-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;
-
-	dev_dbg(&client->dev, "\n");
-
-	/* set cold state by default */
-	dev->warm = false;
-
-	/* power on */
-	ret = regmap_write(dev->regmap[2], 0x05, 0x00);
-	if (ret)
-		goto err;
-
-	ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2);
-	if (ret)
-		goto err;
-
-	/* request the firmware, this will block and timeout */
-	ret = request_firmware(&fw, fw_file, &client->dev);
-	if (ret) {
-		dev_err(&client->dev, "firmare file '%s' not found\n",
-				fw_file);
-		goto err;
-	}
-
-	dev_info(&client->dev, "downloading firmware from file '%s'\n",
-			fw_file);
-
-	ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
-	if (ret)
-		goto err;
-
-	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);
-
-		ret = regmap_bulk_write(dev->regmap[0], 0xf6,
-				&fw->data[fw->size - remaining], len);
-		if (ret) {
-			dev_err(&client->dev,
-					"firmware download failed=%d\n", ret);
-			goto err;
-		}
-	}
-
-	ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
-	if (ret)
-		goto err;
-
-	release_firmware(fw);
-	fw = NULL;
-
-	/* warm state */
-	dev->warm = true;
-
-	return 0;
-err:
-	if (fw)
-		release_firmware(fw);
-
-	dev_dbg(&client->dev, "failed=%d\n", ret);
-	return ret;
-}
-
-static int mn88472_sleep(struct dvb_frontend *fe)
-{
-	struct i2c_client *client = fe->demodulator_priv;
-	struct mn88472_dev *dev = i2c_get_clientdata(client);
-	int ret;
-
-	dev_dbg(&client->dev, "\n");
-
-	/* power off */
-	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);
-	return ret;
-}
-
-static struct dvb_frontend_ops mn88472_ops = {
-	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
-	.info = {
-		.name = "Panasonic MN88472",
-		.caps =	FE_CAN_FEC_1_2                 |
-			FE_CAN_FEC_2_3                 |
-			FE_CAN_FEC_3_4                 |
-			FE_CAN_FEC_5_6                 |
-			FE_CAN_FEC_7_8                 |
-			FE_CAN_FEC_AUTO                |
-			FE_CAN_QPSK                    |
-			FE_CAN_QAM_16                  |
-			FE_CAN_QAM_32                  |
-			FE_CAN_QAM_64                  |
-			FE_CAN_QAM_128                 |
-			FE_CAN_QAM_256                 |
-			FE_CAN_QAM_AUTO                |
-			FE_CAN_TRANSMISSION_MODE_AUTO  |
-			FE_CAN_GUARD_INTERVAL_AUTO     |
-			FE_CAN_HIERARCHY_AUTO          |
-			FE_CAN_MUTE_TS                 |
-			FE_CAN_2G_MODULATION           |
-			FE_CAN_MULTISTREAM
-	},
-
-	.get_tune_settings = mn88472_get_tune_settings,
-
-	.init = mn88472_init,
-	.sleep = mn88472_sleep,
-
-	.set_frontend = mn88472_set_frontend,
-
-	.read_status = mn88472_read_status,
-};
-
-static int mn88472_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
-{
-	struct mn88472_config *config = client->dev.platform_data;
-	struct mn88472_dev *dev;
-	int ret;
-	unsigned int utmp;
-	static const struct regmap_config regmap_config = {
-		.reg_bits = 8,
-		.val_bits = 8,
-	};
-
-	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) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	dev->i2c_wr_max = config->i2c_wr_max;
-	dev->client[0] = client;
-	dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);
-	if (IS_ERR(dev->regmap[0])) {
-		ret = PTR_ERR(dev->regmap[0]);
-		goto err_kfree;
-	}
-
-	/* check demod answers to I2C */
-	ret = regmap_read(dev->regmap[0], 0x00, &utmp);
-	if (ret)
-		goto err_regmap_0_regmap_exit;
-
-	/*
-	 * Chip has three I2C addresses for different register pages. 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.
-	 */
-	dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
-	if (dev->client[1] == NULL) {
-		ret = -ENODEV;
-		dev_err(&client->dev, "I2C registration failed\n");
-		if (ret)
-			goto err_regmap_0_regmap_exit;
-	}
-	dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);
-	if (IS_ERR(dev->regmap[1])) {
-		ret = PTR_ERR(dev->regmap[1]);
-		goto err_client_1_i2c_unregister_device;
-	}
-	i2c_set_clientdata(dev->client[1], dev);
-
-	dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
-	if (dev->client[2] == NULL) {
-		ret = -ENODEV;
-		dev_err(&client->dev, "2nd I2C registration failed\n");
-		if (ret)
-			goto err_regmap_1_regmap_exit;
-	}
-	dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);
-	if (IS_ERR(dev->regmap[2])) {
-		ret = PTR_ERR(dev->regmap[2]);
-		goto err_client_2_i2c_unregister_device;
-	}
-	i2c_set_clientdata(dev->client[2], dev);
-
-	/* create dvb_frontend */
-	memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
-	dev->fe.demodulator_priv = client;
-	*config->fe = &dev->fe;
-	i2c_set_clientdata(client, dev);
-
-	dev_info(&client->dev, "Panasonic MN88472 successfully attached\n");
-	return 0;
-
-err_client_2_i2c_unregister_device:
-	i2c_unregister_device(dev->client[2]);
-err_regmap_1_regmap_exit:
-	regmap_exit(dev->regmap[1]);
-err_client_1_i2c_unregister_device:
-	i2c_unregister_device(dev->client[1]);
-err_regmap_0_regmap_exit:
-	regmap_exit(dev->regmap[0]);
-err_kfree:
-	kfree(dev);
-err:
-	dev_dbg(&client->dev, "failed=%d\n", ret);
-	return ret;
-}
-
-static int mn88472_remove(struct i2c_client *client)
-{
-	struct mn88472_dev *dev = i2c_get_clientdata(client);
-
-	dev_dbg(&client->dev, "\n");
-
-	regmap_exit(dev->regmap[2]);
-	i2c_unregister_device(dev->client[2]);
-
-	regmap_exit(dev->regmap[1]);
-	i2c_unregister_device(dev->client[1]);
-
-	regmap_exit(dev->regmap[0]);
-
-	kfree(dev);
-
-	return 0;
-}
-
-static const struct i2c_device_id mn88472_id_table[] = {
-	{"mn88472", 0},
-	{}
-};
-MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
-
-static struct i2c_driver mn88472_driver = {
-	.driver = {
-		.owner	= THIS_MODULE,
-		.name	= "mn88472",
-	},
-	.probe		= mn88472_probe,
-	.remove		= mn88472_remove,
-	.id_table	= mn88472_id_table,
-};
-
-module_i2c_driver(mn88472_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(MN88472_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
deleted file mode 100644
index 1095949..0000000
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Panasonic MN88472 DVB-T/T2/C demodulator driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- */
-
-#ifndef MN88472_PRIV_H
-#define MN88472_PRIV_H
-
-#include "dvb_frontend.h"
-#include "mn88472.h"
-#include <linux/firmware.h>
-#include <linux/regmap.h>
-
-#define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
-
-struct mn88472_dev {
-	struct i2c_client *client[3];
-	struct regmap *regmap[3];
-	struct dvb_frontend fe;
-	u16 i2c_wr_max;
-	fe_delivery_system_t delivery_system;
-	bool warm; /* FW running */
-};
-
-#endif
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 655cf50..c2e675a 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -27,6 +27,8 @@ source "drivers/staging/media/davinci_vpfe/Kconfig"
 
 source "drivers/staging/media/dt3155v4l/Kconfig"
 
+source "drivers/staging/media/mn88472/Kconfig"
+
 source "drivers/staging/media/omap24xx/Kconfig"
 
 source "drivers/staging/media/omap4iss/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 6dbe578..e174c57 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_VIDEO_DM365_VPFE)	+= davinci_vpfe/
 obj-$(CONFIG_VIDEO_OMAP4)	+= omap4iss/
 obj-$(CONFIG_VIDEO_OMAP2)       += omap24xx/
 obj-$(CONFIG_VIDEO_TCM825X)     += omap24xx/
+obj-$(CONFIG_DVB_MN88472)       += mn88472/
 
diff --git a/drivers/staging/media/mn88472/Kconfig b/drivers/staging/media/mn88472/Kconfig
new file mode 100644
index 0000000..a85c90a
--- /dev/null
+++ b/drivers/staging/media/mn88472/Kconfig
@@ -0,0 +1,7 @@
+config DVB_MN88472
+	tristate "Panasonic MN88472"
+	depends on DVB_CORE && I2C
+	select REGMAP_I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  Say Y when you want to support this frontend.
diff --git a/drivers/staging/media/mn88472/Makefile b/drivers/staging/media/mn88472/Makefile
new file mode 100644
index 0000000..5987b7e
--- /dev/null
+++ b/drivers/staging/media/mn88472/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_DVB_MN88472) += mn88472.o
+
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/staging/media/mn88472/mn88472.c b/drivers/staging/media/mn88472/mn88472.c
new file mode 100644
index 0000000..52de8f8
--- /dev/null
+++ b/drivers/staging/media/mn88472/mn88472.c
@@ -0,0 +1,523 @@
+/*
+ * Panasonic MN88472 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "mn88472_priv.h"
+
+static int mn88472_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 400;
+	return 0;
+}
+
+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;
+	u8 delivery_system_val, if_val[3], bw_val[7], bw_val2;
+
+	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);
+
+	if (!dev->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+		delivery_system_val = 0x02;
+		break;
+	case SYS_DVBT2:
+		delivery_system_val = 0x03;
+		break;
+	case SYS_DVBC_ANNEX_A:
+		delivery_system_val = 0x04;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		if (c->bandwidth_hz <= 6000000) {
+			/* IF 3570000 Hz, BW 6000000 Hz */
+			memcpy(if_val, "\x2c\x94\xdb", 3);
+			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(if_val, "\x39\x11\xbc", 3);
+			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(if_val, "\x39\x11\xbc", 3);
+			memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
+			bw_val2 = 0x00;
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	case SYS_DVBC_ANNEX_A:
+		/* IF 5070000 Hz, BW 8000000 Hz */
+		memcpy(if_val, "\x3f\x50\x2c", 3);
+		memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
+		bw_val2 = 0x00;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params) {
+		ret = fe->ops.tuner_ops.set_params(fe);
+		if (ret)
+			goto err;
+	}
+
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+		if (ret)
+			goto err;
+
+		dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
+	}
+
+	switch (if_frequency) {
+	case 3570000:
+	case 4570000:
+	case 5070000:
+		break;
+	default:
+		dev_err(&client->dev, "IF frequency %d not supported\n",
+				if_frequency);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	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)
+		goto err;
+
+	ret = regmap_write(dev->regmap[2], 0x00, 0x66);
+	if (ret)
+		goto err;
+	ret = regmap_write(dev->regmap[2], 0x01, 0x00);
+	if (ret)
+		goto err;
+	ret = regmap_write(dev->regmap[2], 0x02, 0x01);
+	if (ret)
+		goto err;
+	ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
+	if (ret)
+		goto err;
+	ret = regmap_write(dev->regmap[2], 0x04, bw_val2);
+	if (ret)
+		goto err;
+
+	for (i = 0; i < sizeof(if_val); i++) {
+		ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[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;
+	}
+
+	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);
+		ret = regmap_write(dev->regmap[0], 0x00, 0xba);
+		ret = regmap_write(dev->regmap[0], 0x01, 0x13);
+		if (ret)
+			goto err;
+		break;
+	case SYS_DVBT2:
+		ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
+		ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
+		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);
+		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);
+	ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
+	ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
+	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, fe_status_t *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;
+
+	*status = 0;
+
+	if (!dev->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		/* FIXME: implement me */
+		utmp = 0x08; /* DVB-C lock value */
+		break;
+	case SYS_DVBC_ANNEX_A:
+		ret = regmap_read(dev->regmap[1], 0x84, &utmp);
+		if (ret)
+			goto err;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (utmp == 0x08)
+		*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);
+	return ret;
+}
+
+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;
+
+	dev_dbg(&client->dev, "\n");
+
+	/* set cold state by default */
+	dev->warm = false;
+
+	/* power on */
+	ret = regmap_write(dev->regmap[2], 0x05, 0x00);
+	if (ret)
+		goto err;
+
+	ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2);
+	if (ret)
+		goto err;
+
+	/* request the firmware, this will block and timeout */
+	ret = request_firmware(&fw, fw_file, &client->dev);
+	if (ret) {
+		dev_err(&client->dev, "firmare file '%s' not found\n",
+				fw_file);
+		goto err;
+	}
+
+	dev_info(&client->dev, "downloading firmware from file '%s'\n",
+			fw_file);
+
+	ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
+	if (ret)
+		goto err;
+
+	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);
+
+		ret = regmap_bulk_write(dev->regmap[0], 0xf6,
+				&fw->data[fw->size - remaining], len);
+		if (ret) {
+			dev_err(&client->dev,
+					"firmware download failed=%d\n", ret);
+			goto err;
+		}
+	}
+
+	ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
+	if (ret)
+		goto err;
+
+	release_firmware(fw);
+	fw = NULL;
+
+	/* warm state */
+	dev->warm = true;
+
+	return 0;
+err:
+	if (fw)
+		release_firmware(fw);
+
+	dev_dbg(&client->dev, "failed=%d\n", ret);
+	return ret;
+}
+
+static int mn88472_sleep(struct dvb_frontend *fe)
+{
+	struct i2c_client *client = fe->demodulator_priv;
+	struct mn88472_dev *dev = i2c_get_clientdata(client);
+	int ret;
+
+	dev_dbg(&client->dev, "\n");
+
+	/* power off */
+	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);
+	return ret;
+}
+
+static struct dvb_frontend_ops mn88472_ops = {
+	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
+	.info = {
+		.name = "Panasonic MN88472",
+		.caps =	FE_CAN_FEC_1_2                 |
+			FE_CAN_FEC_2_3                 |
+			FE_CAN_FEC_3_4                 |
+			FE_CAN_FEC_5_6                 |
+			FE_CAN_FEC_7_8                 |
+			FE_CAN_FEC_AUTO                |
+			FE_CAN_QPSK                    |
+			FE_CAN_QAM_16                  |
+			FE_CAN_QAM_32                  |
+			FE_CAN_QAM_64                  |
+			FE_CAN_QAM_128                 |
+			FE_CAN_QAM_256                 |
+			FE_CAN_QAM_AUTO                |
+			FE_CAN_TRANSMISSION_MODE_AUTO  |
+			FE_CAN_GUARD_INTERVAL_AUTO     |
+			FE_CAN_HIERARCHY_AUTO          |
+			FE_CAN_MUTE_TS                 |
+			FE_CAN_2G_MODULATION           |
+			FE_CAN_MULTISTREAM
+	},
+
+	.get_tune_settings = mn88472_get_tune_settings,
+
+	.init = mn88472_init,
+	.sleep = mn88472_sleep,
+
+	.set_frontend = mn88472_set_frontend,
+
+	.read_status = mn88472_read_status,
+};
+
+static int mn88472_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct mn88472_config *config = client->dev.platform_data;
+	struct mn88472_dev *dev;
+	int ret;
+	unsigned int utmp;
+	static const struct regmap_config regmap_config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+
+	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) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	dev->i2c_wr_max = config->i2c_wr_max;
+	dev->client[0] = client;
+	dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);
+	if (IS_ERR(dev->regmap[0])) {
+		ret = PTR_ERR(dev->regmap[0]);
+		goto err_kfree;
+	}
+
+	/* check demod answers to I2C */
+	ret = regmap_read(dev->regmap[0], 0x00, &utmp);
+	if (ret)
+		goto err_regmap_0_regmap_exit;
+
+	/*
+	 * Chip has three I2C addresses for different register pages. 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.
+	 */
+	dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
+	if (dev->client[1] == NULL) {
+		ret = -ENODEV;
+		dev_err(&client->dev, "I2C registration failed\n");
+		if (ret)
+			goto err_regmap_0_regmap_exit;
+	}
+	dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);
+	if (IS_ERR(dev->regmap[1])) {
+		ret = PTR_ERR(dev->regmap[1]);
+		goto err_client_1_i2c_unregister_device;
+	}
+	i2c_set_clientdata(dev->client[1], dev);
+
+	dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
+	if (dev->client[2] == NULL) {
+		ret = -ENODEV;
+		dev_err(&client->dev, "2nd I2C registration failed\n");
+		if (ret)
+			goto err_regmap_1_regmap_exit;
+	}
+	dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);
+	if (IS_ERR(dev->regmap[2])) {
+		ret = PTR_ERR(dev->regmap[2]);
+		goto err_client_2_i2c_unregister_device;
+	}
+	i2c_set_clientdata(dev->client[2], dev);
+
+	/* create dvb_frontend */
+	memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
+	dev->fe.demodulator_priv = client;
+	*config->fe = &dev->fe;
+	i2c_set_clientdata(client, dev);
+
+	dev_info(&client->dev, "Panasonic MN88472 successfully attached\n");
+	return 0;
+
+err_client_2_i2c_unregister_device:
+	i2c_unregister_device(dev->client[2]);
+err_regmap_1_regmap_exit:
+	regmap_exit(dev->regmap[1]);
+err_client_1_i2c_unregister_device:
+	i2c_unregister_device(dev->client[1]);
+err_regmap_0_regmap_exit:
+	regmap_exit(dev->regmap[0]);
+err_kfree:
+	kfree(dev);
+err:
+	dev_dbg(&client->dev, "failed=%d\n", ret);
+	return ret;
+}
+
+static int mn88472_remove(struct i2c_client *client)
+{
+	struct mn88472_dev *dev = i2c_get_clientdata(client);
+
+	dev_dbg(&client->dev, "\n");
+
+	regmap_exit(dev->regmap[2]);
+	i2c_unregister_device(dev->client[2]);
+
+	regmap_exit(dev->regmap[1]);
+	i2c_unregister_device(dev->client[1]);
+
+	regmap_exit(dev->regmap[0]);
+
+	kfree(dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id mn88472_id_table[] = {
+	{"mn88472", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
+
+static struct i2c_driver mn88472_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "mn88472",
+	},
+	.probe		= mn88472_probe,
+	.remove		= mn88472_remove,
+	.id_table	= mn88472_id_table,
+};
+
+module_i2c_driver(mn88472_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(MN88472_FIRMWARE);
diff --git a/drivers/staging/media/mn88472/mn88472_priv.h b/drivers/staging/media/mn88472/mn88472_priv.h
new file mode 100644
index 0000000..1095949
--- /dev/null
+++ b/drivers/staging/media/mn88472/mn88472_priv.h
@@ -0,0 +1,36 @@
+/*
+ * Panasonic MN88472 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef MN88472_PRIV_H
+#define MN88472_PRIV_H
+
+#include "dvb_frontend.h"
+#include "mn88472.h"
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+
+#define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
+
+struct mn88472_dev {
+	struct i2c_client *client[3];
+	struct regmap *regmap[3];
+	struct dvb_frontend fe;
+	u16 i2c_wr_max;
+	fe_delivery_system_t delivery_system;
+	bool warm; /* FW running */
+};
+
+#endif
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 10/11] mn88472: add staging TODO
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (8 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 09/11] mn88472: move to staging Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  2014-11-12  4:11 ` [PATCH 11/11] MAINTAINERS: add mn88472 (Panasonic MN88472) Antti Palosaari
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Add TODO for mainlining.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/staging/media/mn88472/TODO | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 drivers/staging/media/mn88472/TODO

diff --git a/drivers/staging/media/mn88472/TODO b/drivers/staging/media/mn88472/TODO
new file mode 100644
index 0000000..b90a14b
--- /dev/null
+++ b/drivers/staging/media/mn88472/TODO
@@ -0,0 +1,21 @@
+Driver general quality is not good enough for mainline. Also, other
+device drivers (USB-bridge, tuner) needed for Astrometa receiver in
+question could need some changes. However, if that driver is mainlined
+due to some other device than Astrometa, unrelated TODOs could be
+skipped. In that case rtl28xxu driver needs module parameter to prevent
+driver loading.
+
+Required TODOs:
+* missing lock flags
+* I2C errors
+* tuner sensitivity
+
+*Do not* send any patch fixing checkpatch.pl issues. Currently it passes
+checkpatch.pl tests. I don't want waste my time to review this kind of
+trivial stuff. *Do not* add missing register I/O error checks. Those are
+missing for the reason it is much easier to compare I2C data sniffs when
+there is less lines. Those error checks are about the last thing to be added.
+
+Patches should be submitted to:
+linux-media@vger.kernel.org and Antti Palosaari <crope@iki.fi>
+
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 11/11] MAINTAINERS: add mn88472 (Panasonic MN88472)
  2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
                   ` (9 preceding siblings ...)
  2014-11-12  4:11 ` [PATCH 10/11] mn88472: add staging TODO Antti Palosaari
@ 2014-11-12  4:11 ` Antti Palosaari
  10 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:11 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Add mn88472 driver from staging. DVB-T/T2/C demodulator driver.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 MAINTAINERS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2a9cff1..644a1ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6115,6 +6115,17 @@ S:	Supported
 F:	include/linux/mlx5/
 F:	drivers/infiniband/hw/mlx5/
 
+MN88472 MEDIA DRIVER
+M:	Antti Palosaari <crope@iki.fi>
+L:	linux-media@vger.kernel.org
+W:	http://linuxtv.org/
+W:	http://palosaari.fi/linux/
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+T:	git git://linuxtv.org/anttip/media_tree.git
+S:	Maintained
+F:	drivers/staging/media/mn88472/
+F:	drivers/media/dvb-frontends/mn88472.h
+
 MODULE SUPPORT
 M:	Rusty Russell <rusty@rustcorp.com.au>
 S:	Maintained
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-11-12  4:11 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-12  4:11 [PATCH 00/11] Panasonic MN88472 DVB-T/T2/C demod driver Antti Palosaari
2014-11-12  4:11 ` [PATCH 01/11] mn88472: Panasonic MN88472 demod driver (DVB-C only) Antti Palosaari
2014-11-12  4:11 ` [PATCH 02/11] mn88472: correct attach symbol name Antti Palosaari
2014-11-12  4:11 ` [PATCH 03/11] mn88472: add small delay to wait DVB-C lock Antti Palosaari
2014-11-12  4:11 ` [PATCH 04/11] mn88472: rename mn88472_c.c => mn88472.c Antti Palosaari
2014-11-12  4:11 ` [PATCH 05/11] mn88472: rename state to dev Antti Palosaari
2014-11-12  4:11 ` [PATCH 06/11] mn88472: convert driver to I2C client Antti Palosaari
2014-11-12  4:11 ` [PATCH 07/11] mn88472: Convert driver to I2C RegMap API Antti Palosaari
2014-11-12  4:11 ` [PATCH 08/11] mn88472: implement DVB-T and DVB-T2 Antti Palosaari
2014-11-12  4:11 ` [PATCH 09/11] mn88472: move to staging Antti Palosaari
2014-11-12  4:11 ` [PATCH 10/11] mn88472: add staging TODO Antti Palosaari
2014-11-12  4:11 ` [PATCH 11/11] MAINTAINERS: add mn88472 (Panasonic MN88472) Antti Palosaari

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).