* [PATCH v3 06/21] ARM: dts: efm32: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Wolfram Sang, Javier Martinez Canillas,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
Uwe Kleine-König, Mark Rutland, Russell King,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170414010445.21727-1-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/efm32gg-dk3750.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
index 98fc667d22c7..84f0a9abc290 100644
--- a/arch/arm/boot/dts/efm32gg-dk3750.dts
+++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
@@ -36,7 +36,7 @@
};
eeprom@50 {
- compatible = "microchip,24c02";
+ compatible = "microchip,24c02", "atmel,24c02";
reg = <0x50>;
pagesize = <16>;
};
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 07/21] ARM: dts: imx: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Wolfram Sang, Javier Martinez Canillas, Fabio Estevam,
devicetree-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Rob Herring,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
Russell King, Shawn Guo
In-Reply-To: <20170414010445.21727-1-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi | 2 +-
arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi | 2 +-
arch/arm/boot/dts/imx28-evk.dts | 2 +-
arch/arm/boot/dts/imx53-tqma53.dtsi | 2 +-
arch/arm/boot/dts/imx6q-cm-fx6.dts | 2 +-
arch/arm/boot/dts/imx6q-utilite-pro.dts | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
index 4f3e0f473581..e4c20b3a8ccd 100644
--- a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
+++ b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
@@ -40,7 +40,7 @@
status = "okay";
at24@52 {
- compatible = "at,24c32";
+ compatible = "at,24c32", "atmel,24c32";
pagesize = <32>;
reg = <0x52>;
};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
index 82fec935ce83..e46a2fd55732 100644
--- a/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
+++ b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
@@ -193,7 +193,7 @@
status = "okay";
at24@52 {
- compatible = "at,24c32";
+ compatible = "at,24c32", "atmel,24c32";
pagesize = <32>;
reg = <0x52>;
};
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index a5ba669b4eaa..55c1a6a7425d 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -203,7 +203,7 @@
};
at24@51 {
- compatible = "at24,24c32";
+ compatible = "at24,24c32", "atmel,24c32";
pagesize = <32>;
reg = <0x51>;
};
diff --git a/arch/arm/boot/dts/imx53-tqma53.dtsi b/arch/arm/boot/dts/imx53-tqma53.dtsi
index 85972f2201c2..95da69691de3 100644
--- a/arch/arm/boot/dts/imx53-tqma53.dtsi
+++ b/arch/arm/boot/dts/imx53-tqma53.dtsi
@@ -272,7 +272,7 @@
};
eeprom: 24c64@50 {
- compatible = "at,24c64";
+ compatible = "at,24c64", "atmel,24c64";
pagesize = <32>;
reg = <0x50>;
};
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
index 66cac5328b86..9dda47a86552 100644
--- a/arch/arm/boot/dts/imx6q-cm-fx6.dts
+++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts
@@ -215,7 +215,7 @@
clock-frequency = <100000>;
eeprom@50 {
- compatible = "at24,24c02";
+ compatible = "at24,24c02", "atmel,24c02";
reg = <0x50>;
pagesize = <16>;
};
diff --git a/arch/arm/boot/dts/imx6q-utilite-pro.dts b/arch/arm/boot/dts/imx6q-utilite-pro.dts
index 69bdd82ce21f..085080f61c7b 100644
--- a/arch/arm/boot/dts/imx6q-utilite-pro.dts
+++ b/arch/arm/boot/dts/imx6q-utilite-pro.dts
@@ -128,7 +128,7 @@
#size-cells = <0>;
eeprom@50 {
- compatible = "at24,24c02";
+ compatible = "at24,24c02", "atmel,24c02";
reg = <0x50>;
pagesize = <16>;
};
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 08/21] ARM: dts: keystone: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Mark Rutland, devicetree, Wolfram Sang, Russell King,
Javier Martinez Canillas, Rob Herring, Santosh Shilimkar,
linux-arm-kernel
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/keystone-k2e-evm.dts | 2 +-
arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
arch/arm/boot/dts/keystone-k2l-evm.dts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/keystone-k2e-evm.dts b/arch/arm/boot/dts/keystone-k2e-evm.dts
index ae1ebe7ee021..8c79caae9c1b 100644
--- a/arch/arm/boot/dts/keystone-k2e-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2e-evm.dts
@@ -69,7 +69,7 @@
&i2c0 {
dtt@50 {
- compatible = "at,24c1024";
+ compatible = "at,24c1024", "atmel,24c1024";
reg = <0x50>;
};
};
diff --git a/arch/arm/boot/dts/keystone-k2hk-evm.dts b/arch/arm/boot/dts/keystone-k2hk-evm.dts
index 2156ff92d08f..7c6916a11b18 100644
--- a/arch/arm/boot/dts/keystone-k2hk-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2hk-evm.dts
@@ -145,7 +145,7 @@
&i2c0 {
dtt@50 {
- compatible = "at,24c1024";
+ compatible = "at,24c1024", "atmel,24c1024";
reg = <0x50>;
};
};
diff --git a/arch/arm/boot/dts/keystone-k2l-evm.dts b/arch/arm/boot/dts/keystone-k2l-evm.dts
index 056b42f99d7a..685a236a57f4 100644
--- a/arch/arm/boot/dts/keystone-k2l-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2l-evm.dts
@@ -42,7 +42,7 @@
&i2c0 {
dtt@50 {
- compatible = "at,24c1024";
+ compatible = "at,24c1024", "atmel,24c1024";
reg = <0x50>;
};
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 09/21] ARM: dts: lpc18xx: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Mark Rutland, devicetree, Wolfram Sang, Joachim Eastwood,
Russell King, Javier Martinez Canillas, Rob Herring,
linux-arm-kernel
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/lpc4337-ciaa.dts | 6 +++---
arch/arm/boot/dts/lpc4350-hitex-eval.dts | 2 +-
arch/arm/boot/dts/lpc4357-ea4357-devkit.dts | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/lpc4337-ciaa.dts b/arch/arm/boot/dts/lpc4337-ciaa.dts
index 7c16d639a1b4..beddaba85393 100644
--- a/arch/arm/boot/dts/lpc4337-ciaa.dts
+++ b/arch/arm/boot/dts/lpc4337-ciaa.dts
@@ -174,17 +174,17 @@
clock-frequency = <400000>;
eeprom@50 {
- compatible = "microchip,24c512";
+ compatible = "microchip,24c512", "atmel,24c512";
reg = <0x50>;
};
eeprom@51 {
- compatible = "microchip,24c02";
+ compatible = "microchip,24c02", "atmel,24c02";
reg = <0x51>;
};
eeprom@54 {
- compatible = "microchip,24c512";
+ compatible = "microchip,24c512", "atmel,24c512";
reg = <0x54>;
};
};
diff --git a/arch/arm/boot/dts/lpc4350-hitex-eval.dts b/arch/arm/boot/dts/lpc4350-hitex-eval.dts
index 874c75d44013..8b973f537d3a 100644
--- a/arch/arm/boot/dts/lpc4350-hitex-eval.dts
+++ b/arch/arm/boot/dts/lpc4350-hitex-eval.dts
@@ -429,7 +429,7 @@
};
eeprom@50 {
- compatible = "nxp,24c02";
+ compatible = "nxp,24c02", "atmel,24c02";
reg = <0x50>;
};
diff --git a/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts b/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
index 9b5fad622522..02b23fa29d75 100644
--- a/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
+++ b/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
@@ -490,7 +490,7 @@
};
eeprom@57 {
- compatible = "microchip,24c64";
+ compatible = "microchip,24c64", "atmel,24c64";
reg = <0x57>;
};
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 10/21] ARM: dts: r7s72100: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Wolfram Sang, Javier Martinez Canillas, Simon Horman,
devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
Magnus Damm, Mark Rutland,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170414010445.21727-1-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
---
Changes in v3:
- Add Geert Uytterhoeven reviewed-by tag.
Changes in v2: None
arch/arm/boot/dts/r7s72100-genmai.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts
index 52a7b586bac7..b0db621ff176 100644
--- a/arch/arm/boot/dts/r7s72100-genmai.dts
+++ b/arch/arm/boot/dts/r7s72100-genmai.dts
@@ -57,7 +57,7 @@
clock-frequency = <400000>;
eeprom@50 {
- compatible = "renesas,24c128";
+ compatible = "renesas,24c128", "atmel,24c128";
reg = <0x50>;
pagesize = <64>;
};
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 11/21] ARM: dts: koelsch: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, Simon Horman, devicetree,
Russell King, linux-renesas-soc, Rob Herring, Magnus Damm,
Mark Rutland, linux-arm-kernel
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Changes in v3:
- Add Geert Uytterhoeven reviewed-by tag.
Changes in v2: None
arch/arm/boot/dts/r8a7791-koelsch.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 001e6116c47c..dc8ed02de707 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -702,7 +702,7 @@
};
eeprom@50 {
- compatible = "renesas,24c02";
+ compatible = "renesas,24c02", "atmel,24c02";
reg = <0x50>;
pagesize = <16>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 12/21] ARM: dts: socfpga: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Mark Rutland, devicetree, Dinh Nguyen, Wolfram Sang, Russell King,
Javier Martinez Canillas, Rob Herring, linux-arm-kernel
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
index 363ee62457fe..24f566d81667 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
@@ -294,7 +294,7 @@
clock-frequency = <100000>;
at24@50 {
- compatible = "at24,24c02";
+ compatible = "at24,24c02", "atmel,24c02";
pagesize = <8>;
reg = <0x50>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 13/21] ARM: dts: uniphier: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree,
Masahiro Yamada, Rob Herring, Mark Rutland, Russell King,
linux-arm-kernel
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/uniphier-pro4-ace.dts | 2 +-
arch/arm/boot/dts/uniphier-pro4-sanji.dts | 2 +-
arch/arm/boot/dts/uniphier-pxs2-gentil.dts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/uniphier-pro4-ace.dts b/arch/arm/boot/dts/uniphier-pro4-ace.dts
index fefc89149234..b9a4919d7c93 100644
--- a/arch/arm/boot/dts/uniphier-pro4-ace.dts
+++ b/arch/arm/boot/dts/uniphier-pro4-ace.dts
@@ -88,7 +88,7 @@
status = "okay";
eeprom@54 {
- compatible = "st,24c64";
+ compatible = "st,24c64", "atmel,24c64";
reg = <0x54>;
pagesize = <32>;
};
diff --git a/arch/arm/boot/dts/uniphier-pro4-sanji.dts b/arch/arm/boot/dts/uniphier-pro4-sanji.dts
index 6c63c8bad825..3950baa8d55d 100644
--- a/arch/arm/boot/dts/uniphier-pro4-sanji.dts
+++ b/arch/arm/boot/dts/uniphier-pro4-sanji.dts
@@ -83,7 +83,7 @@
status = "okay";
eeprom@54 {
- compatible = "st,24c64";
+ compatible = "st,24c64", "atmel,24c64";
reg = <0x54>;
pagesize = <32>;
};
diff --git a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts
index cccc86658d20..afba587ffbbc 100644
--- a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts
+++ b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts
@@ -80,7 +80,7 @@
status = "okay";
eeprom@54 {
- compatible = "st,24c64";
+ compatible = "st,24c64", "atmel,24c64";
reg = <0x54>;
pagesize = <32>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 14/21] ARM: dts: zynq: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Wolfram Sang, Javier Martinez Canillas, Sören Brinkmann,
devicetree-u79uwXL29TY76Z2rM5mHXA, Michal Simek, Rob Herring,
Mark Rutland, Russell King,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170414010445.21727-1-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/zynq-zc702.dts | 2 +-
arch/arm/boot/dts/zynq-zc706.dts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index 0cdad2cc8b78..9aae7e061d19 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -136,7 +136,7 @@
#size-cells = <0>;
reg = <2>;
eeprom@54 {
- compatible = "at,24c08";
+ compatible = "at,24c08", "atmel,24c08";
reg = <0x54>;
};
};
diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts
index ad4bb06dba25..ff0fca1c41c8 100644
--- a/arch/arm/boot/dts/zynq-zc706.dts
+++ b/arch/arm/boot/dts/zynq-zc706.dts
@@ -92,7 +92,7 @@
#size-cells = <0>;
reg = <2>;
eeprom@54 {
- compatible = "at,24c08";
+ compatible = "at,24c08", "atmel,24c08";
reg = <0x54>;
};
};
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 15/21] arm64: dts: ls1043a: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree, Stuart Yoder,
Rob Herring, Hongtao Jia, linux-arm-kernel, Will Deacon,
Herbert Xu, Mark Rutland, Catalin Marinas, Shawn Guo,
Horia Geantă
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
index c37110bc1506..5389eae627e5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
@@ -75,11 +75,11 @@
reg = <0x4c>;
};
eeprom@52 {
- compatible = "at24,24c512";
+ compatible = "at24,24c512", "atmel,24c512";
reg = <0x52>;
};
eeprom@53 {
- compatible = "at24,24c512";
+ compatible = "at24,24c512", "atmel,24c512";
reg = <0x53>;
};
rtc@68 {
--
2.9.3
^ permalink raw reply related
* [PATCH v3 16/21] arm64: zynqmp: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, Sören Brinkmann,
devicetree, Michal Simek, Rob Herring, Will Deacon, Mark Rutland,
Catalin Marinas, linux-arm-kernel
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
index ef1b9e573af0..9f29f99984f7 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
@@ -55,7 +55,7 @@
status = "okay";
clock-frequency = <400000>;
eeprom@54 {
- compatible = "at,24c64";
+ compatible = "at,24c64", "atmel,24c64";
reg = <0x54>;
};
};
@@ -64,7 +64,7 @@
status = "okay";
clock-frequency = <400000>;
eeprom@55 {
- compatible = "at,24c64";
+ compatible = "at,24c64", "atmel,24c64";
reg = <0x55>;
};
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 17/21] powerpc/5200: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree,
Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Rob Herring, Mark Rutland, linuxppc-dev
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/powerpc/boot/dts/digsy_mtc.dts | 2 +-
arch/powerpc/boot/dts/pcm030.dts | 2 +-
arch/powerpc/boot/dts/pcm032.dts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts
index 955bff629df3..0acb6ff7fc22 100644
--- a/arch/powerpc/boot/dts/digsy_mtc.dts
+++ b/arch/powerpc/boot/dts/digsy_mtc.dts
@@ -73,7 +73,7 @@
i2c@3d00 {
eeprom@50 {
- compatible = "at,24c08";
+ compatible = "at,24c08", "atmel,24c08";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index 192e66af0001..836e47cc4bed 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -71,7 +71,7 @@
reg = <0x51>;
};
eeprom@52 {
- compatible = "catalyst,24c32";
+ compatible = "catalyst,24c32", "atmel,24c32";
reg = <0x52>;
pagesize = <32>;
};
diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts
index 96b139bf50e9..576249bf2fb9 100644
--- a/arch/powerpc/boot/dts/pcm032.dts
+++ b/arch/powerpc/boot/dts/pcm032.dts
@@ -75,7 +75,7 @@
reg = <0x51>;
};
eeprom@52 {
- compatible = "catalyst,24c32";
+ compatible = "catalyst,24c32", "atmel,24c32";
reg = <0x52>;
pagesize = <32>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 18/21] powerpc/fsl: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree,
Florian Larysch, Michael Ellerman, Scott Wood,
Benjamin Herrenschmidt, Paul Mackerras, Rob Herring, Mark Rutland,
linuxppc-dev
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/powerpc/boot/dts/fsl/b4qds.dtsi | 8 ++++----
arch/powerpc/boot/dts/fsl/c293pcie.dts | 2 +-
arch/powerpc/boot/dts/fsl/p1010rdb.dtsi | 2 +-
arch/powerpc/boot/dts/fsl/p1023rdb.dts | 2 +-
arch/powerpc/boot/dts/fsl/p2041rdb.dts | 4 ++--
arch/powerpc/boot/dts/fsl/p3041ds.dts | 4 ++--
arch/powerpc/boot/dts/fsl/p4080ds.dts | 4 ++--
arch/powerpc/boot/dts/fsl/p5020ds.dts | 4 ++--
arch/powerpc/boot/dts/fsl/p5040ds.dts | 4 ++--
arch/powerpc/boot/dts/fsl/t208xqds.dtsi | 8 ++++----
arch/powerpc/boot/dts/fsl/t4240qds.dts | 12 ++++++------
arch/powerpc/boot/dts/fsl/t4240rdb.dts | 6 +++---
12 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/b4qds.dtsi b/arch/powerpc/boot/dts/fsl/b4qds.dtsi
index 3785ef826d07..18053d59be01 100644
--- a/arch/powerpc/boot/dts/fsl/b4qds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4qds.dtsi
@@ -166,19 +166,19 @@
reg = <0>;
eeprom@50 {
- compatible = "at24,24c64";
+ compatible = "at24,24c64", "atmel,24c64";
reg = <0x50>;
};
eeprom@51 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x51>;
};
eeprom@53 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x53>;
};
eeprom@57 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x57>;
};
rtc@68 {
diff --git a/arch/powerpc/boot/dts/fsl/c293pcie.dts b/arch/powerpc/boot/dts/fsl/c293pcie.dts
index 66709788429d..5e905e0857cf 100644
--- a/arch/powerpc/boot/dts/fsl/c293pcie.dts
+++ b/arch/powerpc/boot/dts/fsl/c293pcie.dts
@@ -153,7 +153,7 @@
&soc {
i2c@3000 {
eeprom@50 {
- compatible = "st,24c1024";
+ compatible = "st,24c1024", "atmel,24c1024";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
index a8e4ba070104..2ca9cee2ddeb 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
@@ -89,7 +89,7 @@
&board_soc {
i2c@3000 {
eeprom@50 {
- compatible = "st,24c256";
+ compatible = "st,24c256", "atmel,24c256";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/fsl/p1023rdb.dts b/arch/powerpc/boot/dts/fsl/p1023rdb.dts
index 9716ca64651c..ae38ed66a7a4 100644
--- a/arch/powerpc/boot/dts/fsl/p1023rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/p1023rdb.dts
@@ -79,7 +79,7 @@
i2c@3000 {
eeprom@53 {
- compatible = "at24,24c04";
+ compatible = "at24,24c04", "atmel,24c04";
reg = <0x53>;
};
diff --git a/arch/powerpc/boot/dts/fsl/p2041rdb.dts b/arch/powerpc/boot/dts/fsl/p2041rdb.dts
index e50fea95a853..0c34e8c46961 100644
--- a/arch/powerpc/boot/dts/fsl/p2041rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/p2041rdb.dts
@@ -127,7 +127,7 @@
reg = <0x48>;
};
eeprom@50 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x50>;
};
rtc@68 {
@@ -142,7 +142,7 @@
i2c@118100 {
eeprom@50 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x50>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/p3041ds.dts b/arch/powerpc/boot/dts/fsl/p3041ds.dts
index 40748e415adb..383656b73e61 100644
--- a/arch/powerpc/boot/dts/fsl/p3041ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p3041ds.dts
@@ -124,11 +124,11 @@
i2c@118100 {
eeprom@51 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x51>;
};
eeprom@52 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x52>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/p4080ds.dts b/arch/powerpc/boot/dts/fsl/p4080ds.dts
index 816b9788d5f6..9ca8d7cf8d48 100644
--- a/arch/powerpc/boot/dts/fsl/p4080ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p4080ds.dts
@@ -125,11 +125,11 @@
i2c@118100 {
eeprom@51 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x51>;
};
eeprom@52 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x52>;
};
rtc@68 {
diff --git a/arch/powerpc/boot/dts/fsl/p5020ds.dts b/arch/powerpc/boot/dts/fsl/p5020ds.dts
index cd6f37386111..4e6eab62f747 100644
--- a/arch/powerpc/boot/dts/fsl/p5020ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p5020ds.dts
@@ -124,11 +124,11 @@
i2c@118100 {
eeprom@51 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x51>;
};
eeprom@52 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x52>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/p5040ds.dts b/arch/powerpc/boot/dts/fsl/p5040ds.dts
index 45084738cf4e..d164e731146e 100644
--- a/arch/powerpc/boot/dts/fsl/p5040ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p5040ds.dts
@@ -133,11 +133,11 @@
i2c@118100 {
eeprom@51 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x51>;
};
eeprom@52 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x52>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
index ec080bd01b09..780103e3eaae 100644
--- a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
@@ -147,17 +147,17 @@
reg = <0x0>;
eeprom@50 {
- compatible = "at24,24c512";
+ compatible = "at24,24c512", "atmel,24c512";
reg = <0x50>;
};
eeprom@51 {
- compatible = "at24,24c02";
+ compatible = "at24,24c02", "atmel,24c02";
reg = <0x51>;
};
eeprom@57 {
- compatible = "at24,24c02";
+ compatible = "at24,24c02", "atmel,24c02";
reg = <0x57>;
};
@@ -174,7 +174,7 @@
reg = <0x1>;
eeprom@55 {
- compatible = "at24,24c02";
+ compatible = "at24,24c02", "atmel,24c02";
reg = <0x55>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/t4240qds.dts b/arch/powerpc/boot/dts/fsl/t4240qds.dts
index 9573ceada07c..9f01bcfad699 100644
--- a/arch/powerpc/boot/dts/fsl/t4240qds.dts
+++ b/arch/powerpc/boot/dts/fsl/t4240qds.dts
@@ -377,27 +377,27 @@
reg = <0>;
eeprom@51 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x51>;
};
eeprom@52 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x52>;
};
eeprom@53 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x53>;
};
eeprom@54 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x54>;
};
eeprom@55 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x55>;
};
eeprom@56 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x56>;
};
rtc@68 {
diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts
index 8166c660712a..9fb192e36bf0 100644
--- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts
@@ -130,15 +130,15 @@
reg = <0x2f>;
};
eeprom@52 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x52>;
};
eeprom@54 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x54>;
};
eeprom@56 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x56>;
};
rtc@68 {
--
2.9.3
^ permalink raw reply related
* [PATCH v3 19/21] powerpc/512x: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree,
Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Rob Herring, Mark Rutland, linuxppc-dev
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/powerpc/boot/dts/mpc5121ads.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts
index 75888ce2c792..ece5d60256ee 100644
--- a/arch/powerpc/boot/dts/mpc5121ads.dts
+++ b/arch/powerpc/boot/dts/mpc5121ads.dts
@@ -94,7 +94,7 @@
};
eeprom@50 {
- compatible = "at,24c32";
+ compatible = "at,24c32", "atmel,24c32";
reg = <0x50>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 20/21] powerpc/83xx: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree,
Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Rob Herring, Mark Rutland, linuxppc-dev
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/powerpc/boot/dts/mpc8308_p1m.dts | 2 +-
arch/powerpc/boot/dts/mpc8349emitx.dts | 2 +-
arch/powerpc/boot/dts/mpc8377_rdb.dts | 2 +-
arch/powerpc/boot/dts/mpc8377_wlan.dts | 2 +-
arch/powerpc/boot/dts/mpc8378_rdb.dts | 2 +-
arch/powerpc/boot/dts/mpc8379_rdb.dts | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8308_p1m.dts b/arch/powerpc/boot/dts/mpc8308_p1m.dts
index 57f86cdf9f36..cab933b3957a 100644
--- a/arch/powerpc/boot/dts/mpc8308_p1m.dts
+++ b/arch/powerpc/boot/dts/mpc8308_p1m.dts
@@ -123,7 +123,7 @@
interrupt-parent = <&ipic>;
dfsrr;
fram@50 {
- compatible = "ramtron,24c64";
+ compatible = "ramtron,24c64", "atmel,24c64";
reg = <0x50>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 90aed3ac2f69..00c5ef08e474 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -92,7 +92,7 @@
dfsrr;
eeprom: at24@50 {
- compatible = "st,24c256";
+ compatible = "st,24c256", "atmel,24c256";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts
index e32613963ab0..02c59d05fe16 100644
--- a/arch/powerpc/boot/dts/mpc8377_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts
@@ -150,7 +150,7 @@
};
at24@50 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts
index c0c790168b96..2bc3ed8a18c3 100644
--- a/arch/powerpc/boot/dts/mpc8377_wlan.dts
+++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts
@@ -135,7 +135,7 @@
dfsrr;
at24@50 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts
index 71842fcd621f..9e681e3d6064 100644
--- a/arch/powerpc/boot/dts/mpc8378_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts
@@ -150,7 +150,7 @@
};
at24@50 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x50>;
};
diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts
index e442a29b2fe0..3197bb78e19b 100644
--- a/arch/powerpc/boot/dts/mpc8379_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts
@@ -148,7 +148,7 @@
};
at24@50 {
- compatible = "at24,24c256";
+ compatible = "at24,24c256", "atmel,24c256";
reg = <0x50>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 21/21] powerpc/44x: Add generic compatible string for I2C EEPROM
From: Javier Martinez Canillas @ 2017-04-14 1:04 UTC (permalink / raw)
To: linux-kernel
Cc: Wolfram Sang, Javier Martinez Canillas, devicetree,
Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Rob Herring, Mark Rutland, linuxppc-dev
In-Reply-To: <20170414010445.21727-1-javier@osg.samsung.com>
The at24 driver allows to register I2C EEPROM chips using different vendor
and devices, but the I2C subsystem does not take the vendor into account
when matching using the I2C table since it only has device entries.
But when matching using an OF table, both the vendor and device has to be
taken into account so the driver defines only a set of compatible strings
using the "atmel" vendor as a generic fallback for compatible I2C devices.
So add this generic fallback to the device node compatible string to make
the device to match the driver using the OF device ID table.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/powerpc/boot/dts/warp.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
index e576ee85c42f..19e0ec83b1a5 100644
--- a/arch/powerpc/boot/dts/warp.dts
+++ b/arch/powerpc/boot/dts/warp.dts
@@ -238,7 +238,7 @@
/* This will create 52 and 53 */
at24@52 {
- compatible = "at,24c04";
+ compatible = "at,24c04", "atmel,24c04";
reg = <0x52>;
};
};
--
2.9.3
^ permalink raw reply related
* Re: [RFC 2/2] mux: mmio-based syscon mux controller
From: Steve Longerbeam @ 2017-04-14 1:09 UTC (permalink / raw)
To: Philipp Zabel, Peter Rosin
Cc: Rob Herring, Mark Rutland, Sakari Ailus, devicetree, linux-kernel,
kernel
In-Reply-To: <20170413154812.19597-2-p.zabel@pengutronix.de>
On 04/13/2017 08:48 AM, Philipp Zabel wrote:
> This adds a driver for mmio-based syscon multiplexers controlled by a
> single bitfield in a syscon register range.
>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> drivers/mux/Kconfig | 13 +++++
> drivers/mux/Makefile | 1 +
> drivers/mux/mux-syscon.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 144 insertions(+)
> create mode 100644 drivers/mux/mux-syscon.c
>
> diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
> index 86668b4d2fc52..a5e6a3b01ac24 100644
> --- a/drivers/mux/Kconfig
> +++ b/drivers/mux/Kconfig
> @@ -43,4 +43,17 @@ config MUX_GPIO
> To compile the driver as a module, choose M here: the module will
> be called mux-gpio.
>
> +config MUX_SYSCON
my preference would be CONFIG_MUX_MMIO.
> + tristate "MMIO bitfield-controlled Multiplexer"
"MMIO register bitfield-controlled Multiplexer"
The rest looks good to me.
Steve
> + depends on OF && MFD_SYSCON
> + help
> + MMIO bitfield-controlled Multiplexer controller.
> +
> + The driver builds a single multiplexer controller using a bitfield
> + in a syscon register. For N bit wide bitfields, there will be 2^N
> + possible multiplexer states.
> +
> + To compile the driver as a module, choose M here: the module will
> + be called mux-syscon.
> +
> endif
> diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
> index b00a7d37d2fbe..234309f6655f7 100644
> --- a/drivers/mux/Makefile
> +++ b/drivers/mux/Makefile
> @@ -5,3 +5,4 @@
> obj-$(CONFIG_MULTIPLEXER) += mux-core.o
> obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o
> obj-$(CONFIG_MUX_GPIO) += mux-gpio.o
> +obj-$(CONFIG_MUX_SYSCON) += mux-syscon.o
> diff --git a/drivers/mux/mux-syscon.c b/drivers/mux/mux-syscon.c
> new file mode 100644
> index 0000000000000..31cacc61f1439
> --- /dev/null
> +++ b/drivers/mux/mux-syscon.c
> @@ -0,0 +1,130 @@
> +/*
> + * syscon bitfield-controlled multiplexer driver
> + *
> + * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/mux.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/regmap.h>
> +
> +struct mux_syscon {
> + struct regmap_field *field;
> +};
> +
> +static int mux_syscon_set(struct mux_control *mux, int state)
> +{
> + struct mux_syscon *mux_syscon = mux_chip_priv(mux->chip);
> +
> + return regmap_field_write(mux_syscon->field, state);
> +}
> +
> +static const struct mux_control_ops mux_syscon_ops = {
> + .set = mux_syscon_set,
> +};
> +
> +static const struct of_device_id mux_syscon_dt_ids[] = {
> + { .compatible = "mmio-mux", },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mux_syscon_dt_ids);
> +
> +static int of_get_reg_field(struct device_node *node, struct reg_field *field)
> +{
> + u32 bit_mask;
> + int ret;
> +
> + ret = of_property_read_u32(node, "reg", &field->reg);
> + if (ret < 0)
> + return ret;
> +
> + ret = of_property_read_u32(node, "bit-mask", &bit_mask);
> + if (ret < 0)
> + return ret;
> +
> + ret = of_property_read_u32(node, "bit-shift", &field->lsb);
> + if (ret < 0)
> + return ret;
> +
> + field->msb = field->lsb + fls(bit_mask) - 1;
> +
> + return 0;
> +}
> +
> +static int mux_syscon_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct mux_chip *mux_chip;
> + struct mux_syscon *mux_syscon;
> + struct regmap *regmap;
> + struct reg_field field;
> + int bits;
> + s32 idle_state;
> + int ret;
> +
> + ret = of_get_reg_field(pdev->dev.of_node, &field);
> + if (ret) {
> + dev_err(&pdev->dev, "missing bit-field properties: %d\n", ret);
> + return ret;
> + }
> +
> + regmap = syscon_node_to_regmap(pdev->dev.of_node->parent);
> + if (IS_ERR(regmap)) {
> + ret = PTR_ERR(regmap);
> + dev_err(&pdev->dev, "failed to get syscon regmap: %d\n", ret);
> + return ret;
> + }
> +
> + mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_syscon));
> + if (!mux_chip)
> + return -ENOMEM;
> +
> + mux_syscon = mux_chip_priv(mux_chip);
> + mux_chip->ops = &mux_syscon_ops;
> +
> + mux_syscon->field = devm_regmap_field_alloc(&pdev->dev, regmap, field);
> + if (IS_ERR(mux_syscon->field)) {
> + ret = PTR_ERR(mux_syscon->field);
> + dev_err(&pdev->dev, "failed to regmap bit-field: %d\n", ret);
> + return ret;
> + }
> + bits = 1 + field.msb - field.lsb;
> +
> + mux_chip->mux->states = 1 << bits;
> +
> + ret = device_property_read_u32(dev, "idle-state", (u32 *)&idle_state);
> + if (ret >= 0 && idle_state != MUX_IDLE_AS_IS) {
> + if (idle_state < 0 || idle_state >= mux_chip->mux->states) {
> + dev_err(dev, "invalid idle-state %u\n", idle_state);
> + return -EINVAL;
> + }
> +
> + mux_chip->mux->idle_state = idle_state;
> + }
> +
> + regmap_field_read(mux_syscon->field, &mux_chip->mux->cached_state);
> +
> + return devm_mux_chip_register(dev, mux_chip);
> +}
> +
> +static struct platform_driver mux_syscon_driver = {
> + .driver = {
> + .name = "mmio-mux",
> + .of_match_table = of_match_ptr(mux_syscon_dt_ids),
> + },
> + .probe = mux_syscon_probe,
> +};
> +module_platform_driver(mux_syscon_driver);
> +
> +MODULE_DESCRIPTION("MMIO bitfield-controlled multiplexer driver");
> +MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
> +MODULE_LICENSE("GPL v2");
^ permalink raw reply
* [PATCH v2 0/15] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator
From: Yasunari.Takiguchi @ 2017-04-14 1:50 UTC (permalink / raw)
To: akpm, linux-kernel, devicetree, linux-media
Cc: tbird20d, frowand.list, Yasunari Takiguchi
From: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com>
Hi,
This is the patch series (version 2) of Sony CXD2880 DVB-T2/T tuner + demodulator driver.
The driver supports DVB-API and interfaces through SPI.
We have tested the driver on Raspberry Pi 3 and got picture and sound from a media player.
Thanks,
Takiguchi
---
Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt | 14 ++++++++++++++
drivers/media/spi/cxd2880-spi.c | 728 ++++++++++++++++++++++++++++++++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880.h | 46 +
drivers/media/dvb-frontends/cxd2880/cxd2880_common.c | 84 +
drivers/media/dvb-frontends/cxd2880/cxd2880_common.h | 86 +
drivers/media/dvb-frontends/cxd2880/cxd2880_io.c | 68 +
drivers/media/dvb-frontends/cxd2880/cxd2880_io.h | 62 +
drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h | 35 +
drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c | 71 +
drivers/media/dvb-frontends/cxd2880/cxd2880_math.c | 89 +
drivers/media/dvb-frontends/cxd2880/cxd2880_math.h | 40 +
drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c | 147 +
drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h | 40 +
drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h | 51 +
drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c | 130 +
drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h | 45 +
drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h | 50 +
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c | 3925 ++++++++++++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h | 395 ++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h | 29 +
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c | 207 ++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h | 52 +
drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c | 99 +
drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h | 44 +
drivers/media/dvb-frontends/cxd2880/cxd2880_top.c | 1550 ++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h | 91 +
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c | 1072 +++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h | 62 +
drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c | 197 ++
drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.h | 58 +
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c | 1190 +++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h | 106 +
drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h | 402 ++++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c | 1309 ++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h | 82 +
drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c | 311 +++
drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.h | 64 +
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c | 2523 ++++++++++++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h | 170 ++
drivers/media/dvb-frontends/Makefile | 1 +
drivers/media/dvb-frontends/cxd2880/Makefile | 21 +++++++++++++++++++++
drivers/media/spi/Makefile | 5 +++++
drivers/media/dvb-frontends/Kconfig | 2 ++
drivers/media/dvb-frontends/cxd2880/Kconfig | 6 ++++++
drivers/media/spi/Kconfig | 14 ++++++++++++++
MAINTAINERS | 9 +++++++++
46 files changed, 15782 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
create mode 100644 drivers/media/spi/cxd2880-spi.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_top.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/Makefile
create mode 100644 drivers/media/dvb-frontends/cxd2880/Kconfig
--
2.11.0
^ permalink raw reply
* [PATCH v2 01/15] [dt-bindings] [media] Add document file for CXD2880 SPI I/F
From: Yasunari.Takiguchi-7U/KSKJipcs @ 2017-04-14 2:00 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: tbird20d-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w, Yasunari Takiguchi,
Masayuki Yamamoto, Hideki Nozawa, Kota Yonezawa,
Toshihiko Matsumoto, Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
From: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
This is the document file for Sony CXD2880 DVB-T2/T tuner + demodulator.
It contains the description of the SPI adapter binding.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe-7U/KSKJipcs@public.gmane.org>
---
.../devicetree/bindings/media/spi/sony-cxd2880.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
diff --git a/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt b/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
new file mode 100644
index 000000000000..fc5aa263abe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
@@ -0,0 +1,14 @@
+Sony CXD2880 DVB-T2/T tuner + demodulator driver SPI adapter
+
+Required properties:
+- compatible: Should be "sony,cxd2880".
+- reg: SPI chip select number for the device.
+- spi-max-frequency: Maximum bus speed, should be set to <55000000> (55MHz).
+
+Example:
+
+cxd2880@0 {
+ compatible = "sony,cxd2880";
+ reg = <0>; /* CE0 */
+ spi-max-frequency = <55000000>; /* 55MHz */
+};
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 02/15] [media] cxd2880-spi: Add support for CXD2008 SPI interface
From: Yasunari.Takiguchi-7U/KSKJipcs @ 2017-04-14 2:08 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: tbird20d-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w, Yasunari Takiguchi,
Masayuki Yamamoto, Hideki Nozawa, Kota Yonezawa,
Toshihiko Matsumoto, Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
From: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
This is the SPI adapter part of the driver for the
Sony CXD2880 DVB-T2/T tuner + demodulator.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe-7U/KSKJipcs@public.gmane.org>
---
drivers/media/spi/cxd2880-spi.c | 728 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 728 insertions(+)
create mode 100644 drivers/media/spi/cxd2880-spi.c
diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c
new file mode 100644
index 000000000000..82e122349055
--- /dev/null
+++ b/drivers/media/spi/cxd2880-spi.c
@@ -0,0 +1,728 @@
+/*
+ * cxd2880-spi.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * SPI adapter
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/spi/spi.h>
+
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_frontend.h"
+#include "cxd2880.h"
+
+#define CXD2880_MAX_FILTER_SIZE 32
+#define BURST_WRITE_MAX 128
+#define MAX_TRANS_PACKET 300
+
+struct cxd2880_ts_buf_info {
+ u8 read_ready;
+ u8 almost_full;
+ u8 almost_empty;
+ u8 overflow;
+ u8 underflow;
+ u16 packet_num;
+};
+
+struct cxd2880_pid_config {
+ u8 is_enable;
+ u16 pid;
+};
+
+struct cxd2880_pid_filter_config {
+ u8 is_negative;
+ struct cxd2880_pid_config pid_config[CXD2880_MAX_FILTER_SIZE];
+};
+
+struct cxd2880_dvb_spi {
+ struct dvb_frontend dvb_fe;
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dmx_frontend dmx_fe;
+ struct task_struct *cxd2880_ts_read_thread;
+ struct spi_device *spi;
+ struct mutex spi_mutex; /* For SPI access exclusive control */
+ int feed_count;
+ int all_pid_feed_count;
+ u8 *ts_buf;
+ struct cxd2880_pid_filter_config filter_config;
+};
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int cxd2880_write_spi(struct spi_device *spi, u8 *data, u32 size)
+{
+ struct spi_message msg;
+ struct spi_transfer tx;
+ int ret = 0;
+
+ if ((!spi) || (!data)) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ memset(&tx, 0, sizeof(tx));
+ tx.tx_buf = data;
+ tx.len = size;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&tx, &msg);
+ ret = spi_sync(spi, &msg);
+
+ return ret;
+}
+
+static int cxd2880_write_reg(struct spi_device *spi,
+ u8 subAddress, const u8 *data, u32 size)
+{
+ u8 send_data[BURST_WRITE_MAX + 4];
+ const u8 *write_data_top = NULL;
+ int ret = 0;
+
+ if ((!spi) || (!data)) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+ if (size > BURST_WRITE_MAX) {
+ pr_err("%s: data size > WRITE_MAX\n", __func__);
+ return -EINVAL;
+ }
+
+ if (subAddress + size > 0x100) {
+ pr_err("%s: out of range\n", __func__);
+ return -EINVAL;
+ }
+
+ send_data[0] = 0x0E;
+ write_data_top = data;
+
+ while (size > 0) {
+ send_data[1] = subAddress;
+ if (size > 255)
+ send_data[2] = 255;
+ else
+ send_data[2] = (u8)size;
+
+ memcpy(&send_data[3], write_data_top, send_data[2]);
+
+ ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3);
+ if (ret) {
+ dev_err(&spi->dev, "%s: write spi failed %d\n",
+ __func__, ret);
+ break;
+ }
+ subAddress += send_data[2];
+ write_data_top += send_data[2];
+ size -= send_data[2];
+ }
+
+ return ret;
+}
+
+static int cxd2880_spi_read_ts(struct spi_device *spi,
+ u8 *read_data,
+ u32 packet_num)
+{
+ int ret = 0;
+ u8 data[3];
+ struct spi_message message;
+ struct spi_transfer transfer[2];
+
+ if ((!spi) || (!read_data) || (!packet_num)) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+ if (packet_num > 0xFFFF) {
+ dev_err(&spi->dev, "%s: packet num > 0xFFFF\n", __func__);
+ return -EINVAL;
+ }
+
+ data[0] = 0x10;
+ data[1] = (u8)((packet_num >> 8) & 0xFF);
+ data[2] = (u8)(packet_num & 0xFF);
+
+ spi_message_init(&message);
+ memset(transfer, 0, sizeof(transfer));
+
+ transfer[0].len = 3;
+ transfer[0].tx_buf = data;
+ spi_message_add_tail(&transfer[0], &message);
+ transfer[1].len = packet_num * 188;
+ transfer[1].rx_buf = read_data;
+ spi_message_add_tail(&transfer[1], &message);
+
+ ret = spi_sync(spi, &message);
+ if (ret)
+ dev_err(&spi->dev, "%s: spi_write_then_read failed\n",
+ __func__);
+
+ return ret;
+}
+
+static int cxd2880_spi_read_ts_buffer_info(struct spi_device *spi,
+ struct cxd2880_ts_buf_info *info)
+{
+ u8 send_data = 0x20;
+ u8 recv_data[2];
+ int ret = 0;
+
+ if ((!spi) || (!info)) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = spi_write_then_read(spi, &send_data, 1,
+ recv_data, sizeof(recv_data));
+ if (ret)
+ dev_err(&spi->dev,
+ "%s: spi_write_then_read failed\n", __func__);
+
+ info->read_ready = (u8)((recv_data[0] & 0x80) ? 1 : 0);
+ info->almost_full = (u8)((recv_data[0] & 0x40) ? 1 : 0);
+ info->almost_empty = (u8)((recv_data[0] & 0x20) ? 1 : 0);
+ info->overflow = (u8)((recv_data[0] & 0x10) ? 1 : 0);
+ info->underflow = (u8)((recv_data[0] & 0x08) ? 1 : 0);
+ info->packet_num = (u16)(((recv_data[0] & 0x07) << 8) | recv_data[1]);
+
+ return ret;
+}
+
+static int cxd2880_spi_clear_ts_buffer(struct spi_device *spi)
+{
+ u8 data = 0x03;
+ int ret = 0;
+
+ ret = cxd2880_write_spi(spi, &data, 1);
+
+ if (ret)
+ pr_err("%s: write spi failed\n", __func__);
+
+ return ret;
+}
+
+static int cxd2880_set_pid_filter(struct spi_device *spi,
+ struct cxd2880_pid_filter_config *cfg)
+{
+ u8 data[65];
+
+ if (!spi) {
+ pr_err("%s: ivnalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ data[0] = 0x00;
+ if (cxd2880_write_reg(spi, 0x00, &data[0], 1) != 0)
+ return -EIO;
+ if (!cfg) {
+ data[0] = 0x02;
+ if (cxd2880_write_reg(spi, 0x50, &data[0], 1) != 0)
+ return -EIO;
+ } else {
+ data[0] = (u8)(cfg->is_negative ? 0x01 : 0x00);
+ {
+ int i = 0;
+ u16 pid = 0;
+
+ for (i = 0; i < CXD2880_MAX_FILTER_SIZE; i++) {
+ pid = cfg->pid_config[i].pid;
+ if (cfg->pid_config[i].is_enable) {
+ data[1 + (i * 2)] =
+ (u8)((u8)(pid >> 8) | 0x20);
+ data[2 + (i * 2)] =
+ (u8)(pid & 0xFF);
+ } else {
+ data[1 + (i * 2)] = 0x00;
+ data[2 + (i * 2)] = 0x00;
+ }
+ }
+ }
+ if (cxd2880_write_reg(spi, 0x50, data, 65) != 0)
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int cxd2880_update_pid_filter(struct cxd2880_dvb_spi *dvb_spi,
+ struct cxd2880_pid_filter_config *cfg,
+ bool is_all_pid_filter)
+{
+ int ret = 0;
+
+ if ((!dvb_spi) || (!cfg)) {
+ pr_err("%s: invalid arg.\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dvb_spi->spi_mutex);
+ if (is_all_pid_filter) {
+ struct cxd2880_pid_filter_config tmpcfg;
+
+ memset(&tmpcfg, 0, sizeof(tmpcfg));
+ tmpcfg.is_negative = 1;
+ tmpcfg.pid_config[0].is_enable = 1;
+ tmpcfg.pid_config[0].pid = 0x1FFF;
+
+ ret = cxd2880_set_pid_filter(dvb_spi->spi, &tmpcfg);
+ } else {
+ ret = cxd2880_set_pid_filter(dvb_spi->spi, cfg);
+ }
+ mutex_unlock(&dvb_spi->spi_mutex);
+
+ if (ret) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: set_pid_filter failed\n", __func__);
+ }
+
+ return ret;
+}
+
+static int cxd2880_ts_read(void *arg)
+{
+ struct cxd2880_dvb_spi *dvb_spi = NULL;
+ struct cxd2880_ts_buf_info info;
+ struct timespec ts;
+ long elapsed = 0;
+ long starttime = 0;
+ u32 i;
+ int ret;
+
+ dvb_spi = (struct cxd2880_dvb_spi *)arg;
+ if (!dvb_spi) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = cxd2880_spi_clear_ts_buffer(dvb_spi->spi);
+ if (ret) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: set_clear_ts_buffer failed\n", __func__);
+ return ret;
+ }
+
+ getnstimeofday(&ts);
+ starttime = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
+ while (!kthread_should_stop()) {
+ getnstimeofday(&ts);
+ elapsed =
+ ((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000))
+ - starttime;
+ ret = cxd2880_spi_read_ts_buffer_info(dvb_spi->spi,
+ &info);
+ if (ret) {
+ pr_err("%s: spi_read_ts_buffer_info error\n",
+ __func__);
+ return ret;
+ }
+
+ if (info.packet_num > MAX_TRANS_PACKET) {
+ for (i = 0; i < info.packet_num / MAX_TRANS_PACKET;
+ i++) {
+ cxd2880_spi_read_ts(dvb_spi->spi,
+ dvb_spi->ts_buf,
+ MAX_TRANS_PACKET);
+ dvb_dmx_swfilter(&dvb_spi->demux,
+ dvb_spi->ts_buf,
+ MAX_TRANS_PACKET * 188);
+ }
+ starttime = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
+ } else if ((info.packet_num > 0) && (elapsed >= 500)) {
+ cxd2880_spi_read_ts(dvb_spi->spi,
+ dvb_spi->ts_buf,
+ info.packet_num);
+ dvb_dmx_swfilter(&dvb_spi->demux,
+ dvb_spi->ts_buf,
+ info.packet_num * 188);
+ starttime = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
+ } else {
+ usleep_range(10000, 11000);
+ }
+ }
+
+ return 0;
+}
+
+static int cxd2880_start_feed(struct dvb_demux_feed *feed)
+{
+ int ret = 0;
+ int i = 0;
+ struct dvb_demux *demux = NULL;
+ struct cxd2880_dvb_spi *dvb_spi = NULL;
+
+ if (!feed) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ demux = feed->demux;
+ if (!demux) {
+ pr_err("%s: feed->demux is NULL\n", __func__);
+ return -EINVAL;
+ }
+ dvb_spi = (struct cxd2880_dvb_spi *)demux->priv;
+
+ if (dvb_spi->feed_count == CXD2880_MAX_FILTER_SIZE) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: Exceeded maximum PID count (32).", __func__);
+ dev_err(&dvb_spi->spi->dev,
+ "Selected PID cannot be enabled.\n");
+ return -EBUSY;
+ }
+
+ if (feed->pid == 0x2000) {
+ if (dvb_spi->all_pid_feed_count == 0) {
+ ret = cxd2880_update_pid_filter(dvb_spi,
+ &dvb_spi->filter_config,
+ true);
+ if (ret) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: update pid filter failed\n",
+ __func__);
+ return ret;
+ }
+ }
+ dvb_spi->all_pid_feed_count++;
+
+ dev_dbg(&dvb_spi->spi->dev,
+ "%s: all PID feed (count = %d)\n",
+ __func__, dvb_spi->all_pid_feed_count);
+ } else {
+ struct cxd2880_pid_filter_config cfgtmp;
+
+ cfgtmp = dvb_spi->filter_config;
+
+ for (i = 0; i < CXD2880_MAX_FILTER_SIZE; i++) {
+ if (cfgtmp.pid_config[i].is_enable == 0) {
+ cfgtmp.pid_config[i].is_enable = 1;
+ cfgtmp.pid_config[i].pid = feed->pid;
+ dev_dbg(&dvb_spi->spi->dev,
+ "%s: store PID %d to #%d\n",
+ __func__, feed->pid, i);
+ break;
+ }
+ }
+ if (i == CXD2880_MAX_FILTER_SIZE) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: PID filter is full. Assumed bug.\n",
+ __func__);
+ return -EBUSY;
+ }
+ if (!dvb_spi->all_pid_feed_count)
+ ret = cxd2880_update_pid_filter(dvb_spi,
+ &cfgtmp,
+ false);
+ if (ret)
+ return ret;
+
+ dvb_spi->filter_config = cfgtmp;
+ }
+
+ if (dvb_spi->feed_count == 0) {
+ dvb_spi->ts_buf =
+ kmalloc(sizeof(u8) * MAX_TRANS_PACKET * 188,
+ GFP_KERNEL | GFP_DMA);
+ if (!dvb_spi->ts_buf) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: ts buffer allocate failed\n", __func__);
+ memset(&dvb_spi->filter_config, 0,
+ sizeof(dvb_spi->filter_config));
+ dvb_spi->all_pid_feed_count = 0;
+ return -ENOMEM;
+ }
+ dvb_spi->cxd2880_ts_read_thread = kthread_run(cxd2880_ts_read,
+ dvb_spi,
+ "cxd2880_ts_read");
+ if (IS_ERR(dvb_spi->cxd2880_ts_read_thread)) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: kthread_run failed/\n",
+ __func__);
+ kfree(dvb_spi->ts_buf);
+ dvb_spi->ts_buf = NULL;
+ memset(&dvb_spi->filter_config, 0,
+ sizeof(dvb_spi->filter_config));
+ dvb_spi->all_pid_feed_count = 0;
+ return PTR_ERR(dvb_spi->cxd2880_ts_read_thread);
+ }
+ }
+
+ dvb_spi->feed_count++;
+
+ dev_dbg(&dvb_spi->spi->dev, "%s: start feed (count %d)\n",
+ __func__, dvb_spi->feed_count);
+ return 0;
+}
+
+static int cxd2880_stop_feed(struct dvb_demux_feed *feed)
+{
+ int i = 0;
+ int ret = 0;
+ struct dvb_demux *demux = NULL;
+ struct cxd2880_dvb_spi *dvb_spi = NULL;
+
+ if (!feed) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ demux = feed->demux;
+ if (!demux) {
+ pr_err("%s: feed->demux is NULL\n", __func__);
+ return -EINVAL;
+ }
+ dvb_spi = (struct cxd2880_dvb_spi *)demux->priv;
+
+ if (!dvb_spi->feed_count) {
+ dev_warn(&dvb_spi->spi->dev,
+ "%s: no feed is started\n", __func__);
+ return -EINVAL;
+ }
+
+ if (feed->pid == 0x2000) {
+ /*
+ * Special PID case.
+ * Number of 0x2000 feed request was stored
+ * in dvb_spi->all_pid_feed_count.
+ */
+ if (dvb_spi->all_pid_feed_count <= 0) {
+ dev_warn(&dvb_spi->spi->dev,
+ "%s: PID %d not found.\n",
+ __func__, feed->pid);
+ return -EINVAL;
+ }
+ dvb_spi->all_pid_feed_count--;
+ } else {
+ struct cxd2880_pid_filter_config cfgtmp;
+
+ cfgtmp = dvb_spi->filter_config;
+
+ for (i = 0; i < CXD2880_MAX_FILTER_SIZE; i++) {
+ if (feed->pid == cfgtmp.pid_config[i].pid &&
+ cfgtmp.pid_config[i].is_enable != 0) {
+ cfgtmp.pid_config[i].is_enable = 0;
+ cfgtmp.pid_config[i].pid = 0;
+ dev_dbg(&dvb_spi->spi->dev,
+ "%s: removed PID %d from #%d\n",
+ __func__, feed->pid, i);
+ break;
+ }
+ }
+ dvb_spi->filter_config = cfgtmp;
+
+ if (i == CXD2880_MAX_FILTER_SIZE) {
+ dev_warn(&dvb_spi->spi->dev, "%s: PID %d not found\n",
+ __func__, feed->pid);
+ return -EINVAL;
+ }
+ }
+
+ ret = cxd2880_update_pid_filter(dvb_spi,
+ &dvb_spi->filter_config,
+ dvb_spi->all_pid_feed_count > 0);
+ dvb_spi->feed_count--;
+
+ if (dvb_spi->feed_count == 0) {
+ int ret_stop = 0;
+
+ ret_stop = kthread_stop(dvb_spi->cxd2880_ts_read_thread);
+ if (ret_stop) {
+ dev_err(&dvb_spi->spi->dev,
+ "%s: cxd2880_ts_read thread didn't terminate normally\n",
+ __func__);
+ ret = ret_stop;
+ }
+ kfree(dvb_spi->ts_buf);
+ dvb_spi->ts_buf = NULL;
+ }
+
+ dev_dbg(&dvb_spi->spi->dev, "%s: stop feed ok.(count %d)\n",
+ __func__, dvb_spi->feed_count);
+
+ return ret;
+}
+
+static const struct of_device_id cxd2880_spi_of_match[] = {
+ { .compatible = "sony,cxd2880" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, cxd2880_spi_of_match);
+
+static int
+cxd2880_spi_probe(struct spi_device *spi)
+{
+ int ret = 0;
+ struct cxd2880_dvb_spi *dvb_spi = NULL;
+ struct cxd2880_config config;
+
+ if (!spi) {
+ pr_err("%s: invalid arg.\n", __func__);
+ return -EINVAL;
+ }
+
+ dvb_spi = kzalloc(sizeof(struct cxd2880_dvb_spi), GFP_KERNEL);
+ if (!dvb_spi)
+ return -ENOMEM;
+
+ dvb_spi->spi = spi;
+ mutex_init(&dvb_spi->spi_mutex);
+ dev_set_drvdata(&spi->dev, dvb_spi);
+ config.spi = spi;
+ config.spi_mutex = &dvb_spi->spi_mutex;
+
+ ret = dvb_register_adapter(&dvb_spi->adapter,
+ "CXD2880",
+ THIS_MODULE,
+ &spi->dev,
+ adapter_nr);
+ if (ret < 0) {
+ dev_err(&spi->dev, "%s: dvb_register_adapter() failed\n",
+ __func__);
+ goto fail_adapter;
+ }
+
+ if (!dvb_attach(cxd2880_attach, &dvb_spi->dvb_fe, &config)) {
+ dev_err(&spi->dev, "%s: cxd2880_attach failed\n", __func__);
+ goto fail_attach;
+ }
+
+ ret = dvb_register_frontend(&dvb_spi->adapter,
+ &dvb_spi->dvb_fe);
+ if (ret < 0) {
+ dev_err(&spi->dev, "%s: dvb_register_frontend() failed\n",
+ __func__);
+ goto fail_frontend;
+ }
+
+ dvb_spi->demux.dmx.capabilities = DMX_TS_FILTERING;
+ dvb_spi->demux.priv = dvb_spi;
+ dvb_spi->demux.filternum = CXD2880_MAX_FILTER_SIZE;
+ dvb_spi->demux.feednum = CXD2880_MAX_FILTER_SIZE;
+ dvb_spi->demux.start_feed = cxd2880_start_feed;
+ dvb_spi->demux.stop_feed = cxd2880_stop_feed;
+
+ ret = dvb_dmx_init(&dvb_spi->demux);
+ if (ret < 0) {
+ dev_err(&spi->dev, "%s: dvb_dmx_init() failed\n", __func__);
+ goto fail_dmx;
+ }
+
+ dvb_spi->dmxdev.filternum = CXD2880_MAX_FILTER_SIZE;
+ dvb_spi->dmxdev.demux = &dvb_spi->demux.dmx;
+ dvb_spi->dmxdev.capabilities = 0;
+ ret = dvb_dmxdev_init(&dvb_spi->dmxdev,
+ &dvb_spi->adapter);
+ if (ret < 0) {
+ dev_err(&spi->dev, "%s: dvb_dmxdev_init() failed\n", __func__);
+ goto fail_dmxdev;
+ }
+
+ dvb_spi->dmx_fe.source = DMX_FRONTEND_0;
+ ret = dvb_spi->demux.dmx.add_frontend(&dvb_spi->demux.dmx,
+ &dvb_spi->dmx_fe);
+ if (ret < 0) {
+ dev_err(&spi->dev, "%s: add_frontend() failed\n", __func__);
+ goto fail_dmx_fe;
+ }
+
+ ret = dvb_spi->demux.dmx.connect_frontend(&dvb_spi->demux.dmx,
+ &dvb_spi->dmx_fe);
+ if (ret < 0) {
+ dev_err(&spi->dev, "%s: dvb_register_frontend() failed\n",
+ __func__);
+ goto fail_fe_conn;
+ }
+
+ dev_info(&spi->dev, "Sony CXD2880 has successfully attached.\n");
+
+ return 0;
+
+fail_fe_conn:
+ dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx,
+ &dvb_spi->dmx_fe);
+fail_dmx_fe:
+ dvb_dmxdev_release(&dvb_spi->dmxdev);
+fail_dmxdev:
+ dvb_dmx_release(&dvb_spi->demux);
+fail_dmx:
+ dvb_unregister_frontend(&dvb_spi->dvb_fe);
+fail_frontend:
+ dvb_frontend_detach(&dvb_spi->dvb_fe);
+fail_attach:
+ dvb_unregister_adapter(&dvb_spi->adapter);
+fail_adapter:
+ kfree(dvb_spi);
+ return ret;
+}
+
+static int
+cxd2880_spi_remove(struct spi_device *spi)
+{
+ struct cxd2880_dvb_spi *dvb_spi;
+
+ if (!spi) {
+ pr_err("%s: invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
+ dvb_spi = (struct cxd2880_dvb_spi *)dev_get_drvdata(&spi->dev);
+
+ if (!dvb_spi) {
+ pr_err("%s: failed\n", __func__);
+ return -EINVAL;
+ }
+ dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx,
+ &dvb_spi->dmx_fe);
+ dvb_dmxdev_release(&dvb_spi->dmxdev);
+ dvb_dmx_release(&dvb_spi->demux);
+ dvb_unregister_frontend(&dvb_spi->dvb_fe);
+ dvb_frontend_detach(&dvb_spi->dvb_fe);
+ dvb_unregister_adapter(&dvb_spi->adapter);
+
+ kfree(dvb_spi);
+ dev_info(&spi->dev, "%s: cxd2880_spi remove ok.\n", __func__);
+
+ return 0;
+}
+
+static const struct spi_device_id cxd2880_spi_id[] = {
+ { "cxd2880", 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(spi, cxd2880_spi_id);
+
+static struct spi_driver cxd2880_spi_driver = {
+ .driver = {
+ .name = "cxd2880",
+ .of_match_table = cxd2880_spi_of_match,
+ },
+ .id_table = cxd2880_spi_id,
+ .probe = cxd2880_spi_probe,
+ .remove = cxd2880_spi_remove,
+};
+module_spi_driver(cxd2880_spi_driver);
+
+MODULE_DESCRIPTION(
+"Sony CXD2880 DVB-T2/T tuner + demodulator drvier SPI adapter");
+MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
+MODULE_LICENSE("GPL v2");
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 03/15] [media] cxd2880: Add common files for the driver
From: Yasunari.Takiguchi-7U/KSKJipcs @ 2017-04-14 2:17 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: tbird20d-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w, Yasunari Takiguchi,
Masayuki Yamamoto, Hideki Nozawa, Kota Yonezawa,
Toshihiko Matsumoto, Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
From: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
These are common files for the driver for the
Sony CXD2880 DVB-T2/T tuner + demodulator.
These contains helper functions for the driver.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe-7U/KSKJipcs@public.gmane.org>
---
drivers/media/dvb-frontends/cxd2880/cxd2880.h | 46 ++++++++++++
.../media/dvb-frontends/cxd2880/cxd2880_common.c | 84 +++++++++++++++++++++
.../media/dvb-frontends/cxd2880/cxd2880_common.h | 86 ++++++++++++++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_io.c | 68 +++++++++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_io.h | 62 ++++++++++++++++
.../media/dvb-frontends/cxd2880/cxd2880_stdlib.h | 35 +++++++++
.../dvb-frontends/cxd2880/cxd2880_stopwatch_port.c | 71 ++++++++++++++++++
7 files changed, 452 insertions(+)
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880.h b/drivers/media/dvb-frontends/cxd2880/cxd2880.h
new file mode 100644
index 000000000000..281f9a784eb5
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880.h
@@ -0,0 +1,46 @@
+/*
+ * cxd2880.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver public definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_H
+#define CXD2880_H
+
+struct cxd2880_config {
+ struct spi_device *spi;
+ struct mutex *spi_mutex; /* For SPI access exclusive control */
+};
+
+#if IS_REACHABLE(CONFIG_DVB_CXD2880)
+extern struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe,
+ struct cxd2880_config *cfg);
+#else
+static inline struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe,
+ struct cxd2880_config *cfg)
+{
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_CXD2880 */
+
+#endif /* CXD2880_H */
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
new file mode 100644
index 000000000000..850f3a76b2c7
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
@@ -0,0 +1,84 @@
+/*
+ * cxd2880_common.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_common.h"
+
+#define MASKUPPER(n) (((n) == 0) ? 0 : (0xFFFFFFFFU << (32 - (n))))
+#define MASKLOWER(n) (((n) == 0) ? 0 : (0xFFFFFFFFU >> (32 - (n))))
+
+int cxd2880_convert2s_complement(u32 value, u32 bitlen)
+{
+ if ((bitlen == 0) || (bitlen >= 32))
+ return (int)value;
+
+ if (value & (u32)(1 << (bitlen - 1)))
+ return (int)(MASKUPPER(32 - bitlen) | value);
+ else
+ return (int)(MASKLOWER(bitlen) & value);
+}
+
+u32 cxd2880_bit_split_from_byte_array(u8 *array, u32 start_bit, u32 bit_num)
+{
+ u32 value = 0;
+ u8 *array_read;
+ u8 bit_read;
+ u32 len_remain;
+
+ if (!array)
+ return 0;
+ if ((bit_num == 0) || (bit_num > 32))
+ return 0;
+
+ array_read = array + (start_bit / 8);
+ bit_read = (u8)(start_bit % 8);
+ len_remain = bit_num;
+
+ if (bit_read != 0) {
+ if (((int)len_remain) <= 8 - bit_read) {
+ value = (*array_read) >> ((8 - bit_read) - len_remain);
+ len_remain = 0;
+ } else {
+ value = *array_read++;
+ len_remain -= 8 - bit_read;
+ }
+ }
+
+ while (len_remain > 0) {
+ if (len_remain < 8) {
+ value <<= len_remain;
+ value |= (*array_read++ >> (8 - len_remain));
+ len_remain = 0;
+ } else {
+ value <<= 8;
+ value |= (u32)(*array_read++);
+ len_remain -= 8;
+ }
+ }
+
+ value &= MASKLOWER(bit_num);
+
+ return value;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_common.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.h
new file mode 100644
index 000000000000..b1ecb44bca10
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.h
@@ -0,0 +1,86 @@
+/*
+ * cxd2880_common.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver common definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_COMMON_H
+#define CXD2880_COMMON_H
+
+#include <linux/types.h>
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#include <linux/delay.h>
+#define CXD2880_SLEEP(n) msleep(n)
+#ifndef CXD2880_SLEEP_IN_MON
+#define CXD2880_SLEEP_IN_MON(n, obj) CXD2880_SLEEP(n)
+#endif
+
+#define CXD2880_ARG_UNUSED(arg) ((void)(arg))
+
+enum cxd2880_ret {
+ CXD2880_RESULT_OK,
+ CXD2880_RESULT_ERROR_ARG,
+ CXD2880_RESULT_ERROR_IO,
+ CXD2880_RESULT_ERROR_SW_STATE,
+ CXD2880_RESULT_ERROR_HW_STATE,
+ CXD2880_RESULT_ERROR_TIMEOUT,
+ CXD2880_RESULT_ERROR_UNLOCK,
+ CXD2880_RESULT_ERROR_RANGE,
+ CXD2880_RESULT_ERROR_NOSUPPORT,
+ CXD2880_RESULT_ERROR_CANCEL,
+ CXD2880_RESULT_ERROR_OTHER,
+ CXD2880_RESULT_ERROR_OVERFLOW,
+ CXD2880_RESULT_OK_CONFIRM
+};
+
+int cxd2880_convert2s_complement(u32 value, u32 bitlen);
+
+u32 cxd2880_bit_split_from_byte_array(u8 *array, u32 start_bit, u32 bit_num);
+
+struct cxd2880_atomic {
+ int counter;
+};
+
+#define cxd2880_atomic_set(a, i) ((a)->counter = i)
+#define cxd2880_atomic_read(a) ((a)->counter)
+
+struct cxd2880_stopwatch {
+ u32 start_time;
+};
+
+enum cxd2880_ret cxd2880_stopwatch_start(struct cxd2880_stopwatch *stopwatch);
+
+enum cxd2880_ret cxd2880_stopwatch_sleep(struct cxd2880_stopwatch *stopwatch,
+ u32 ms);
+
+enum cxd2880_ret cxd2880_stopwatch_elapsed(struct cxd2880_stopwatch *stopwatch,
+ u32 *elapsed);
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_io.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.c
new file mode 100644
index 000000000000..f0f82055a953
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.c
@@ -0,0 +1,68 @@
+/*
+ * cxd2880_io.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * register I/O interface functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_io.h"
+
+enum cxd2880_ret cxd2880_io_common_write_one_reg(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt,
+ u8 sub_address, u8 data)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!io)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret = io->write_regs(io, tgt, sub_address, &data, 1);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_io_set_reg_bits(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt,
+ u8 sub_address, u8 data, u8 mask)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!io)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (mask == 0x00)
+ return CXD2880_RESULT_OK;
+
+ if (mask != 0xFF) {
+ u8 rdata = 0x00;
+
+ ret = io->read_regs(io, tgt, sub_address, &rdata, 1);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ data = (u8)((data & mask) | (rdata & (mask ^ 0xFF)));
+ }
+
+ ret = io->write_reg(io, tgt, sub_address, data);
+
+ return ret;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_io.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.h
new file mode 100644
index 000000000000..4d6db13cf910
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.h
@@ -0,0 +1,62 @@
+/*
+ * cxd2880_io.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * register I/O interface definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_IO_H
+#define CXD2880_IO_H
+
+#include "cxd2880_common.h"
+
+enum cxd2880_io_tgt {
+ CXD2880_IO_TGT_SYS,
+ CXD2880_IO_TGT_DMD
+};
+
+struct cxd2880_io {
+ enum cxd2880_ret (*read_regs)(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt, u8 sub_address,
+ u8 *data, u32 size);
+ enum cxd2880_ret (*write_regs)(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt, u8 sub_address,
+ const u8 *data, u32 size);
+ enum cxd2880_ret (*write_reg)(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt, u8 sub_address,
+ u8 data);
+ void *if_object;
+ u8 i2c_address_sys;
+ u8 i2c_address_demod;
+ u8 slave_select;
+ void *user;
+};
+
+enum cxd2880_ret cxd2880_io_common_write_one_reg(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt,
+ u8 sub_address, u8 data);
+
+enum cxd2880_ret cxd2880_io_set_reg_bits(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt,
+ u8 sub_address, u8 data, u8 mask);
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h
new file mode 100644
index 000000000000..b9ca1b9df110
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h
@@ -0,0 +1,35 @@
+/*
+ * cxd2880_stdlib.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * standard lib function aliases
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_STDLIB_H
+#define CXD2880_STDLIB_H
+
+#include <linux/string.h>
+
+#define cxd2880_memcpy memcpy
+#define cxd2880_memset memset
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c
new file mode 100644
index 000000000000..14ad6aa6c4c0
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c
@@ -0,0 +1,71 @@
+/*
+ * cxd2880_stopwatch_port.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * time measurement functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_common.h"
+
+#include <linux/ktime.h>
+#include <linux/time.h>
+#include <linux/timekeeping.h>
+
+static u32 get_time_count(void)
+{
+ struct timespec tp;
+
+ getnstimeofday(&tp);
+
+ return (u32)((tp.tv_sec * 1000) + (tp.tv_nsec / 1000000));
+}
+
+enum cxd2880_ret cxd2880_stopwatch_start(struct cxd2880_stopwatch *stopwatch)
+{
+ if (!stopwatch)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ stopwatch->start_time = get_time_count();
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_stopwatch_sleep(struct cxd2880_stopwatch *stopwatch,
+ u32 ms)
+{
+ if (!stopwatch)
+ return CXD2880_RESULT_ERROR_ARG;
+ CXD2880_ARG_UNUSED(*stopwatch);
+ CXD2880_SLEEP(ms);
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_stopwatch_elapsed(struct cxd2880_stopwatch *stopwatch,
+ u32 *elapsed)
+{
+ if (!stopwatch || !elapsed)
+ return CXD2880_RESULT_ERROR_ARG;
+ *elapsed = get_time_count() - stopwatch->start_time;
+
+ return CXD2880_RESULT_OK;
+}
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 04/15] [media] cxd2880: Add math functions for the driver
From: Yasunari.Takiguchi-7U/KSKJipcs @ 2017-04-14 2:22 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: tbird20d-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w, Yasunari Takiguchi,
Masayuki Yamamoto, Hideki Nozawa, Kota Yonezawa,
Toshihiko Matsumoto, Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
From: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
Provide some math support functions (fixed-point log functions)
for the Sony CXD2880 DVB-T2/T tuner + demodulator driver.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe-7U/KSKJipcs@public.gmane.org>
---
drivers/media/dvb-frontends/cxd2880/cxd2880_math.c | 89 ++++++++++++++++++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_math.h | 40 ++++++++++
2 files changed, 129 insertions(+)
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_math.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
new file mode 100644
index 000000000000..434c827898ff
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
@@ -0,0 +1,89 @@
+/*
+ * cxd2880_math.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * mathmatics functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_math.h"
+
+#define MAX_BIT_PRECISION 5
+#define FRAC_BITMASK 0x1F
+#define LOG2_10_100X 332
+#define LOG2_E_100X 144
+
+static const u8 log2_look_up[] = {
+ 0, 4,
+ 9, 13,
+ 17, 21,
+ 25, 29,
+ 32, 36,
+ 39, 43,
+ 46, 49,
+ 52, 55,
+ 58, 61,
+ 64, 67,
+ 70, 73,
+ 75, 78,
+ 81, 83,
+ 86, 88,
+ 91, 93,
+ 95, 98
+};
+
+u32 cxd2880_math_log2(u32 x)
+{
+ u8 count = 0;
+ u8 index = 0;
+ u32 xval = x;
+
+ for (x >>= 1; x > 0; x >>= 1)
+ count++;
+
+ x = count * 100;
+
+ if (count > 0) {
+ if (count <= MAX_BIT_PRECISION) {
+ index =
+ (u8)(xval << (MAX_BIT_PRECISION - count)) &
+ FRAC_BITMASK;
+ x += log2_look_up[index];
+ } else {
+ index =
+ (u8)(xval >> (count - MAX_BIT_PRECISION)) &
+ FRAC_BITMASK;
+ x += log2_look_up[index];
+ }
+ }
+
+ return x;
+}
+
+u32 cxd2880_math_log10(u32 x)
+{
+ return ((100 * cxd2880_math_log2(x) + LOG2_10_100X / 2) / LOG2_10_100X);
+}
+
+u32 cxd2880_math_log(u32 x)
+{
+ return ((100 * cxd2880_math_log2(x) + LOG2_E_100X / 2) / LOG2_E_100X);
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_math.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
new file mode 100644
index 000000000000..94211835a4ad
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
@@ -0,0 +1,40 @@
+/*
+ * cxd2880_math.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * mathmatics definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_MATH_H_
+#define CXD2880_MATH_H_
+
+#include "cxd2880_common.h"
+
+u32 cxd2880_math_log2(u32 x);
+u32 cxd2880_math_log10(u32 x);
+u32 cxd2880_math_log(u32 x);
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#endif
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 05/15] [media] cxd2880: Add spi device IO routines
From: Yasunari.Takiguchi @ 2017-04-14 2:25 UTC (permalink / raw)
To: linux-kernel, devicetree, linux-media
Cc: tbird20d, frowand.list, Yasunari Takiguchi, Masayuki Yamamoto,
Hideki Nozawa, Kota Yonezawa, Toshihiko Matsumoto,
Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi@sony.com>
From: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com>
Add functions for initializing, reading and writing to the SPI
device for the Sony CXD2880 DVB-T2/T tuner + demodulator.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto@sony.com>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa@sony.com>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa@sony.com>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto@sony.com>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe@sony.com>
---
.../dvb-frontends/cxd2880/cxd2880_devio_spi.c | 147 +++++++++++++++++++++
.../dvb-frontends/cxd2880/cxd2880_devio_spi.h | 40 ++++++
drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h | 51 +++++++
.../dvb-frontends/cxd2880/cxd2880_spi_device.c | 130 ++++++++++++++++++
.../dvb-frontends/cxd2880/cxd2880_spi_device.h | 45 +++++++
5 files changed, 413 insertions(+)
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
new file mode 100644
index 000000000000..516efade6bf5
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
@@ -0,0 +1,147 @@
+/*
+ * cxd2880_devio_spi.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * I/O interface via SPI
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_devio_spi.h"
+#include "cxd2880_stdlib.h"
+
+#define BURST_WRITE_MAX 128
+
+static enum cxd2880_ret cxd2880_io_spi_read_reg(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt,
+ u8 sub_address, u8 *data,
+ u32 size)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+ struct cxd2880_spi *spi = NULL;
+ u8 send_data[6];
+ u8 *read_data_top = data;
+
+ if ((!io) || (!io->if_object) || (!data))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (sub_address + size > 0x100)
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ spi = (struct cxd2880_spi *)(io->if_object);
+
+ if (tgt == CXD2880_IO_TGT_SYS)
+ send_data[0] = 0x0B;
+ else
+ send_data[0] = 0x0A;
+
+ send_data[3] = 0;
+ send_data[4] = 0;
+ send_data[5] = 0;
+
+ while (size > 0) {
+ send_data[1] = sub_address;
+ if (size > 255)
+ send_data[2] = 255;
+ else
+ send_data[2] = (u8)size;
+
+ ret =
+ spi->write_read(spi, send_data, sizeof(send_data),
+ read_data_top, send_data[2]);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ sub_address += send_data[2];
+ read_data_top += send_data[2];
+ size -= send_data[2];
+ }
+
+ return ret;
+}
+
+static enum cxd2880_ret cxd2880_io_spi_write_reg(struct cxd2880_io *io,
+ enum cxd2880_io_tgt tgt,
+ u8 sub_address,
+ const u8 *data, u32 size)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+ struct cxd2880_spi *spi = NULL;
+ u8 send_data[BURST_WRITE_MAX + 4];
+ const u8 *write_data_top = data;
+
+ if ((!io) || (!io->if_object) || (!data))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (size > BURST_WRITE_MAX)
+ return CXD2880_RESULT_ERROR_OVERFLOW;
+
+ if (sub_address + size > 0x100)
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ spi = (struct cxd2880_spi *)(io->if_object);
+
+ if (tgt == CXD2880_IO_TGT_SYS)
+ send_data[0] = 0x0F;
+ else
+ send_data[0] = 0x0E;
+
+ while (size > 0) {
+ send_data[1] = sub_address;
+ if (size > 255)
+ send_data[2] = 255;
+ else
+ send_data[2] = (u8)size;
+
+ cxd2880_memcpy(&send_data[3], write_data_top, send_data[2]);
+
+ if (tgt == CXD2880_IO_TGT_SYS) {
+ send_data[3 + send_data[2]] = 0x00;
+ ret = spi->write(spi, send_data, send_data[2] + 4);
+ } else {
+ ret = spi->write(spi, send_data, send_data[2] + 3);
+ }
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ sub_address += send_data[2];
+ write_data_top += send_data[2];
+ size -= send_data[2];
+ }
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_io_spi_create(struct cxd2880_io *io,
+ struct cxd2880_spi *spi, u8 slave_select)
+{
+ if ((!io) || (!spi))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ io->read_regs = cxd2880_io_spi_read_reg;
+ io->write_regs = cxd2880_io_spi_write_reg;
+ io->write_reg = cxd2880_io_common_write_one_reg;
+ io->if_object = spi;
+ io->i2c_address_sys = 0;
+ io->i2c_address_demod = 0;
+ io->slave_select = slave_select;
+
+ return CXD2880_RESULT_OK;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h
new file mode 100644
index 000000000000..15934bf11935
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h
@@ -0,0 +1,40 @@
+/*
+ * cxd2880_devio_spi.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * I/O interface via SPI
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_DEVIO_SPI_H
+#define CXD2880_DEVIO_SPI_H
+
+#include "cxd2880_common.h"
+#include "cxd2880_io.h"
+#include "cxd2880_spi.h"
+
+#include "cxd2880_tnrdmd.h"
+
+enum cxd2880_ret cxd2880_io_spi_create(struct cxd2880_io *io,
+ struct cxd2880_spi *spi,
+ u8 slave_select);
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h
new file mode 100644
index 000000000000..81e5be747962
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h
@@ -0,0 +1,51 @@
+/*
+ * cxd2880_spi.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * SPI access definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_SPI_H
+#define CXD2880_SPI_H
+
+#include "cxd2880_common.h"
+
+enum cxd2880_spi_mode {
+ CXD2880_SPI_MODE_0,
+ CXD2880_SPI_MODE_1,
+ CXD2880_SPI_MODE_2,
+ CXD2880_SPI_MODE_3
+};
+
+struct cxd2880_spi {
+ enum cxd2880_ret (*read)(struct cxd2880_spi *spi, u8 *data,
+ u32 size);
+ enum cxd2880_ret (*write)(struct cxd2880_spi *spi, const u8 *data,
+ u32 size);
+ enum cxd2880_ret (*write_read)(struct cxd2880_spi *spi,
+ const u8 *tx_data, u32 tx_size,
+ u8 *rx_data, u32 rx_size);
+ u32 flags;
+ void *user;
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c
new file mode 100644
index 000000000000..af9ed40c900b
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c
@@ -0,0 +1,130 @@
+/*
+ * cxd2880_spi_device.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * SPI access functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/spi/spi.h>
+
+#include "cxd2880_spi_device.h"
+
+static enum cxd2880_ret cxd2880_spi_device_write(struct cxd2880_spi *spi,
+ const u8 *data, u32 size)
+{
+ struct cxd2880_spi_device *spi_device = NULL;
+ struct spi_message msg;
+ struct spi_transfer tx;
+ int result = 0;
+
+ if ((!spi) || (!spi->user) || (!data) || (size == 0))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ spi_device = (struct cxd2880_spi_device *)(spi->user);
+
+ memset(&tx, 0, sizeof(tx));
+ tx.tx_buf = data;
+ tx.len = size;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&tx, &msg);
+ result = spi_sync(spi_device->spi, &msg);
+
+ if (result < 0)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret cxd2880_spi_device_write_read(struct cxd2880_spi *spi,
+ const u8 *tx_data,
+ u32 tx_size,
+ u8 *rx_data,
+ u32 rx_size)
+{
+ struct cxd2880_spi_device *spi_device = NULL;
+ int result = 0;
+
+ if ((!spi) || (!spi->user) || (!tx_data) ||
+ (tx_size == 0) || (!rx_data) || (rx_size == 0))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ spi_device = (struct cxd2880_spi_device *)(spi->user);
+
+ result = spi_write_then_read(spi_device->spi, tx_data,
+ tx_size, rx_data, rx_size);
+ if (result < 0)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret
+cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device,
+ enum cxd2880_spi_mode mode,
+ u32 speed_hz)
+{
+ int result = 0;
+ struct spi_device *spi = spi_device->spi;
+
+ switch (mode) {
+ case CXD2880_SPI_MODE_0:
+ spi->mode = SPI_MODE_0;
+ break;
+ case CXD2880_SPI_MODE_1:
+ spi->mode = SPI_MODE_1;
+ break;
+ case CXD2880_SPI_MODE_2:
+ spi->mode = SPI_MODE_2;
+ break;
+ case CXD2880_SPI_MODE_3:
+ spi->mode = SPI_MODE_3;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+
+ spi->max_speed_hz = speed_hz;
+ spi->bits_per_word = 8;
+ result = spi_setup(spi);
+ if (result != 0) {
+ pr_err("spi_setup failed %d\n", result);
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_spi_device_create_spi(struct cxd2880_spi *spi,
+ struct cxd2880_spi_device *spi_device)
+{
+ if ((!spi) || (!spi_device))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ spi->read = NULL;
+ spi->write = cxd2880_spi_device_write;
+ spi->write_read = cxd2880_spi_device_write_read;
+ spi->flags = 0;
+ spi->user = spi_device;
+
+ return CXD2880_RESULT_OK;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h
new file mode 100644
index 000000000000..343d9161d537
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h
@@ -0,0 +1,45 @@
+/*
+ * cxd2880_spi_device.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * SPI access interface
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_SPI_DEVICE_H
+#define CXD2880_SPI_DEVICE_H
+
+#include "cxd2880_spi.h"
+
+struct cxd2880_spi_device {
+ struct spi_device *spi;
+};
+
+enum cxd2880_ret
+cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device,
+ enum cxd2880_spi_mode mode,
+ u32 speedHz);
+
+enum cxd2880_ret
+cxd2880_spi_device_create_spi(struct cxd2880_spi *spi,
+ struct cxd2880_spi_device *spi_device);
+
+#endif /* CXD2880_SPI_DEVICE_H */
--
2.11.0
^ permalink raw reply related
* [PATCH v2 06/15] [media] cxd2880: Add tuner part of the driver
From: Yasunari.Takiguchi-7U/KSKJipcs @ 2017-04-14 2:26 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: tbird20d-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w, Yasunari Takiguchi,
Masayuki Yamamoto, Hideki Nozawa, Kota Yonezawa,
Toshihiko Matsumoto, Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
From: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
This part of the driver has the main routines to handle
the tuner and demodulator functionality. The tnrdmd_mon.* files
have monitor functions for the driver.
This is part of the Sony CXD2880 DVB-T2/T tuner + demodulator driver.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto-7U/KSKJipcs@public.gmane.org>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe-7U/KSKJipcs@public.gmane.org>
---
drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h | 50 +
.../media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c | 3925 ++++++++++++++++++++
.../media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h | 395 ++
.../cxd2880/cxd2880_tnrdmd_driver_version.h | 29 +
.../dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c | 207 ++
.../dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h | 52 +
6 files changed, 4658 insertions(+)
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
new file mode 100644
index 000000000000..7de098d556fe
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
@@ -0,0 +1,50 @@
+/*
+ * cxd2880_dtv.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * DTV related definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_DTV_H
+#define CXD2880_DTV_H
+
+enum cxd2880_dtv_sys {
+ CXD2880_DTV_SYS_UNKNOWN,
+ CXD2880_DTV_SYS_DVBT,
+ CXD2880_DTV_SYS_DVBT2,
+ CXD2880_DTV_SYS_ISDBT,
+ CXD2880_DTV_SYS_ISDBTSB,
+ CXD2880_DTV_SYS_ISDBTMM_A,
+ CXD2880_DTV_SYS_ISDBTMM_B,
+ CXD2880_DTV_SYS_ANY
+};
+
+enum cxd2880_dtv_bandwidth {
+ CXD2880_DTV_BW_UNKNOWN = 0,
+ CXD2880_DTV_BW_1_7_MHZ = 1,
+ CXD2880_DTV_BW_5_MHZ = 5,
+ CXD2880_DTV_BW_6_MHZ = 6,
+ CXD2880_DTV_BW_7_MHZ = 7,
+ CXD2880_DTV_BW_8_MHZ = 8
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
new file mode 100644
index 000000000000..286384ae0124
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
@@ -0,0 +1,3925 @@
+/*
+ * cxd2880_tnrdmd.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common control functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_common.h"
+#include "cxd2880_stdlib.h"
+#include "cxd2880_tnrdmd.h"
+#include "cxd2880_tnrdmd_mon.h"
+#include "cxd2880_tnrdmd_dvbt.h"
+#include "cxd2880_tnrdmd_dvbt2.h"
+
+static enum cxd2880_ret p_init1(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data = 0;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if ((tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) ||
+ (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)) {
+ switch (tnr_dmd->create_param.ts_output_if) {
+ case CXD2880_TNRDMD_TSOUT_IF_TS:
+ data = 0x00;
+ break;
+ case CXD2880_TNRDMD_TSOUT_IF_SPI:
+ data = 0x01;
+ break;
+ case CXD2880_TNRDMD_TSOUT_IF_SDIO:
+ data = 0x02;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10,
+ data) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x11,
+ 0x16) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ switch (tnr_dmd->chip_id) {
+ case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X:
+ data = 0x1A;
+ break;
+ case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11:
+ data = 0x16;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_NOSUPPORT;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10,
+ data) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->create_param.en_internal_ldo)
+ data = 0x01;
+ else
+ data = 0x00;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x11,
+ data) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x13,
+ data) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x12,
+ data) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ switch (tnr_dmd->chip_id) {
+ case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X:
+ data = 0x01;
+ break;
+ case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11:
+ data = 0x00;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_NOSUPPORT;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x69,
+ data) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret p_init2(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data[6] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = tnr_dmd->create_param.xosc_cap;
+ data[1] = tnr_dmd->create_param.xosc_i;
+ switch (tnr_dmd->create_param.xtal_share_type) {
+ case CXD2880_TNRDMD_XTAL_SHARE_NONE:
+ data[2] = 0x01;
+ data[3] = 0x00;
+ break;
+ case CXD2880_TNRDMD_XTAL_SHARE_EXTREF:
+ data[2] = 0x00;
+ data[3] = 0x00;
+ break;
+ case CXD2880_TNRDMD_XTAL_SHARE_MASTER:
+ data[2] = 0x01;
+ data[3] = 0x01;
+ break;
+ case CXD2880_TNRDMD_XTAL_SHARE_SLAVE:
+ data[2] = 0x00;
+ data[3] = 0x01;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+ data[4] = 0x06;
+ data[5] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x13, data,
+ 6) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret p_init3(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data[2] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ switch (tnr_dmd->diver_mode) {
+ case CXD2880_TNRDMD_DIVERMODE_SINGLE:
+ data[0] = 0x00;
+ break;
+ case CXD2880_TNRDMD_DIVERMODE_MAIN:
+ data[0] = 0x03;
+ break;
+ case CXD2880_TNRDMD_DIVERMODE_SUB:
+ data[0] = 0x02;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+
+ data[1] = 0x01;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x1F, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret rf_init1(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data[80] = { 0 };
+ u8 addr = 0;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x01;
+ data[1] = 0x00;
+ data[2] = 0x01;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x21, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x01;
+ data[1] = 0x01;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x17, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->create_param.stationary_use) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x1A,
+ 0x06) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x4F,
+ 0x18) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x61,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x71,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x9D,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x7D,
+ 0x02) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x8F,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x8B,
+ 0xC6) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x9A,
+ 0x03) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x1C,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ if ((tnr_dmd->create_param.is_cxd2881gg) &&
+ (tnr_dmd->create_param.xtal_share_type ==
+ CXD2880_TNRDMD_XTAL_SHARE_SLAVE))
+ data[1] = 0x00;
+ else
+ data[1] = 0x1F;
+ data[2] = 0x0A;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xB5, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xB9,
+ 0x07) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x33,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xC1,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xC4,
+ 0x1E) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) {
+ data[0] = 0x34;
+ data[1] = 0x2C;
+ } else {
+ data[0] = 0x2F;
+ data[1] = 0x25;
+ }
+ data[2] = 0x15;
+ data[3] = 0x19;
+ data[4] = 0x1B;
+ data[5] = 0x15;
+ data[6] = 0x19;
+ data[7] = 0x1B;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xD9, data,
+ 8) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x11) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x6C;
+ data[1] = 0x10;
+ data[2] = 0xA6;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x44, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x16;
+ data[1] = 0xA8;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x50, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x22;
+ data[2] = 0x00;
+ data[3] = 0x88;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x62, data,
+ 4) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x74,
+ 0x75) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x05;
+ data[1] = 0x05;
+ data[2] = 0x05;
+ data[3] = 0x05;
+ data[4] = 0x05;
+ data[5] = 0x05;
+ data[6] = 0x05;
+ data[7] = 0x05;
+ data[8] = 0x05;
+ data[9] = 0x04;
+ data[10] = 0x04;
+ data[11] = 0x04;
+ data[12] = 0x03;
+ data[13] = 0x03;
+ data[14] = 0x03;
+ data[15] = 0x04;
+ data[16] = 0x04;
+ data[17] = 0x05;
+ data[18] = 0x05;
+ data[19] = 0x05;
+ data[20] = 0x02;
+ data[21] = 0x02;
+ data[22] = 0x02;
+ data[23] = 0x02;
+ data[24] = 0x02;
+ data[25] = 0x02;
+ data[26] = 0x02;
+ data[27] = 0x02;
+ data[28] = 0x02;
+ data[29] = 0x03;
+ data[30] = 0x02;
+ data[31] = 0x01;
+ data[32] = 0x01;
+ data[33] = 0x01;
+ data[34] = 0x02;
+ data[35] = 0x02;
+ data[36] = 0x03;
+ data[37] = 0x04;
+ data[38] = 0x04;
+ data[39] = 0x04;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x7F, data,
+ 40) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x16) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x71;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x23,
+ 0x89) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0xFF;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ data[4] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27, data,
+ 5) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ data[4] = 0x00;
+ data[5] = 0x01;
+ data[6] = 0x00;
+ data[7] = 0x01;
+ data[8] = 0x00;
+ data[9] = 0x02;
+ data[10] = 0x00;
+ data[11] = 0x63;
+ data[12] = 0x00;
+ data[13] = 0x00;
+ data[14] = 0x00;
+ data[15] = 0x03;
+ data[16] = 0x00;
+ data[17] = 0x04;
+ data[18] = 0x00;
+ data[19] = 0x04;
+ data[20] = 0x00;
+ data[21] = 0x06;
+ data[22] = 0x00;
+ data[23] = 0x06;
+ data[24] = 0x00;
+ data[25] = 0x08;
+ data[26] = 0x00;
+ data[27] = 0x09;
+ data[28] = 0x00;
+ data[29] = 0x0B;
+ data[30] = 0x00;
+ data[31] = 0x0B;
+ data[32] = 0x00;
+ data[33] = 0x0D;
+ data[34] = 0x00;
+ data[35] = 0x0D;
+ data[36] = 0x00;
+ data[37] = 0x0F;
+ data[38] = 0x00;
+ data[39] = 0x0F;
+ data[40] = 0x00;
+ data[41] = 0x0F;
+ data[42] = 0x00;
+ data[43] = 0x10;
+ data[44] = 0x00;
+ data[45] = 0x79;
+ data[46] = 0x00;
+ data[47] = 0x00;
+ data[48] = 0x00;
+ data[49] = 0x02;
+ data[50] = 0x00;
+ data[51] = 0x00;
+ data[52] = 0x00;
+ data[53] = 0x03;
+ data[54] = 0x00;
+ data[55] = 0x01;
+ data[56] = 0x00;
+ data[57] = 0x03;
+ data[58] = 0x00;
+ data[59] = 0x03;
+ data[60] = 0x00;
+ data[61] = 0x03;
+ data[62] = 0x00;
+ data[63] = 0x04;
+ data[64] = 0x00;
+ data[65] = 0x04;
+ data[66] = 0x00;
+ data[67] = 0x06;
+ data[68] = 0x00;
+ data[69] = 0x05;
+ data[70] = 0x00;
+ data[71] = 0x07;
+ data[72] = 0x00;
+ data[73] = 0x07;
+ data[74] = 0x00;
+ data[75] = 0x08;
+ data[76] = 0x00;
+ data[77] = 0x0A;
+ data[78] = 0x03;
+ data[79] = 0xE0;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x3A, data,
+ 80) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = 0x03;
+ data[1] = 0xE0;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xBC, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x51,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xC5,
+ 0x07) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x11) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x70,
+ 0xE9) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x76,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x78,
+ 0x32) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x7A,
+ 0x46) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x7C,
+ 0x86) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x7E,
+ 0xA4) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xE1,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->create_param.stationary_use) {
+ data[0] = 0x06;
+ data[1] = 0x07;
+ data[2] = 0x1A;
+ } else {
+ data[0] = 0x00;
+ data[1] = 0x08;
+ data[2] = 0x19;
+ }
+ data[3] = 0x0E;
+ data[4] = 0x09;
+ data[5] = 0x0E;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x12) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ for (addr = 0x10; addr < 0x9F; addr += 6) {
+ if (tnr_dmd->lna_thrs_tbl_air) {
+ u8 idx = 0;
+
+ idx = (addr - 0x10) / 6;
+ data[0] =
+ tnr_dmd->lna_thrs_tbl_air->thrs[idx].off_on;
+ data[1] =
+ tnr_dmd->lna_thrs_tbl_air->thrs[idx].on_off;
+ }
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, addr,
+ data,
+ 6) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ data[0] = 0x00;
+ data[1] = 0x08;
+ if (tnr_dmd->create_param.stationary_use)
+ data[2] = 0x1A;
+ else
+ data[2] = 0x19;
+ data[3] = 0x0E;
+ data[4] = 0x09;
+ data[5] = 0x0E;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x13) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ for (addr = 0x10; addr < 0xCF; addr += 6) {
+ if (tnr_dmd->lna_thrs_tbl_cable) {
+ u8 idx = 0;
+
+ idx = (addr - 0x10) / 6;
+ data[0] =
+ tnr_dmd->lna_thrs_tbl_cable->thrs[idx].off_on;
+ data[1] =
+ tnr_dmd->lna_thrs_tbl_cable->thrs[idx].on_off;
+ }
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, addr,
+ data,
+ 6) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x11) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x08;
+ data[1] = 0x09;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xBD, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x08;
+ data[1] = 0x09;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xC4, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x20;
+ data[1] = 0x20;
+ data[2] = 0x30;
+ data[3] = 0x41;
+ data[4] = 0x50;
+ data[5] = 0x5F;
+ data[6] = 0x6F;
+ data[7] = 0x80;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xC9, data,
+ 8) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x14) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x15;
+ data[1] = 0x18;
+ data[2] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x15,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x16) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x09;
+ data[2] = 0x00;
+ data[3] = 0x08;
+ data[4] = 0x00;
+ data[5] = 0x07;
+ data[6] = 0x00;
+ data[7] = 0x06;
+ data[8] = 0x00;
+ data[9] = 0x05;
+ data[10] = 0x00;
+ data[11] = 0x03;
+ data[12] = 0x00;
+ data[13] = 0x02;
+ data[14] = 0x00;
+ data[15] = 0x00;
+ data[16] = 0x00;
+ data[17] = 0x78;
+ data[18] = 0x00;
+ data[19] = 0x00;
+ data[20] = 0x00;
+ data[21] = 0x06;
+ data[22] = 0x00;
+ data[23] = 0x08;
+ data[24] = 0x00;
+ data[25] = 0x08;
+ data[26] = 0x00;
+ data[27] = 0x0C;
+ data[28] = 0x00;
+ data[29] = 0x0C;
+ data[30] = 0x00;
+ data[31] = 0x0D;
+ data[32] = 0x00;
+ data[33] = 0x0F;
+ data[34] = 0x00;
+ data[35] = 0x0E;
+ data[36] = 0x00;
+ data[37] = 0x0E;
+ data[38] = 0x00;
+ data[39] = 0x10;
+ data[40] = 0x00;
+ data[41] = 0x0F;
+ data[42] = 0x00;
+ data[43] = 0x0E;
+ data[44] = 0x00;
+ data[45] = 0x10;
+ data[46] = 0x00;
+ data[47] = 0x0F;
+ data[48] = 0x00;
+ data[49] = 0x0E;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x12, data,
+ 50) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0x00)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x25,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x11, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0x00)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x02,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x8F,
+ 0x16) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x67,
+ 0x60) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x6A,
+ 0x0F) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x6C,
+ 0x17) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0xFE;
+ data[2] = 0xEE;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x6E, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0xA1;
+ data[1] = 0x8B;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x8D, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x08;
+ data[1] = 0x09;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x77, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->create_param.stationary_use) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x80,
+ 0xAA) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x41,
+ 0xA0) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x4B,
+ 0x68) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x25,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x1A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0x00)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x14,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x26,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret rf_init2(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data[5] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x40;
+ data[1] = 0x40;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xEA, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ data[0] = 0x00;
+ if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X)
+ data[1] = 0x00;
+ else
+ data[1] = 0x01;
+ data[2] = 0x01;
+ data[3] = 0x03;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x30, data,
+ 4) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x14) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x1B,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xD3,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_tune1(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dtv_sys sys, u32 freq_khz,
+ enum cxd2880_dtv_bandwidth bandwidth,
+ u8 is_cable, int shift_frequency_khz)
+{
+ u8 data[11] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x0E;
+ data[3] = 0x00;
+ data[4] = 0x03;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xE7, data,
+ 5) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = 0x1F;
+ data[1] = 0x80;
+ data[2] = 0x18;
+ data[3] = 0x00;
+ data[4] = 0x07;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xE7, data,
+ 5) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ data[0] = 0x72;
+ data[1] = 0x81;
+ data[3] = 0x1D;
+ data[4] = 0x6F;
+ data[5] = 0x7E;
+ data[7] = 0x1C;
+ switch (sys) {
+ case CXD2880_DTV_SYS_DVBT:
+ case CXD2880_DTV_SYS_ISDBT:
+ case CXD2880_DTV_SYS_ISDBTSB:
+ case CXD2880_DTV_SYS_ISDBTMM_A:
+ case CXD2880_DTV_SYS_ISDBTMM_B:
+ data[2] = 0x94;
+ data[6] = 0x91;
+ break;
+ case CXD2880_DTV_SYS_DVBT2:
+ data[2] = 0x96;
+ data[6] = 0x93;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x44, data,
+ 8) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x62,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x15) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x03;
+ data[1] = 0xE2;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x1E, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = (u8)(is_cable ? 0x01 : 0x00);
+ data[1] = 0x00;
+ data[2] = 0x6B;
+ data[3] = 0x4D;
+
+ switch (bandwidth) {
+ case CXD2880_DTV_BW_1_7_MHZ:
+ data[4] = 0x03;
+ break;
+ case CXD2880_DTV_BW_5_MHZ:
+ case CXD2880_DTV_BW_6_MHZ:
+ data[4] = 0x00;
+ break;
+ case CXD2880_DTV_BW_7_MHZ:
+ data[4] = 0x01;
+ break;
+ case CXD2880_DTV_BW_8_MHZ:
+ data[4] = 0x02;
+ break;
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+
+ data[5] = 0x00;
+
+ freq_khz += shift_frequency_khz;
+
+ data[6] = (u8)((freq_khz >> 16) & 0x0F);
+ data[7] = (u8)((freq_khz >> 8) & 0xFF);
+ data[8] = (u8)(freq_khz & 0xFF);
+ data[9] = 0xFF;
+ data[10] = 0xFE;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x52, data,
+ 11) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_tune2(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dtv_bandwidth bandwidth,
+ enum cxd2880_tnrdmd_clockmode clk_mode,
+ int shift_frequency_khz)
+{
+ u8 data[3] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x11) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = 0x01;
+ data[1] = 0x0E;
+ data[2] = 0x01;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2D, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x1A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x29,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2C, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x60,
+ data[0]) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x62,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x11) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2D,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2F,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (shift_frequency_khz != 0) {
+ int shift_freq = 0;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x60, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ shift_freq = shift_frequency_khz * 1000;
+
+ switch (clk_mode) {
+ case CXD2880_TNRDMD_CLOCKMODE_A:
+ case CXD2880_TNRDMD_CLOCKMODE_C:
+ default:
+ if (shift_freq >= 0)
+ shift_freq = (shift_freq + 183 / 2) / 183;
+ else
+ shift_freq = (shift_freq - 183 / 2) / 183;
+ break;
+ case CXD2880_TNRDMD_CLOCKMODE_B:
+ if (shift_freq >= 0)
+ shift_freq = (shift_freq + 178 / 2) / 178;
+ else
+ shift_freq = (shift_freq - 178 / 2) / 178;
+ break;
+ }
+
+ shift_freq +=
+ cxd2880_convert2s_complement((data[0] << 8) | data[1], 16);
+
+ if (shift_freq > 32767)
+ shift_freq = 32767;
+ else if (shift_freq < -32768)
+ shift_freq = -32768;
+
+ data[0] = (u8)(((u32)shift_freq >> 8) & 0xFF);
+ data[1] = (u8)((u32)shift_freq & 0xFF);
+
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x60, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x69, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ shift_freq = -shift_frequency_khz;
+
+ if (bandwidth == CXD2880_DTV_BW_1_7_MHZ) {
+ switch (clk_mode) {
+ case CXD2880_TNRDMD_CLOCKMODE_A:
+ case CXD2880_TNRDMD_CLOCKMODE_C:
+ default:
+ if (shift_freq >= 0)
+ shift_freq =
+ (shift_freq * 1000 +
+ 17578 / 2) / 17578;
+ else
+ shift_freq =
+ (shift_freq * 1000 -
+ 17578 / 2) / 17578;
+ break;
+ case CXD2880_TNRDMD_CLOCKMODE_B:
+ if (shift_freq >= 0)
+ shift_freq =
+ (shift_freq * 1000 +
+ 17090 / 2) / 17090;
+ else
+ shift_freq =
+ (shift_freq * 1000 -
+ 17090 / 2) / 17090;
+ break;
+ }
+ } else {
+ switch (clk_mode) {
+ case CXD2880_TNRDMD_CLOCKMODE_A:
+ case CXD2880_TNRDMD_CLOCKMODE_C:
+ default:
+ if (shift_freq >= 0)
+ shift_freq =
+ (shift_freq * 1000 +
+ 35156 / 2) / 35156;
+ else
+ shift_freq =
+ (shift_freq * 1000 -
+ 35156 / 2) / 35156;
+ break;
+ case CXD2880_TNRDMD_CLOCKMODE_B:
+ if (shift_freq >= 0)
+ shift_freq =
+ (shift_freq * 1000 +
+ 34180 / 2) / 34180;
+ else
+ shift_freq =
+ (shift_freq * 1000 -
+ 34180 / 2) / 34180;
+ break;
+ }
+ }
+
+ shift_freq += cxd2880_convert2s_complement(data[0], 8);
+
+ if (shift_freq > 127)
+ shift_freq = 127;
+ else if (shift_freq < -128)
+ shift_freq = -128;
+
+ data[0] = (u8)((u32)shift_freq & 0xFF);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x69,
+ data[0]) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->create_param.stationary_use) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x8A,
+ 0x87) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_tune3(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u8 en_fef_intmtnt_ctrl)
+{
+ u8 data[6] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x41,
+ 0xA0) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xFE,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((sys == CXD2880_DTV_SYS_DVBT2) && en_fef_intmtnt_ctrl) {
+ data[0] = 0x01;
+ data[1] = 0x01;
+ data[2] = 0x01;
+ data[3] = 0x01;
+ data[4] = 0x01;
+ data[5] = 0x01;
+ } else {
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ data[4] = 0x00;
+ data[5] = 0x00;
+ }
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xEF, data,
+ 6) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x2D) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((sys == CXD2880_DTV_SYS_DVBT2) && en_fef_intmtnt_ctrl)
+ data[0] = 0x00;
+ else
+ data[0] = 0x01;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xB1,
+ data[0]) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_tune4(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data[2] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ {
+ if (tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) !=
+ CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x14;
+ data[1] = 0x00;
+ if (tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x55,
+ data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x0B;
+ data[1] = 0xFF;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x53, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x57,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x0B;
+ data[1] = 0xFF;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x55, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ {
+ if (tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) !=
+ CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x14;
+ data[1] = 0x00;
+ if (tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x53,
+ data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x57,
+ 0x02) !=
+ CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xFE,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_DMD, 0xFE,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_sleep1(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data[3] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x57,
+ 0x03) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x53, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ {
+ if (tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) !=
+ CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x1F;
+ data[1] = 0xFF;
+ data[2] = 0x03;
+ if (tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x55,
+ data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x00;
+ if (tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
+ CXD2880_IO_TGT_SYS, 0x53,
+ data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x1F;
+ data[1] = 0xFF;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x55, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_sleep2(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ u8 data = 0;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x2D) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xB1,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xB2, &data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data & 0x01) == 0x00)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xF4,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xF3,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xF2,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xF1,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xF0,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xEF,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_sleep3(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xFD,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret x_sleep4(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0xE2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x41,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x21,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret spll_reset(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_tnrdmd_clockmode clockmode)
+{
+ u8 data[4] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x29,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x28,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x26,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x22,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ switch (clockmode) {
+ case CXD2880_TNRDMD_CLOCKMODE_A:
+ data[0] = 0x00;
+ break;
+
+ case CXD2880_TNRDMD_CLOCKMODE_B:
+ data[0] = 0x01;
+ break;
+
+ case CXD2880_TNRDMD_CLOCKMODE_C:
+ data[0] = 0x02;
+ break;
+
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x30,
+ data[0]) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x22,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(2);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x10, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0x00)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x26, data,
+ 4) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret t_power_x(struct cxd2880_tnrdmd *tnr_dmd, u8 on)
+{
+ u8 data[3] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x29,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x28,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x25,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (on) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2B,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x12, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2A,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ } else {
+ data[0] = 0x03;
+ data[1] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2A, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x13, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x25,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x11, data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if ((data[0] & 0x01) == 0)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x27, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+struct cxd2880_tnrdmd_ts_clk_cfg {
+ u8 srl_clk_mode;
+ u8 srl_duty_mode;
+ u8 ts_clk_period;
+};
+
+static enum cxd2880_ret set_ts_clk_mode_and_freq(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dtv_sys sys)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+ u8 backwards_compatible = 0;
+ struct cxd2880_tnrdmd_ts_clk_cfg ts_clk_cfg;
+
+ const struct cxd2880_tnrdmd_ts_clk_cfg srl_ts_clk_stgs[2][2] = {
+ {
+ {3, 1, 8,},
+ {0, 2, 16,}
+ },
+ {
+ {1, 1, 8,},
+ {2, 2, 16,}
+ }
+ };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ {
+ u8 ts_rate_ctrl_off = 0;
+ u8 ts_in_off = 0;
+ u8 ts_clk_manaul_on = 0;
+
+ if ((sys == CXD2880_DTV_SYS_ISDBT) ||
+ (sys == CXD2880_DTV_SYS_ISDBTSB) ||
+ (sys == CXD2880_DTV_SYS_ISDBTMM_A) ||
+ (sys == CXD2880_DTV_SYS_ISDBTMM_B)) {
+ backwards_compatible = 0;
+ ts_rate_ctrl_off = 1;
+ ts_in_off = 0;
+ } else if (tnr_dmd->is_ts_backwards_compatible_mode) {
+ backwards_compatible = 1;
+ ts_rate_ctrl_off = 1;
+ ts_in_off = 1;
+ } else {
+ backwards_compatible = 0;
+ ts_rate_ctrl_off = 0;
+ ts_in_off = 0;
+ }
+
+ if (tnr_dmd->ts_byte_clk_manual_setting) {
+ ts_clk_manaul_on = 1;
+ ts_rate_ctrl_off = 0;
+ }
+
+ ret =
+ cxd2880_io_set_reg_bits(tnr_dmd->io, CXD2880_IO_TGT_DMD,
+ 0xD3, ts_rate_ctrl_off, 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_io_set_reg_bits(tnr_dmd->io, CXD2880_IO_TGT_DMD,
+ 0xDE, ts_in_off, 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_io_set_reg_bits(tnr_dmd->io, CXD2880_IO_TGT_DMD,
+ 0xDA, ts_clk_manaul_on, 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ts_clk_cfg =
+ srl_ts_clk_stgs[tnr_dmd->srl_ts_clk_mod_cnts]
+ [(u8)tnr_dmd->srl_ts_clk_frq];
+
+ if (tnr_dmd->ts_byte_clk_manual_setting)
+ ts_clk_cfg.ts_clk_period = tnr_dmd->ts_byte_clk_manual_setting;
+
+ ret =
+ cxd2880_io_set_reg_bits(tnr_dmd->io, CXD2880_IO_TGT_DMD, 0xC4,
+ ts_clk_cfg.srl_clk_mode, 0x03);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_io_set_reg_bits(tnr_dmd->io, CXD2880_IO_TGT_DMD, 0xD1,
+ ts_clk_cfg.srl_duty_mode, 0x03);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret = tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xD9,
+ ts_clk_cfg.ts_clk_period);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ {
+ u8 data = (u8)(backwards_compatible ? 0x00 : 0x01);
+
+ if (sys == CXD2880_DTV_SYS_DVBT) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ ret =
+ cxd2880_io_set_reg_bits(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x66,
+ data, 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static enum cxd2880_ret pid_ftr_setting(struct cxd2880_tnrdmd *tnr_dmd,
+ struct cxd2880_tnrdmd_pid_ftr_cfg
+ *pid_ftr_cfg)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (!pid_ftr_cfg) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x50,
+ 0x02) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ } else {
+ u8 data[65];
+
+ data[0] = (u8)(pid_ftr_cfg->is_negative ? 0x01 : 0x00);
+ {
+ int i = 0;
+
+ for (i = 0; i < 32; i++) {
+ if (pid_ftr_cfg->pid_cfg[i].is_en) {
+ data[1 + (i * 2)] =
+ (u8)((u8)
+ (pid_ftr_cfg->pid_cfg[i].pid
+ >> 8) | 0x20);
+ data[2 + (i * 2)] =
+ (u8)(pid_ftr_cfg->pid_cfg[i].pid
+ & 0xFF);
+ } else {
+ data[1 + (i * 2)] = 0x00;
+ data[2 + (i * 2)] = 0x00;
+ }
+ }
+ }
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x50, data,
+ 65) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+static enum cxd2880_ret load_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+ u8 i;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) {
+ ret = tnr_dmd->io->write_reg(tnr_dmd->io,
+ tnr_dmd->cfg_mem[i].tgt,
+ 0x00, tnr_dmd->cfg_mem[i].bank);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
+ tnr_dmd->cfg_mem[i].tgt,
+ tnr_dmd->cfg_mem[i].address,
+ tnr_dmd->cfg_mem[i].value,
+ tnr_dmd->cfg_mem[i].bit_mask);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return ret;
+}
+
+static enum cxd2880_ret set_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_io_tgt tgt,
+ u8 bank, u8 address, u8 value, u8 bit_mask)
+{
+ u8 i;
+ u8 value_stored = 0;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) {
+ if ((value_stored == 0) &&
+ (tnr_dmd->cfg_mem[i].tgt == tgt) &&
+ (tnr_dmd->cfg_mem[i].bank == bank) &&
+ (tnr_dmd->cfg_mem[i].address == address)) {
+ tnr_dmd->cfg_mem[i].value &= ~bit_mask;
+ tnr_dmd->cfg_mem[i].value |= (value & bit_mask);
+
+ tnr_dmd->cfg_mem[i].bit_mask |= bit_mask;
+
+ value_stored = 1;
+ }
+ }
+
+ if (value_stored == 0) {
+ if (tnr_dmd->cfg_mem_last_entry <
+ CXD2880_TNRDMD_MAX_CFG_MEM_COUNT) {
+ tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].tgt = tgt;
+ tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bank =
+ bank;
+ tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].address =
+ address;
+ tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].value =
+ (value & bit_mask);
+ tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bit_mask =
+ bit_mask;
+ tnr_dmd->cfg_mem_last_entry++;
+ } else {
+ return CXD2880_RESULT_ERROR_OVERFLOW;
+ }
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
+ struct cxd2880_io *io,
+ struct cxd2880_tnrdmd_create_param
+ *create_param)
+{
+ if ((!tnr_dmd) || (!io) || (!create_param))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ cxd2880_memset(tnr_dmd, 0, sizeof(struct cxd2880_tnrdmd));
+
+ tnr_dmd->io = io;
+ tnr_dmd->create_param = *create_param;
+
+ tnr_dmd->diver_mode = CXD2880_TNRDMD_DIVERMODE_SINGLE;
+ tnr_dmd->diver_sub = NULL;
+
+ tnr_dmd->srl_ts_clk_mod_cnts = 1;
+ tnr_dmd->en_fef_intmtnt_base = 1;
+ tnr_dmd->en_fef_intmtnt_lite = 1;
+ tnr_dmd->rf_lvl_cmpstn = NULL;
+ tnr_dmd->lna_thrs_tbl_air = NULL;
+ tnr_dmd->lna_thrs_tbl_cable = NULL;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd
+ *tnr_dmd_main,
+ struct cxd2880_io *io_main,
+ struct cxd2880_tnrdmd *tnr_dmd_sub,
+ struct cxd2880_io *io_sub,
+ struct
+ cxd2880_tnrdmd_diver_create_param
+ *create_param)
+{
+ if ((!tnr_dmd_main) || (!io_main) || (!tnr_dmd_sub) || (!io_sub) ||
+ (!create_param))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ cxd2880_memset(tnr_dmd_main, 0, sizeof(struct cxd2880_tnrdmd));
+ cxd2880_memset(tnr_dmd_sub, 0, sizeof(struct cxd2880_tnrdmd));
+
+ tnr_dmd_main->io = io_main;
+ tnr_dmd_main->diver_mode = CXD2880_TNRDMD_DIVERMODE_MAIN;
+ tnr_dmd_main->diver_sub = tnr_dmd_sub;
+ tnr_dmd_main->create_param.en_internal_ldo =
+ create_param->en_internal_ldo;
+ tnr_dmd_main->create_param.ts_output_if = create_param->ts_output_if;
+ tnr_dmd_main->create_param.xtal_share_type =
+ CXD2880_TNRDMD_XTAL_SHARE_MASTER;
+ tnr_dmd_main->create_param.xosc_cap = create_param->xosc_cap_main;
+ tnr_dmd_main->create_param.xosc_i = create_param->xosc_i_main;
+ tnr_dmd_main->create_param.is_cxd2881gg = create_param->is_cxd2881gg;
+ tnr_dmd_main->create_param.stationary_use =
+ create_param->stationary_use;
+
+ tnr_dmd_sub->io = io_sub;
+ tnr_dmd_sub->diver_mode = CXD2880_TNRDMD_DIVERMODE_SUB;
+ tnr_dmd_sub->diver_sub = NULL;
+ tnr_dmd_sub->create_param.en_internal_ldo =
+ create_param->en_internal_ldo;
+ tnr_dmd_sub->create_param.ts_output_if = create_param->ts_output_if;
+ tnr_dmd_sub->create_param.xtal_share_type =
+ CXD2880_TNRDMD_XTAL_SHARE_SLAVE;
+ tnr_dmd_sub->create_param.xosc_cap = 0;
+ tnr_dmd_sub->create_param.xosc_i = create_param->xosc_i_sub;
+ tnr_dmd_sub->create_param.is_cxd2881gg = create_param->is_cxd2881gg;
+ tnr_dmd_sub->create_param.stationary_use = create_param->stationary_use;
+
+ tnr_dmd_main->srl_ts_clk_mod_cnts = 1;
+ tnr_dmd_main->en_fef_intmtnt_base = 1;
+ tnr_dmd_main->en_fef_intmtnt_lite = 1;
+ tnr_dmd_main->rf_lvl_cmpstn = NULL;
+ tnr_dmd_main->lna_thrs_tbl_air = NULL;
+ tnr_dmd_main->lna_thrs_tbl_cable = NULL;
+
+ tnr_dmd_sub->srl_ts_clk_mod_cnts = 1;
+ tnr_dmd_sub->en_fef_intmtnt_base = 1;
+ tnr_dmd_sub->en_fef_intmtnt_lite = 1;
+ tnr_dmd_sub->rf_lvl_cmpstn = NULL;
+ tnr_dmd_sub->lna_thrs_tbl_air = NULL;
+ tnr_dmd_sub->lna_thrs_tbl_cable = NULL;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if ((!tnr_dmd) || (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ tnr_dmd->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
+ tnr_dmd->state = CXD2880_TNRDMD_STATE_UNKNOWN;
+ tnr_dmd->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN;
+ tnr_dmd->frequency_khz = 0;
+ tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN;
+ tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN;
+ tnr_dmd->scan_mode = 0;
+ cxd2880_atomic_set(&tnr_dmd->cancel, 0);
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ tnr_dmd->diver_sub->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
+ tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_UNKNOWN;
+ tnr_dmd->diver_sub->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN;
+ tnr_dmd->diver_sub->frequency_khz = 0;
+ tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN;
+ tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN;
+ tnr_dmd->diver_sub->scan_mode = 0;
+ cxd2880_atomic_set(&tnr_dmd->diver_sub->cancel, 0);
+ }
+
+ ret = cxd2880_tnrdmd_chip_id(tnr_dmd, &tnr_dmd->chip_id);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->chip_id))
+ return CXD2880_RESULT_ERROR_NOSUPPORT;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret =
+ cxd2880_tnrdmd_chip_id(tnr_dmd->diver_sub,
+ &tnr_dmd->diver_sub->chip_id);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->diver_sub->chip_id))
+ return CXD2880_RESULT_ERROR_NOSUPPORT;
+ }
+
+ ret = p_init1(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = p_init1(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ CXD2880_SLEEP(1);
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = p_init2(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = p_init2(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ CXD2880_SLEEP(5);
+
+ ret = p_init3(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = p_init3(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = rf_init1(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = rf_init1(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ {
+ u8 cpu_task_completed = 0;
+
+ ret =
+ cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
+ &cpu_task_completed);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (!cpu_task_completed)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+ }
+
+ ret = rf_init2(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = rf_init2(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = load_cfg_mem(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = load_cfg_mem(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
+ tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP;
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ u8 *task_completed)
+{
+ u16 cpu_status = 0;
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if ((!tnr_dmd) || (!task_completed))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret = cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd, &cpu_status);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
+ if (cpu_status == 0)
+ *task_completed = 1;
+ else
+ *task_completed = 0;
+
+ return ret;
+ }
+ if (cpu_status != 0) {
+ *task_completed = 0;
+ return ret;
+ }
+
+ ret = cxd2880_tnrdmd_mon_internal_cpu_status_sub(tnr_dmd, &cpu_status);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (cpu_status == 0)
+ *task_completed = 1;
+ else
+ *task_completed = 0;
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u32 frequency_khz,
+ enum cxd2880_dtv_bandwidth
+ bandwidth, u8 one_seg_opt,
+ u8 one_seg_opt_shft_dir)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (frequency_khz < 4000)
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret = cxd2880_tnrdmd_sleep(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ {
+ u8 data = 0;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x2B, &data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ switch (sys) {
+ case CXD2880_DTV_SYS_DVBT:
+ case CXD2880_DTV_SYS_ISDBT:
+ case CXD2880_DTV_SYS_ISDBTSB:
+ case CXD2880_DTV_SYS_ISDBTMM_A:
+ case CXD2880_DTV_SYS_ISDBTMM_B:
+ if (data == 0x00) {
+ ret = t_power_x(tnr_dmd, 1);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode ==
+ CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = t_power_x(tnr_dmd->diver_sub, 1);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+ }
+ break;
+
+ case CXD2880_DTV_SYS_DVBT2:
+ if (data == 0x01) {
+ ret = t_power_x(tnr_dmd, 0);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode ==
+ CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = t_power_x(tnr_dmd->diver_sub, 0);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+ }
+ break;
+
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+ }
+
+ {
+ enum cxd2880_tnrdmd_clockmode new_clk_mode =
+ CXD2880_TNRDMD_CLOCKMODE_A;
+
+ ret = spll_reset(tnr_dmd, new_clk_mode);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ tnr_dmd->clk_mode = new_clk_mode;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = spll_reset(tnr_dmd->diver_sub, new_clk_mode);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ tnr_dmd->diver_sub->clk_mode = new_clk_mode;
+ }
+
+ ret = load_cfg_mem(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = load_cfg_mem(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+ }
+
+ {
+ int shift_frequency_khz = 0;
+
+ if (one_seg_opt) {
+ if (tnr_dmd->diver_mode ==
+ CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ shift_frequency_khz = 350;
+ } else {
+ if (one_seg_opt_shft_dir)
+ shift_frequency_khz = 350;
+ else
+ shift_frequency_khz = -350;
+
+ if (tnr_dmd->create_param.xtal_share_type ==
+ CXD2880_TNRDMD_XTAL_SHARE_SLAVE)
+ shift_frequency_khz *= -1;
+ }
+ } else {
+ if (tnr_dmd->diver_mode ==
+ CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ shift_frequency_khz = 150;
+ } else {
+ switch (tnr_dmd->create_param.xtal_share_type) {
+ case CXD2880_TNRDMD_XTAL_SHARE_NONE:
+ case CXD2880_TNRDMD_XTAL_SHARE_EXTREF:
+ default:
+ shift_frequency_khz = 0;
+ break;
+ case CXD2880_TNRDMD_XTAL_SHARE_MASTER:
+ shift_frequency_khz = 150;
+ break;
+ case CXD2880_TNRDMD_XTAL_SHARE_SLAVE:
+ shift_frequency_khz = -150;
+ break;
+ }
+ }
+ }
+
+ ret =
+ x_tune1(tnr_dmd, sys, frequency_khz, bandwidth,
+ tnr_dmd->is_cable_input, shift_frequency_khz);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret =
+ x_tune1(tnr_dmd->diver_sub, sys, frequency_khz,
+ bandwidth, tnr_dmd->is_cable_input,
+ -shift_frequency_khz);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ CXD2880_SLEEP(10);
+
+ {
+ u8 cpu_task_completed = 0;
+
+ ret =
+ cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
+ &cpu_task_completed);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (!cpu_task_completed)
+ return CXD2880_RESULT_ERROR_HW_STATE;
+ }
+
+ ret =
+ x_tune2(tnr_dmd, bandwidth, tnr_dmd->clk_mode,
+ shift_frequency_khz);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret =
+ x_tune2(tnr_dmd->diver_sub, bandwidth,
+ tnr_dmd->diver_sub->clk_mode,
+ -shift_frequency_khz);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+ }
+
+ if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS) {
+ ret = set_ts_clk_mode_and_freq(tnr_dmd, sys);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ } else {
+ struct cxd2880_tnrdmd_pid_ftr_cfg *pid_ftr_cfg;
+
+ if (tnr_dmd->pid_ftr_cfg_en)
+ pid_ftr_cfg = &tnr_dmd->pid_ftr_cfg;
+ else
+ pid_ftr_cfg = NULL;
+
+ ret = pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u8 en_fef_intmtnt_ctrl)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret = x_tune3(tnr_dmd, sys, en_fef_intmtnt_ctrl);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = x_tune3(tnr_dmd->diver_sub, sys, en_fef_intmtnt_ctrl);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = x_tune4(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 1);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->state == CXD2880_TNRDMD_STATE_SLEEP) {
+ } else if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE) {
+ ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 0);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = x_sleep1(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = x_sleep2(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = x_sleep2(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ switch (tnr_dmd->sys) {
+ case CXD2880_DTV_SYS_DVBT:
+ ret = cxd2880_tnrdmd_dvbt_sleep_setting(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_DTV_SYS_DVBT2:
+ ret = cxd2880_tnrdmd_dvbt2_sleep_setting(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ default:
+ return CXD2880_RESULT_ERROR_SW_STATE;
+ }
+
+ ret = x_sleep3(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = x_sleep3(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = x_sleep4(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ ret = x_sleep4(tnr_dmd->diver_sub);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP;
+ tnr_dmd->frequency_khz = 0;
+ tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN;
+ tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP;
+ tnr_dmd->diver_sub->frequency_khz = 0;
+ tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN;
+ tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN;
+ }
+ } else {
+ return CXD2880_RESULT_ERROR_SW_STATE;
+ }
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_tnrdmd_cfg_id id,
+ int value)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+ u8 data[2] = { 0 };
+ u8 need_sub_setting = 0;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ switch (id) {
+ case CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC4,
+ (u8)(value ? 0x00 :
+ 0x10), 0x10);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC5,
+ (u8)(value ? 0x00 :
+ 0x02), 0x02);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC5,
+ (u8)(value ? 0x00 :
+ 0x04), 0x04);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xCB,
+ (u8)(value ? 0x00 :
+ 0x01), 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC5,
+ (u8)(value ? 0x01 :
+ 0x00), 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSCLK_CONT:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ tnr_dmd->srl_ts_clk_mod_cnts = (u8)(value ? 0x01 : 0x00);
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSCLK_MASK:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if ((value < 0) || (value > 0x1F))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC6, (u8)value,
+ 0x1F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSVALID_MASK:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if ((value < 0) || (value > 0x1F))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC8, (u8)value,
+ 0x1F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSERR_MASK:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if ((value < 0) || (value > 0x1F))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xC9, (u8)value,
+ 0x1F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSERR_VALID_DIS:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x91,
+ (u8)(value ? 0x01 :
+ 0x00), 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSPIN_CURRENT:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x51, (u8)value,
+ 0x3F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x50,
+ (u8)(value ? 0x80 :
+ 0x00), 0x80);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSPIN_PULLUP:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x50, (u8)value,
+ 0x3F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSCLK_FREQ:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if ((value < 0) || (value > 1))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ tnr_dmd->srl_ts_clk_frq =
+ (enum cxd2880_tnrdmd_serial_ts_clk)value;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if ((value < 0) || (value > 0xFF))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ tnr_dmd->ts_byte_clk_manual_setting = (u8)value;
+
+ break;
+
+ case CXD2880_TNRDMD_CFG_TS_PACKET_GAP:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if ((value < 0) || (value > 7))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0xD6, (u8)value,
+ 0x07);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ break;
+
+ case CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE:
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ tnr_dmd->is_ts_backwards_compatible_mode = (u8)(value ? 1 : 0);
+
+ break;
+
+ case CXD2880_TNRDMD_CFG_PWM_VALUE:
+ if ((value < 0) || (value > 0x1000))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x22,
+ (u8)(value ? 0x01 :
+ 0x00), 0x01);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ {
+ u8 data[2];
+
+ data[0] = (u8)(((u16)value >> 8) & 0x1F);
+ data[1] = (u8)((u16)value & 0xFF);
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x23,
+ data[0], 0x1F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x24,
+ data[1], 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ break;
+
+ case CXD2880_TNRDMD_CFG_INTERRUPT:
+ data[0] = (u8)((value >> 8) & 0xFF);
+ data[1] = (u8)(value & 0xFF);
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x48, data[0],
+ 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x49, data[1],
+ 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL:
+ data[0] = (u8)(value & 0x07);
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x4A, data[0],
+ 0x07);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL:
+ data[0] = (u8)((value & 0x07) << 3);
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_SYS,
+ 0x00, 0x4A, data[0],
+ 0x38);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE:
+ if ((value < (int)CXD2880_TNRDMD_CLOCKMODE_UNKNOWN) ||
+ (value > (int)CXD2880_TNRDMD_CLOCKMODE_C))
+ return CXD2880_RESULT_ERROR_RANGE;
+ tnr_dmd->fixed_clk_mode = (enum cxd2880_tnrdmd_clockmode)value;
+ break;
+
+ case CXD2880_TNRDMD_CFG_CABLE_INPUT:
+ tnr_dmd->is_cable_input = (u8)(value ? 1 : 0);
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE:
+ tnr_dmd->en_fef_intmtnt_base = (u8)(value ? 1 : 0);
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE:
+ tnr_dmd->en_fef_intmtnt_lite = (u8)(value ? 1 : 0);
+ break;
+
+ case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS:
+ data[0] = (u8)((value >> 8) & 0x07);
+ data[1] = (u8)(value & 0xFF);
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x99, data[0],
+ 0x07);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x9A, data[1],
+ 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS:
+ data[0] = (u8)((value >> 8) & 0x07);
+ data[1] = (u8)(value & 0xFF);
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x9B, data[0],
+ 0x07);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x9C, data[1],
+ 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS:
+ data[0] = (u8)((value >> 8) & 0x07);
+ data[1] = (u8)(value & 0xFF);
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x9D, data[0],
+ 0x07);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x00, 0x9E, data[1],
+ 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST:
+ tnr_dmd->blind_tune_dvbt2_first = (u8)(value ? 1 : 0);
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD:
+ if ((value < 0) || (value > 31))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x10, 0x60,
+ (u8)(value & 0x1F),
+ 0x1F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD:
+ if ((value < 0) || (value > 7))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x10, 0x6F,
+ (u8)(value & 0x07),
+ 0x07);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT2_BBER_MES:
+ if ((value < 0) || (value > 15))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x20, 0x72,
+ (u8)(value & 0x0F),
+ 0x0F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT2_LBER_MES:
+ if ((value < 0) || (value > 15))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x20, 0x6F,
+ (u8)(value & 0x0F),
+ 0x0F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT_PER_MES:
+ if ((value < 0) || (value > 15))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x10, 0x5C,
+ (u8)(value & 0x0F),
+ 0x0F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_DVBT2_PER_MES:
+ if ((value < 0) || (value > 15))
+ return CXD2880_RESULT_ERROR_RANGE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x24, 0xDC,
+ (u8)(value & 0x0F),
+ 0x0F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ break;
+
+ case CXD2880_TNRDMD_CFG_ISDBT_BERPER_PERIOD:
+ {
+ u8 data[2];
+
+ data[0] = (u8)((value & 0x00007F00) >> 8);
+ data[1] = (u8)(value & 0x000000FF);
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x60, 0x5B,
+ data[0], 0x7F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
+ CXD2880_IO_TGT_DMD,
+ 0x60, 0x5C,
+ data[1], 0xFF);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+ break;
+
+ default:
+ return CXD2880_RESULT_ERROR_ARG;
+ }
+
+ if (need_sub_setting &&
+ (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)) {
+ ret = cxd2880_tnrdmd_set_cfg(tnr_dmd->diver_sub, id, value);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id,
+ u8 en,
+ enum cxd2880_tnrdmd_gpio_mode mode,
+ u8 open_drain, u8 invert)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (id > 2)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (mode > CXD2880_TNRDMD_GPIO_MODE_EEW)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
+ 0x00, 0x40 + id, (u8)mode,
+ 0x0F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
+ 0x00, 0x43,
+ (u8)(open_drain ? (1 << id) :
+ 0), (u8)(1 << id));
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
+ 0x00, 0x44,
+ (u8)(invert ? (1 << id) : 0),
+ (u8)(1 << id));
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
+ 0x00, 0x45,
+ (u8)(en ? 0 : (1 << id)),
+ (u8)(1 << id));
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id,
+ u8 en,
+ enum cxd2880_tnrdmd_gpio_mode
+ mode, u8 open_drain, u8 invert)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret =
+ cxd2880_tnrdmd_gpio_set_cfg(tnr_dmd->diver_sub, id, en, mode,
+ open_drain, invert);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 *value)
+{
+ u8 data = 0;
+
+ if ((!tnr_dmd) || (!value))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (id > 2)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x20, &data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ *value = (u8)((data >> id) & 0x01);
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 *value)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret = cxd2880_tnrdmd_gpio_read(tnr_dmd->diver_sub, id, value);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 value)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (id > 2)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ ret =
+ cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
+ 0x00, 0x46,
+ (u8)(value ? (1 << id) : 0),
+ (u8)(1 << id));
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 value)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret = cxd2880_tnrdmd_gpio_write(tnr_dmd->diver_sub, id, value);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
+ u16 *value)
+{
+ u8 data[2] = { 0 };
+
+ if ((!tnr_dmd) || (!value))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x15, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ *value = (u16)(((u16)data[0] << 8) | (data[1]));
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
+ u16 value)
+{
+ u8 data[2] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = (u8)((value >> 8) & 0xFF);
+ data[1] = (u8)(value & 0xFF);
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x3C, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 clear_overflow_flag,
+ u8 clear_underflow_flag,
+ u8 clear_buf)
+{
+ u8 data[2] = { 0 };
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ data[0] = (u8)(clear_overflow_flag ? 0x02 : 0x00);
+ data[0] |= (u8)(clear_underflow_flag ? 0x01 : 0x00);
+ data[1] = (u8)(clear_buf ? 0x01 : 0x00);
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x9F, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_tnrdmd_chip_id *chip_id)
+{
+ u8 data = 0;
+
+ if ((!tnr_dmd) || (!chip_id))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0xFD, &data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ *chip_id = (enum cxd2880_tnrdmd_chip_id)data;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum cxd2880_io_tgt tgt,
+ u8 bank, u8 address,
+ u8 value, u8 bit_mask)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ tgt, 0x00, bank) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (cxd2880_io_set_reg_bits(tnr_dmd->io, tgt, address, value, bit_mask)
+ != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ ret = set_cfg_mem(tnr_dmd, tgt, bank, address, value, bit_mask);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u8 scan_mode_end)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ CXD2880_ARG_UNUSED(sys);
+
+ tnr_dmd->scan_mode = scan_mode_end;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ ret =
+ cxd2880_tnrdmd_set_scan_mode(tnr_dmd->diver_sub, sys,
+ scan_mode_end);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
+ struct cxd2880_tnrdmd_pid_ftr_cfg
+ *pid_ftr_cfg)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS)
+ return CXD2880_RESULT_ERROR_NOSUPPORT;
+
+ if (pid_ftr_cfg) {
+ tnr_dmd->pid_ftr_cfg = *pid_ftr_cfg;
+ tnr_dmd->pid_ftr_cfg_en = 1;
+ } else {
+ tnr_dmd->pid_ftr_cfg_en = 0;
+ }
+
+ if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE) {
+ ret = pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum
+ cxd2880_ret(*rf_lvl_cmpstn)
+ (struct cxd2880_tnrdmd *,
+ int *))
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ tnr_dmd->rf_lvl_cmpstn = rf_lvl_cmpstn;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum
+ cxd2880_ret
+ (*rf_lvl_cmpstn)(struct
+ cxd2880_tnrdmd
+ *,
+ int *))
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret =
+ cxd2880_tnrdmd_set_rf_lvl_cmpstn(tnr_dmd->diver_sub, rf_lvl_cmpstn);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_air
+ *tbl_air,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_cable
+ *tbl_cable)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ tnr_dmd->lna_thrs_tbl_air = tbl_air;
+ tnr_dmd->lna_thrs_tbl_cable = tbl_cable;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_air
+ *tbl_air,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_cable
+ *tbl_cable)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret =
+ cxd2880_tnrdmd_set_lna_thrs(tnr_dmd->diver_sub, tbl_air, tbl_cable);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
+ *tnr_dmd, u8 en, u8 value)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->create_param.ts_output_if != CXD2880_TNRDMD_TSOUT_IF_TS)
+ return CXD2880_RESULT_ERROR_NOSUPPORT;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (en) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x50,
+ ((value & 0x1F) | 0x80)) !=
+ CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x52,
+ (value & 0x1F)) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ } else {
+ ret = tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x50, 0x3F);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x52,
+ 0x1F) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ ret = load_cfg_mem(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 en)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ switch (tnr_dmd->create_param.ts_output_if) {
+ case CXD2880_TNRDMD_TSOUT_IF_TS:
+ if (en) {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x52,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xC3,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ } else {
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0xC3,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x52,
+ 0x1F) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+ break;
+
+ case CXD2880_TNRDMD_TSOUT_IF_SPI:
+ break;
+
+ case CXD2880_TNRDMD_TSOUT_IF_SDIO:
+ break;
+
+ default:
+ return CXD2880_RESULT_ERROR_SW_STATE;
+ }
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ switch (tnr_dmd->create_param.ts_output_if) {
+ case CXD2880_TNRDMD_TSOUT_IF_SPI:
+ case CXD2880_TNRDMD_TSOUT_IF_SDIO:
+ {
+ u8 data = 0;
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ &data,
+ 1) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+ break;
+ case CXD2880_TNRDMD_TSOUT_IF_TS:
+ default:
+ break;
+ }
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x01,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ return ret;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h
new file mode 100644
index 000000000000..26e29b3b9f6b
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h
@@ -0,0 +1,395 @@
+/*
+ * cxd2880_tnrdmd.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common control interface
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_TNRDMD_H
+#define CXD2880_TNRDMD_H
+
+#include "cxd2880_common.h"
+#include "cxd2880_io.h"
+#include "cxd2880_dtv.h"
+#include "cxd2880_dvbt.h"
+#include "cxd2880_dvbt2.h"
+
+#define CXD2880_TNRDMD_MAX_CFG_MEM_COUNT 100
+
+#define slvt_unfreeze_reg(tnr_dmd) ((void)((tnr_dmd)->io->write_reg\
+((tnr_dmd)->io, CXD2880_IO_TGT_DMD, 0x01, 0x00)))
+
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_UNDERFLOW 0x0001
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_OVERFLOW 0x0002
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_EMPTY 0x0004
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_FULL 0x0008
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_RRDY 0x0010
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_COMMAND 0x0020
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_ACCESS 0x0040
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_CPU_ERROR 0x0100
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_LOCK 0x0200
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_INV_LOCK 0x0400
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_NOOFDM 0x0800
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_EWS 0x1000
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_EEW 0x2000
+#define CXD2880_TNRDMD_INTERRUPT_TYPE_FEC_FAIL 0x4000
+
+#define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_L1POST_OK 0x01
+#define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_DMD_LOCK 0x02
+#define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_TS_LOCK 0x04
+
+enum cxd2880_tnrdmd_chip_id {
+ CXD2880_TNRDMD_CHIP_ID_UNKNOWN = 0x00,
+ CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X = 0x62,
+ CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11 = 0x6A
+};
+
+#define CXD2880_TNRDMD_CHIP_ID_VALID(chip_id) (((chip_id) == \
+CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) || \
+((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11))
+
+enum cxd2880_tnrdmd_state {
+ CXD2880_TNRDMD_STATE_UNKNOWN,
+ CXD2880_TNRDMD_STATE_SLEEP,
+ CXD2880_TNRDMD_STATE_ACTIVE,
+ CXD2880_TNRDMD_STATE_INVALID
+};
+
+enum cxd2880_tnrdmd_divermode {
+ CXD2880_TNRDMD_DIVERMODE_SINGLE,
+ CXD2880_TNRDMD_DIVERMODE_MAIN,
+ CXD2880_TNRDMD_DIVERMODE_SUB
+};
+
+enum cxd2880_tnrdmd_clockmode {
+ CXD2880_TNRDMD_CLOCKMODE_UNKNOWN,
+ CXD2880_TNRDMD_CLOCKMODE_A,
+ CXD2880_TNRDMD_CLOCKMODE_B,
+ CXD2880_TNRDMD_CLOCKMODE_C
+};
+
+enum cxd2880_tnrdmd_tsout_if {
+ CXD2880_TNRDMD_TSOUT_IF_TS,
+ CXD2880_TNRDMD_TSOUT_IF_SPI,
+ CXD2880_TNRDMD_TSOUT_IF_SDIO
+};
+
+enum cxd2880_tnrdmd_xtal_share {
+ CXD2880_TNRDMD_XTAL_SHARE_NONE,
+ CXD2880_TNRDMD_XTAL_SHARE_EXTREF,
+ CXD2880_TNRDMD_XTAL_SHARE_MASTER,
+ CXD2880_TNRDMD_XTAL_SHARE_SLAVE
+};
+
+enum cxd2880_tnrdmd_spectrum_sense {
+ CXD2880_TNRDMD_SPECTRUM_NORMAL,
+ CXD2880_TNRDMD_SPECTRUM_INV
+};
+
+enum cxd2880_tnrdmd_cfg_id {
+ CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB,
+ CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI,
+ CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI,
+ CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI,
+ CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE,
+ CXD2880_TNRDMD_CFG_TSCLK_CONT,
+ CXD2880_TNRDMD_CFG_TSCLK_MASK,
+ CXD2880_TNRDMD_CFG_TSVALID_MASK,
+ CXD2880_TNRDMD_CFG_TSERR_MASK,
+ CXD2880_TNRDMD_CFG_TSERR_VALID_DIS,
+ CXD2880_TNRDMD_CFG_TSPIN_CURRENT,
+ CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL,
+ CXD2880_TNRDMD_CFG_TSPIN_PULLUP,
+ CXD2880_TNRDMD_CFG_TSCLK_FREQ,
+ CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL,
+ CXD2880_TNRDMD_CFG_TS_PACKET_GAP,
+ CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE,
+ CXD2880_TNRDMD_CFG_PWM_VALUE,
+ CXD2880_TNRDMD_CFG_INTERRUPT,
+ CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL,
+ CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL,
+ CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS,
+ CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS,
+ CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS,
+ CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE,
+ CXD2880_TNRDMD_CFG_CABLE_INPUT,
+ CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE,
+ CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE,
+ CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST,
+ CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD,
+ CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD,
+ CXD2880_TNRDMD_CFG_DVBT_PER_MES,
+ CXD2880_TNRDMD_CFG_DVBT2_BBER_MES,
+ CXD2880_TNRDMD_CFG_DVBT2_LBER_MES,
+ CXD2880_TNRDMD_CFG_DVBT2_PER_MES,
+ CXD2880_TNRDMD_CFG_ISDBT_BERPER_PERIOD
+};
+
+enum cxd2880_tnrdmd_lock_result {
+ CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT,
+ CXD2880_TNRDMD_LOCK_RESULT_LOCKED,
+ CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
+};
+
+enum cxd2880_tnrdmd_gpio_mode {
+ CXD2880_TNRDMD_GPIO_MODE_OUTPUT = 0x00,
+ CXD2880_TNRDMD_GPIO_MODE_INPUT = 0x01,
+ CXD2880_TNRDMD_GPIO_MODE_INT = 0x02,
+ CXD2880_TNRDMD_GPIO_MODE_FEC_FAIL = 0x03,
+ CXD2880_TNRDMD_GPIO_MODE_PWM = 0x04,
+ CXD2880_TNRDMD_GPIO_MODE_EWS = 0x05,
+ CXD2880_TNRDMD_GPIO_MODE_EEW = 0x06
+};
+
+enum cxd2880_tnrdmd_serial_ts_clk {
+ CXD2880_TNRDMD_SERIAL_TS_CLK_FULL,
+ CXD2880_TNRDMD_SERIAL_TS_CLK_HALF
+};
+
+struct cxd2880_tnrdmd_cfg_mem {
+ enum cxd2880_io_tgt tgt;
+ u8 bank;
+ u8 address;
+ u8 value;
+ u8 bit_mask;
+};
+
+struct cxd2880_tnrdmd_pid_cfg {
+ u8 is_en;
+ u16 pid;
+};
+
+struct cxd2880_tnrdmd_pid_ftr_cfg {
+ u8 is_negative;
+ struct cxd2880_tnrdmd_pid_cfg pid_cfg[32];
+};
+
+struct cxd2880_tnrdmd_ts_buf_info {
+ u8 read_ready;
+ u8 almost_full;
+ u8 almost_empty;
+ u8 overflow;
+ u8 underflow;
+ u16 packet_num;
+};
+
+struct cxd2880_tnrdmd_lna_thrs {
+ u8 off_on;
+ u8 on_off;
+};
+
+struct cxd2880_tnrdmd_lna_thrs_tbl_air {
+ struct cxd2880_tnrdmd_lna_thrs thrs[24];
+};
+
+struct cxd2880_tnrdmd_lna_thrs_tbl_cable {
+ struct cxd2880_tnrdmd_lna_thrs thrs[32];
+};
+
+struct cxd2880_tnrdmd_create_param {
+ enum cxd2880_tnrdmd_tsout_if ts_output_if;
+ u8 en_internal_ldo;
+ enum cxd2880_tnrdmd_xtal_share xtal_share_type;
+ u8 xosc_cap;
+ u8 xosc_i;
+ u8 is_cxd2881gg;
+ u8 stationary_use;
+};
+
+struct cxd2880_tnrdmd_diver_create_param {
+ enum cxd2880_tnrdmd_tsout_if ts_output_if;
+ u8 en_internal_ldo;
+ u8 xosc_cap_main;
+ u8 xosc_i_main;
+ u8 xosc_i_sub;
+ u8 is_cxd2881gg;
+ u8 stationary_use;
+};
+
+struct cxd2880_tnrdmd {
+ struct cxd2880_tnrdmd *diver_sub;
+ struct cxd2880_io *io;
+ struct cxd2880_tnrdmd_create_param create_param;
+ enum cxd2880_tnrdmd_divermode diver_mode;
+ enum cxd2880_tnrdmd_clockmode fixed_clk_mode;
+ u8 is_cable_input;
+ u8 en_fef_intmtnt_base;
+ u8 en_fef_intmtnt_lite;
+ u8 blind_tune_dvbt2_first;
+ enum cxd2880_ret (*rf_lvl_cmpstn)(struct cxd2880_tnrdmd *tnr_dmd,
+ int *rf_lvl_db);
+ struct cxd2880_tnrdmd_lna_thrs_tbl_air *lna_thrs_tbl_air;
+ struct cxd2880_tnrdmd_lna_thrs_tbl_cable *lna_thrs_tbl_cable;
+ u8 srl_ts_clk_mod_cnts;
+ enum cxd2880_tnrdmd_serial_ts_clk srl_ts_clk_frq;
+ u8 ts_byte_clk_manual_setting;
+ u8 is_ts_backwards_compatible_mode;
+ struct cxd2880_tnrdmd_cfg_mem cfg_mem[CXD2880_TNRDMD_MAX_CFG_MEM_COUNT];
+ u8 cfg_mem_last_entry;
+ struct cxd2880_tnrdmd_pid_ftr_cfg pid_ftr_cfg;
+ u8 pid_ftr_cfg_en;
+ void *user;
+ enum cxd2880_tnrdmd_chip_id chip_id;
+ enum cxd2880_tnrdmd_state state;
+ enum cxd2880_tnrdmd_clockmode clk_mode;
+ u32 frequency_khz;
+ enum cxd2880_dtv_sys sys;
+ enum cxd2880_dtv_bandwidth bandwidth;
+ u8 scan_mode;
+ struct cxd2880_atomic cancel;
+};
+
+enum cxd2880_ret cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
+ struct cxd2880_io *io,
+ struct cxd2880_tnrdmd_create_param
+ *create_param);
+
+enum cxd2880_ret cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd
+ *tnr_dmd_main,
+ struct cxd2880_io *io_main,
+ struct cxd2880_tnrdmd *tnr_dmd_sub,
+ struct cxd2880_io *io_sub,
+ struct
+ cxd2880_tnrdmd_diver_create_param
+ *create_param);
+
+enum cxd2880_ret cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd);
+
+enum cxd2880_ret cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd);
+
+enum cxd2880_ret cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ u8 *task_completed);
+
+enum cxd2880_ret cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u32 frequency_khz,
+ enum cxd2880_dtv_bandwidth
+ bandwidth, u8 one_seg_opt,
+ u8 one_seg_opt_shft_dir);
+
+enum cxd2880_ret cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u8 en_fef_intmtnt_ctrl);
+
+enum cxd2880_ret cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_tnrdmd_cfg_id id,
+ int value);
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id,
+ u8 en,
+ enum cxd2880_tnrdmd_gpio_mode mode,
+ u8 open_drain, u8 invert);
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id,
+ u8 en,
+ enum cxd2880_tnrdmd_gpio_mode
+ mode, u8 open_drain,
+ u8 invert);
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 *value);
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 *value);
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 value);
+
+enum cxd2880_ret cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 id, u8 value);
+
+enum cxd2880_ret cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
+ u16 *value);
+
+enum cxd2880_ret cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
+ u16 value);
+
+enum cxd2880_ret cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 clear_overflow_flag,
+ u8 clear_underflow_flag,
+ u8 clear_buf);
+
+enum cxd2880_ret cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_tnrdmd_chip_id *chip_id);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum cxd2880_io_tgt tgt,
+ u8 bank, u8 address,
+ u8 value, u8 bit_mask);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dtv_sys sys,
+ u8 scan_mode_end);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
+ struct cxd2880_tnrdmd_pid_ftr_cfg
+ *pid_ftr_cfg);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum
+ cxd2880_ret(*rf_lvl_cmpstn)
+ (struct cxd2880_tnrdmd *,
+ int *));
+
+enum cxd2880_ret cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd
+ *tnr_dmd,
+ enum
+ cxd2880_ret
+ (*rf_lvl_cmpstn)(struct
+ cxd2880_tnrdmd
+ *,
+ int *));
+
+enum cxd2880_ret cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_air
+ *tbl_air,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_cable
+ *tbl_cable);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_air
+ *tbl_air,
+ struct
+ cxd2880_tnrdmd_lna_thrs_tbl_cable
+ *tbl_cable);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
+ *tnr_dmd, u8 en, u8 value);
+
+enum cxd2880_ret cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
+ u8 en);
+
+enum cxd2880_ret slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd);
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h
new file mode 100644
index 000000000000..68fb3af04bd4
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h
@@ -0,0 +1,29 @@
+/*
+ * cxd2880_tnrdmd_driver_version.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * version information
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define CXD2880_TNRDMD_DRIVER_VERSION "1.4.1 - 1.0.1"
+
+#define CXD2880_TNRDMD_DRIVER_RELEASE_DATE "2017-04-13"
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c
new file mode 100644
index 000000000000..0ac5b9bf3be8
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c
@@ -0,0 +1,207 @@
+/*
+ * cxd2880_tnrdmd_mon.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common monitor functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_common.h"
+#include "cxd2880_tnrdmd_mon.h"
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_rf_lvl(struct cxd2880_tnrdmd *tnr_dmd,
+ int *rf_lvl_db)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if ((!tnr_dmd) || (!rf_lvl_db))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x01) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x10) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ {
+ u8 data[2] = { 0x80, 0x00 };
+
+ if (tnr_dmd->io->write_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x5B, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ }
+
+ CXD2880_SLEEP_IN_MON(2, tnr_dmd);
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x1A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ {
+ u8 data[2];
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x15, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if ((data[0] != 0) || (data[1] != 0))
+ return CXD2880_RESULT_ERROR_OTHER;
+
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x11, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ *rf_lvl_db =
+ cxd2880_convert2s_complement((data[0] << 3) |
+ ((data[1] & 0xE0) >> 5), 11);
+ }
+
+ *rf_lvl_db *= 125;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x10,
+ 0x00) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ if (tnr_dmd->rf_lvl_cmpstn) {
+ ret = tnr_dmd->rf_lvl_cmpstn(tnr_dmd, rf_lvl_db);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_rf_lvl_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ int *rf_lvl_db)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if ((!tnr_dmd) || (!rf_lvl_db))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret = cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd->diver_sub, rf_lvl_db);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_internal_cpu_status(struct cxd2880_tnrdmd
+ *tnr_dmd, u16 *status)
+{
+ u8 data[2] = { 0 };
+
+ if ((!tnr_dmd) || (!status))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x00,
+ 0x1A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_SYS, 0x15, data,
+ 2) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ *status = (u16)(((u16)data[0] << 8) | data[1]);
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_internal_cpu_status_sub(struct
+ cxd2880_tnrdmd
+ *tnr_dmd,
+ u16 *status)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if ((!tnr_dmd) || (!status))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret =
+ cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd->diver_sub, status);
+
+ return ret;
+}
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_ts_buf_info(struct cxd2880_tnrdmd *tnr_dmd,
+ struct
+ cxd2880_tnrdmd_ts_buf_info
+ *info)
+{
+ u8 data[3] = { 0 };
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+ if ((!tnr_dmd) || (!info))
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+ (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+ return CXD2880_RESULT_ERROR_SW_STATE;
+
+ if (tnr_dmd->io->write_reg(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x00,
+ 0x0A) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+ if (tnr_dmd->io->read_regs(tnr_dmd->io,
+ CXD2880_IO_TGT_DMD, 0x50, data,
+ 3) != CXD2880_RESULT_OK)
+ return CXD2880_RESULT_ERROR_IO;
+
+ info->read_ready = (u8)((data[0] & 0x10) ? 0x01 : 0x00);
+ info->almost_full = (u8)((data[0] & 0x08) ? 0x01 : 0x00);
+ info->almost_empty = (u8)((data[0] & 0x04) ? 0x01 : 0x00);
+ info->overflow = (u8)((data[0] & 0x02) ? 0x01 : 0x00);
+ info->underflow = (u8)((data[0] & 0x01) ? 0x01 : 0x00);
+
+ info->packet_num = (u16)(((u32)(data[1] & 0x07) << 8) | data[2]);
+
+ return ret;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h
new file mode 100644
index 000000000000..506bd559668f
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h
@@ -0,0 +1,52 @@
+/*
+ * cxd2880_tnrdmd_mon.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common monitor interface
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_TNRDMD_MON_H
+#define CXD2880_TNRDMD_MON_H
+
+#include "cxd2880_common.h"
+#include "cxd2880_tnrdmd.h"
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_rf_lvl(struct cxd2880_tnrdmd *tnr_dmd,
+ int *rf_lvl_db);
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_rf_lvl_sub(struct cxd2880_tnrdmd *tnr_dmd,
+ int *rf_lvl_db);
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_internal_cpu_status(struct cxd2880_tnrdmd
+ *tnr_dmd, u16 *status);
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_internal_cpu_status_sub(struct
+ cxd2880_tnrdmd
+ *tnr_dmd,
+ u16 *status);
+
+enum cxd2880_ret cxd2880_tnrdmd_mon_ts_buf_info(struct cxd2880_tnrdmd *tnr_dmd,
+ struct
+ cxd2880_tnrdmd_ts_buf_info
+ *info);
+
+#endif
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 07/15] [media] cxd2880: Add integration layer for the driver
From: Yasunari.Takiguchi @ 2017-04-14 2:29 UTC (permalink / raw)
To: linux-kernel, devicetree, linux-media
Cc: tbird20d, frowand.list, Yasunari Takiguchi, Masayuki Yamamoto,
Hideki Nozawa, Kota Yonezawa, Toshihiko Matsumoto,
Satoshi Watanabe
In-Reply-To: <20170414015043.16731-1-Yasunari.Takiguchi@sony.com>
From: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com>
These functions monitor the driver and watch for task completion.
This is part of the Sony CXD2880 DVB-T2/T tuner + demodulator driver.
Signed-off-by: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com>
Signed-off-by: Masayuki Yamamoto <Masayuki.Yamamoto@sony.com>
Signed-off-by: Hideki Nozawa <Hideki.Nozawa@sony.com>
Signed-off-by: Kota Yonezawa <Kota.Yonezawa@sony.com>
Signed-off-by: Toshihiko Matsumoto <Toshihiko.Matsumoto@sony.com>
Signed-off-by: Satoshi Watanabe <Satoshi.C.Watanabe@sony.com>
---
.../media/dvb-frontends/cxd2880/cxd2880_integ.c | 99 ++++++++++++++++++++++
.../media/dvb-frontends/cxd2880/cxd2880_integ.h | 44 ++++++++++
2 files changed, 143 insertions(+)
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
new file mode 100644
index 000000000000..5ad6685e2a1d
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
@@ -0,0 +1,99 @@
+/*
+ * cxd2880_integ.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * integration layer common functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cxd2880_tnrdmd.h"
+#include "cxd2880_tnrdmd_mon.h"
+#include "cxd2880_integ.h"
+
+enum cxd2880_ret cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ enum cxd2880_ret ret = CXD2880_RESULT_OK;
+ struct cxd2880_stopwatch timer;
+ u32 elapsed_time = 0;
+ u8 cpu_task_completed = 0;
+
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ ret = cxd2880_tnrdmd_init1(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret = cxd2880_stopwatch_start(&timer);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ while (1) {
+ ret = cxd2880_stopwatch_elapsed(&timer, &elapsed_time);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ ret =
+ cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
+ &cpu_task_completed);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ if (cpu_task_completed)
+ break;
+
+ if (elapsed_time > CXD2880_TNRDMD_WAIT_INIT_TIMEOUT)
+ return CXD2880_RESULT_ERROR_TIMEOUT;
+ ret =
+ cxd2880_stopwatch_sleep(&timer,
+ CXD2880_TNRDMD_WAIT_INIT_INTVL);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+ }
+
+ ret = cxd2880_tnrdmd_init2(tnr_dmd);
+ if (ret != CXD2880_RESULT_OK)
+ return ret;
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ cxd2880_atomic_set(&tnr_dmd->cancel, 1);
+
+ return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd
+ *tnr_dmd)
+{
+ if (!tnr_dmd)
+ return CXD2880_RESULT_ERROR_ARG;
+
+ if (cxd2880_atomic_read(&tnr_dmd->cancel) != 0)
+ return CXD2880_RESULT_ERROR_CANCEL;
+
+ return CXD2880_RESULT_OK;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h
new file mode 100644
index 000000000000..9cfc52dbf9d4
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h
@@ -0,0 +1,44 @@
+/*
+ * cxd2880_integ.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * integration layer common interface
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * 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; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CXD2880_INTEG_H
+#define CXD2880_INTEG_H
+
+#include "cxd2880_tnrdmd.h"
+
+#define CXD2880_TNRDMD_WAIT_INIT_TIMEOUT 500
+#define CXD2880_TNRDMD_WAIT_INIT_INTVL 10
+
+#define CXD2880_TNRDMD_WAIT_AGC_STABLE 100
+
+enum cxd2880_ret cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd);
+
+enum cxd2880_ret cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd);
+
+enum cxd2880_ret cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd
+ *tnr_dmd);
+
+#endif
--
2.11.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox