diff mbox series

[28/40] mfd: ti_am335x_tscadc: Add ADC1/magnetic reader support

Message ID 20210825152518.379386-29-miquel.raynal@bootlin.com
State New
Headers show
Series TI AM437X ADC1 | expand

Commit Message

Miquel Raynal Aug. 25, 2021, 3:25 p.m. UTC
Introduce a new compatible that has another set of driver data,
targeting am437x SoCs with a magnetic reader instead of the
touchscreen and a more featureful set of registers.

Co-developed-by: Jason Reeder <jreeder@ti.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Jason Reeder <jreeder@ti.com>
---
 drivers/mfd/ti_am335x_tscadc.c       | 43 ++++++++++++++++++++++------
 include/linux/mfd/ti_am335x_tscadc.h |  9 +++++-
 2 files changed, 43 insertions(+), 9 deletions(-)

Comments

Grygorii Strashko Sept. 1, 2021, 7:26 p.m. UTC | #1
On 25/08/2021 18:25, Miquel Raynal wrote:
> Introduce a new compatible that has another set of driver data,

> targeting am437x SoCs with a magnetic reader instead of the

> touchscreen and a more featureful set of registers.

> 

> Co-developed-by: Jason Reeder <jreeder@ti.com>

> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

> Signed-off-by: Jason Reeder <jreeder@ti.com>

> ---

>   drivers/mfd/ti_am335x_tscadc.c       | 43 ++++++++++++++++++++++------

>   include/linux/mfd/ti_am335x_tscadc.h |  9 +++++-

>   2 files changed, 43 insertions(+), 9 deletions(-)

> 

> diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c

> index 1a30610dc65f..f4f6b9db4d2a 100644

> --- a/drivers/mfd/ti_am335x_tscadc.c

> +++ b/drivers/mfd/ti_am335x_tscadc.c

> @@ -122,9 +122,9 @@ static	int ti_tscadc_probe(struct platform_device *pdev)

>   	const __be32 *cur;

>   	struct clk *clk;

>   	u32 val;

> -	bool use_tsc = false;

> +	bool use_tsc = false, use_mag = false;

>   	int tscmag_wires = 0, adc_channels = 0, readouts = 0, cell_idx = 0;

> -	int total_channels, err;

> +	int mag_tracks = 0, total_channels, err;

>   

>   	/* Allocate memory for device */

>   	tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);

> @@ -146,6 +146,12 @@ static	int ti_tscadc_probe(struct platform_device *pdev)

>   		of_property_read_u32(node, "ti,coordiante-readouts", &readouts);

>   		if (tscmag_wires)

>   			use_tsc = true;

> +	} else {

> +		node = of_get_child_by_name(pdev->dev.of_node, "mag");

> +		of_property_read_u32(node, "ti,tracks", &mag_tracks);


"ti,tracks" seems undocumented?

[....]

-- 
Best regards,
grygorii
Miquel Raynal Sept. 2, 2021, 6:47 a.m. UTC | #2
Hi Grygorii,

Grygorii Strashko <grygorii.strashko@ti.com> wrote on Wed, 1 Sep 2021
22:26:25 +0300:

> On 25/08/2021 18:25, Miquel Raynal wrote:
> > Introduce a new compatible that has another set of driver data,
> > targeting am437x SoCs with a magnetic reader instead of the
> > touchscreen and a more featureful set of registers.
> > 
> > Co-developed-by: Jason Reeder <jreeder@ti.com>
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > Signed-off-by: Jason Reeder <jreeder@ti.com>
> > ---
> >   drivers/mfd/ti_am335x_tscadc.c       | 43 ++++++++++++++++++++++------
> >   include/linux/mfd/ti_am335x_tscadc.h |  9 +++++-
> >   2 files changed, 43 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
> > index 1a30610dc65f..f4f6b9db4d2a 100644
> > --- a/drivers/mfd/ti_am335x_tscadc.c
> > +++ b/drivers/mfd/ti_am335x_tscadc.c
> > @@ -122,9 +122,9 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
> >   	const __be32 *cur;
> >   	struct clk *clk;
> >   	u32 val;
> > -	bool use_tsc = false;
> > +	bool use_tsc = false, use_mag = false;
> >   	int tscmag_wires = 0, adc_channels = 0, readouts = 0, cell_idx = 0;
> > -	int total_channels, err;
> > +	int mag_tracks = 0, total_channels, err;  
> >   >   	/* Allocate memory for device */  
> >   	tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
> > @@ -146,6 +146,12 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
> >   		of_property_read_u32(node, "ti,coordiante-readouts", &readouts);
> >   		if (tscmag_wires)
> >   			use_tsc = true;
> > +	} else {
> > +		node = of_get_child_by_name(pdev->dev.of_node, "mag");
> > +		of_property_read_u32(node, "ti,tracks", &mag_tracks);  
> 
> "ti,tracks" seems undocumented?

Well that's true and almost on purpose, I am not focusing on the
magnetic reader feature, it is not supported, I don't have one, I don't
plan to add support for it. But in the driver I need to know how many
"tracks" are unavailable for the ADC in order to implement the entire
logic (this block comes from TI and the naming from Jason Reeder).

I am not comfortable writing a binding file for a device that I won't
use, it's the best way to miss something and have stable broken
bindings in the future. So I assumed it was not a big deal to have this
property in the code, which may be updated/removed/enhanced later if
needed without having to mess with the code too much. What do you think?

Thanks,
Miquèl
Grygorii Strashko Sept. 2, 2021, 9:57 a.m. UTC | #3
On 02/09/2021 09:47, Miquel Raynal wrote:
> Hi Grygorii,
> 
> Grygorii Strashko <grygorii.strashko@ti.com> wrote on Wed, 1 Sep 2021
> 22:26:25 +0300:
> 
>> On 25/08/2021 18:25, Miquel Raynal wrote:
>>> Introduce a new compatible that has another set of driver data,
>>> targeting am437x SoCs with a magnetic reader instead of the
>>> touchscreen and a more featureful set of registers.
>>>
>>> Co-developed-by: Jason Reeder <jreeder@ti.com>
>>> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
>>> Signed-off-by: Jason Reeder <jreeder@ti.com>
>>> ---
>>>    drivers/mfd/ti_am335x_tscadc.c       | 43 ++++++++++++++++++++++------
>>>    include/linux/mfd/ti_am335x_tscadc.h |  9 +++++-
>>>    2 files changed, 43 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
>>> index 1a30610dc65f..f4f6b9db4d2a 100644
>>> --- a/drivers/mfd/ti_am335x_tscadc.c
>>> +++ b/drivers/mfd/ti_am335x_tscadc.c
>>> @@ -122,9 +122,9 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
>>>    	const __be32 *cur;
>>>    	struct clk *clk;
>>>    	u32 val;
>>> -	bool use_tsc = false;
>>> +	bool use_tsc = false, use_mag = false;
>>>    	int tscmag_wires = 0, adc_channels = 0, readouts = 0, cell_idx = 0;
>>> -	int total_channels, err;
>>> +	int mag_tracks = 0, total_channels, err;
>>>    >   	/* Allocate memory for device */
>>>    	tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
>>> @@ -146,6 +146,12 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
>>>    		of_property_read_u32(node, "ti,coordiante-readouts", &readouts);
>>>    		if (tscmag_wires)
>>>    			use_tsc = true;
>>> +	} else {
>>> +		node = of_get_child_by_name(pdev->dev.of_node, "mag");
>>> +		of_property_read_u32(node, "ti,tracks", &mag_tracks);
>>
>> "ti,tracks" seems undocumented?
> 
> Well that's true and almost on purpose, I am not focusing on the
> magnetic reader feature, it is not supported, I don't have one, I don't
> plan to add support for it. But in the driver I need to know how many
> "tracks" are unavailable for the ADC in order to implement the entire
> logic (this block comes from TI and the naming from Jason Reeder).
> 
> I am not comfortable writing a binding file for a device that I won't
> use, it's the best way to miss something and have stable broken
> bindings in the future. So I assumed it was not a big deal to have this
> property in the code, which may be updated/removed/enhanced later if
> needed without having to mess with the code too much. What do you think?

Sry, it's not ok.
You need to (a) add binding or (b) w/a it in some way -
like drop it and use const value instead, for example.
Miquel Raynal Sept. 2, 2021, 6:31 p.m. UTC | #4
Hi Jonathan,

Jonathan Cameron <jic23@kernel.org> wrote on Mon, 30 Aug 2021 15:10:10
+0100:

> On Wed, 25 Aug 2021 17:25:06 +0200
> Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> 
> > Introduce a new compatible that has another set of driver data,
> > targeting am437x SoCs with a magnetic reader instead of the
> > touchscreen and a more featureful set of registers.
> > 
> > Co-developed-by: Jason Reeder <jreeder@ti.com>
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > Signed-off-by: Jason Reeder <jreeder@ti.com>  
> There is one bit in here that I think should have been back in patch 16 but
> maybe I'm missing something.

Good catch, indeed I should have wired the compatible with the driver
data since patch 16. I will fix this.

Thanks,
Miquèl
Miquel Raynal Sept. 2, 2021, 8:03 p.m. UTC | #5
Hi Jonathan,


> > +static const struct ti_tscadc_data magdata = {
> > +	.has_tsc = false,
> > +	.has_mag = true,
> > +	.name_tscmag = "TI-am43xx-mag",
> > +	.compat_tscmag = "ti,am4372-mag",
> > +	.name_adc = "TI-am43xx-adc",
> > +	.compat_adc = "ti,am4372-adc",
> > +	.target_clk_rate = MAG_ADC_CLK,
> > +};
> > +
> >  static const struct of_device_id ti_tscadc_dt_ids[] = {
> > -	{ .compatible = "ti,am3359-tscadc", },
> > +	{
> > +		.compatible = "ti,am3359-tscadc",
> > +		.data = &tscdata,  
> Interesting to see match data added here and not before.
> Given you don't have any code in here that seems to have
> changed to use the match data, was it buggy before or is this still
> not used?

As said earlier, it was buggy before. It is now fixed.

> 
> > +	},
> > +	{
> > +		.compatible = "ti,am4372-magadc",
> > +		.data = &magdata,
> > +	},
> >  	{ }
> >  };
> >  MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
> > @@ -355,6 +382,6 @@ static struct platform_driver ti_tscadc_driver = {
> >  
> >  module_platform_driver(ti_tscadc_driver);
> >  
> > -MODULE_DESCRIPTION("TI touchscreen / ADC MFD controller driver");
> > +MODULE_DESCRIPTION("TI touchscreen/magnetic reader/ADC MFD controller driver");
> >  MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
> >  MODULE_LICENSE("GPL");
> > diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> > index 082b2af94263..31b22ec567e7 100644
> > --- a/include/linux/mfd/ti_am335x_tscadc.h
> > +++ b/include/linux/mfd/ti_am335x_tscadc.h
> > @@ -129,6 +129,11 @@
> >  #define CNTRLREG_TSC_8WIRE	CNTRLREG_TSC_AFE_CTRL(3)
> >  #define CNTRLREG_TSC_ENB	BIT(7)
> >  
> > +/*Control registers bitfields  for MAGADC IP */
> > +#define CNTRLREG_MAGADCENB      BIT(0)
> > +#define CNTRLREG_MAG_PREAMP_PWRDOWN BIT(5)
> > +#define CNTRLREG_MAG_PREAMP_BYPASS  BIT(6)
> > +
> >  /* FIFO READ Register */
> >  #define FIFOREAD_DATA_MASK (0xfff << 0)
> >  #define FIFOREAD_CHNLID_MASK (0xf << 16)
> > @@ -141,7 +146,8 @@
> >  #define SEQ_STATUS BIT(5)
> >  #define CHARGE_STEP		0x11
> >  
> > -#define TSC_ADC_CLK		3000000
> > +#define TSC_ADC_CLK		3000000 /* 3 MHz */
> > +#define MAG_ADC_CLK		13000000 /* 13 MHz */  
> 
> Not sure on current status, but there is a proposed series floating
> about that adds HZ_PER_MEGAHZ or something like that which would make
> it easier to spot if these have right number of zeros.

Would be nice indeed, but it looks like it's not yet mainline :/

Thanks,
Miquèl
diff mbox series

Patch

diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index 1a30610dc65f..f4f6b9db4d2a 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -122,9 +122,9 @@  static	int ti_tscadc_probe(struct platform_device *pdev)
 	const __be32 *cur;
 	struct clk *clk;
 	u32 val;
-	bool use_tsc = false;
+	bool use_tsc = false, use_mag = false;
 	int tscmag_wires = 0, adc_channels = 0, readouts = 0, cell_idx = 0;
-	int total_channels, err;
+	int mag_tracks = 0, total_channels, err;
 
 	/* Allocate memory for device */
 	tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
@@ -146,6 +146,12 @@  static	int ti_tscadc_probe(struct platform_device *pdev)
 		of_property_read_u32(node, "ti,coordiante-readouts", &readouts);
 		if (tscmag_wires)
 			use_tsc = true;
+	} else {
+		node = of_get_child_by_name(pdev->dev.of_node, "mag");
+		of_property_read_u32(node, "ti,tracks", &mag_tracks);
+		tscmag_wires = mag_tracks * 2;
+		if (tscmag_wires)
+			use_mag = true;
 	}
 
 	node = of_get_child_by_name(pdev->dev.of_node, "adc");
@@ -206,8 +212,9 @@  static	int ti_tscadc_probe(struct platform_device *pdev)
 	 * The TSC_ADC_Subsystem has 2 clock domains: OCP_CLK and ADC_CLK.
 	 * ADCs produce a 12-bit sample every 15 ADC_CLK cycles.
 	 * am33xx ADCs expect to capture 200ksps.
-	 * We need the ADC clocks to run at 3MHz.
-	 * This frequency is valid since TSC_ADC_SS controller design
+	 * am47xx ADCs expect to capture 867ksps.
+	 * We need ADC clocks respectively running at 3MHz and 13MHz.
+	 * These frequencies are valid since TSC_ADC_SS controller design
 	 * assumes the OCP clock is at least 6x faster than the ADC clock.
 	 */
 	clk = devm_clk_get(&pdev->dev, NULL);
@@ -231,7 +238,9 @@  static	int ti_tscadc_probe(struct platform_device *pdev)
 			else
 				tscadc->ctrl |= CNTRLREG_TSC_4WIRE;
 		}
-
+	} else {
+		tscadc->ctrl |= CNTRLREG_MAG_PREAMP_PWRDOWN |
+				CNTRLREG_MAG_PREAMP_BYPASS;
 	}
 
 	regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl);
@@ -241,7 +250,7 @@  static	int ti_tscadc_probe(struct platform_device *pdev)
 	/* Enable the TSC module enable bit */
 	regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl | CNTRLREG_SSENB);
 
-	/* TSC Cell */
+	/* TSC or MAG Cell */
 	if (tscmag_wires > 0) {
 		cell = &tscadc->cells[cell_idx++];
 		cell->name = tscadc->data->name_tscmag;
@@ -329,6 +338,7 @@  static SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume);
 
 static const struct ti_tscadc_data tscdata = {
 	.has_tsc = true,
+	.has_mag = false,
 	.name_tscmag = "TI-am335x-tsc",
 	.compat_tscmag = "ti,am3359-tsc",
 	.name_adc = "TI-am335x-adc",
@@ -336,8 +346,25 @@  static const struct ti_tscadc_data tscdata = {
 	.target_clk_rate = TSC_ADC_CLK,
 };
 
+static const struct ti_tscadc_data magdata = {
+	.has_tsc = false,
+	.has_mag = true,
+	.name_tscmag = "TI-am43xx-mag",
+	.compat_tscmag = "ti,am4372-mag",
+	.name_adc = "TI-am43xx-adc",
+	.compat_adc = "ti,am4372-adc",
+	.target_clk_rate = MAG_ADC_CLK,
+};
+
 static const struct of_device_id ti_tscadc_dt_ids[] = {
-	{ .compatible = "ti,am3359-tscadc", },
+	{
+		.compatible = "ti,am3359-tscadc",
+		.data = &tscdata,
+	},
+	{
+		.compatible = "ti,am4372-magadc",
+		.data = &magdata,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
@@ -355,6 +382,6 @@  static struct platform_driver ti_tscadc_driver = {
 
 module_platform_driver(ti_tscadc_driver);
 
-MODULE_DESCRIPTION("TI touchscreen / ADC MFD controller driver");
+MODULE_DESCRIPTION("TI touchscreen/magnetic reader/ADC MFD controller driver");
 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index 082b2af94263..31b22ec567e7 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -129,6 +129,11 @@ 
 #define CNTRLREG_TSC_8WIRE	CNTRLREG_TSC_AFE_CTRL(3)
 #define CNTRLREG_TSC_ENB	BIT(7)
 
+/*Control registers bitfields  for MAGADC IP */
+#define CNTRLREG_MAGADCENB      BIT(0)
+#define CNTRLREG_MAG_PREAMP_PWRDOWN BIT(5)
+#define CNTRLREG_MAG_PREAMP_BYPASS  BIT(6)
+
 /* FIFO READ Register */
 #define FIFOREAD_DATA_MASK (0xfff << 0)
 #define FIFOREAD_CHNLID_MASK (0xf << 16)
@@ -141,7 +146,8 @@ 
 #define SEQ_STATUS BIT(5)
 #define CHARGE_STEP		0x11
 
-#define TSC_ADC_CLK		3000000
+#define TSC_ADC_CLK		3000000 /* 3 MHz */
+#define MAG_ADC_CLK		13000000 /* 13 MHz */
 #define TOTAL_STEPS		16
 #define TOTAL_CHANNELS		8
 #define FIFO1_THRESHOLD		19
@@ -164,6 +170,7 @@ 
 
 struct ti_tscadc_data {
 	bool has_tsc;
+	bool has_mag;
 	char *name_tscmag;
 	char *compat_tscmag;
 	char *name_adc;