aiodev: rockchip_saradc: Add reset control support
PATCH 1/3 aiodev: rockchip_saradc: Add reset control support
This adds reset control support for the Rockchip ADC driver.
Signed-off-by Alexander Shiyan <[email protected]>
--- drivers/aiodev/rockchip_saradc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/aiodev/rockchip_saradc.c +16 -1
@@ -8,8 +8,9 @@#include <common.h> #include <aiodev.h> -#include <linux/clk.h> #include <regulator.h> +#include <linux/clk.h> +#include <linux/reset.h> #define SARADC_DATA 0x00
@@ -37,6 +38,7 @@ struct rockchip_saradc_data {struct clk *pclk;struct aiodevice aiodev;struct aiochannel *channels; +struct reset_control *reset; }; static inline void rockchip_saradc_reg_wr(struct rockchip_saradc_data *data,
@@ -51,6 +53,13 @@ static inline u32 rockchip_saradc_reg_rd(struct rockchip_saradc_data *data,return readl (data->base + reg); } +static void rockchip_saradc_reset_controller (struct reset_control *reset) +{ +reset_control_assert (reset); +udelay (20 ); +reset_control_deassert (reset); +} +static int rockchip_saradc_read (struct aiochannel *chan,int *val) {struct rockchip_saradc_data *data;
@@ -163,14 +172,20 @@ static int rockchip_saradc_probe(struct device *dev)rockchip_saradc_reg_wr (data,0 ,SARADC_CTRL ); + data->reset =reset_control_get (dev,"saradc-apb" ); + ret =aiodevice_register (&data->aiodev);if (ret) goto fail_channels; +rockchip_saradc_reset_controller (data->reset); +dev_info (dev,"registered as %s\n" ,dev_name (&data->aiodev.dev)); +return 0 ; fail_channels: +reset_control_put (data->reset);kfree (data->channels);kfree (data->aiodev.channels);
Signature · 1 line
2.38.2
PATCH 2/3 aiodev: rockchip_saradc: Prepare driver to add support for other SARADC variants
Let's make separate hardware-dependent calls to allow adding different SARADC variants.
Signed-off-by Alexander Shiyan <[email protected]>
--- drivers/aiodev/rockchip_saradc.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/aiodev/rockchip_saradc.c +15 -3
@@ -24,9 +24,13 @@#define SARADC_TIMEOUT_NS (100 * MSECOND) +struct rockchip_saradc_data ; +struct rockchip_saradc_cfg {unsigned int num_bits;unsigned int num_channels; +void (*init)(struct rockchip_saradc_data *data); +int (*read)(struct aiochannel *chan,int *val); };struct rockchip_saradc_data {
@@ -60,7 +64,12 @@ static void rockchip_saradc_reset_controller(struct reset_control *reset)reset_control_deassert (reset); } -static int rockchip_saradc_read (struct aiochannel *chan,int *val) +static void rockchip_saradc_init_v1 (struct rockchip_saradc_data *data) +{ +rockchip_saradc_reg_wr (data,0 ,SARADC_CTRL ); +}; + +static int rockchip_saradc_read_v1 (struct aiochannel *chan,int *val) {struct rockchip_saradc_data *data;u32 value =0 ;
@@ -103,7 +112,7 @@ static int rockchip_saradc_probe(struct device *dev) data->config =device_get_match_data (dev); data->aiodev.hwdev = dev; - data->aiodev.read = rockchip_saradc_read; + data->aiodev.read = data->config->read; data->base =dev_request_mem_region (dev,0 );if (IS_ERR (data->base)) {
@@ -170,7 +179,8 @@ static int rockchip_saradc_probe(struct device *dev) data->channels[i].unit ="mV" ; } -rockchip_saradc_reg_wr (data,0 ,SARADC_CTRL ); +if (data->config->init) + data->config->init (data); data->reset =reset_control_get (dev,"saradc-apb" );
@@ -197,6 +207,8 @@ static int rockchip_saradc_probe(struct device *dev)static const struct rockchip_saradc_cfg rk3568_saradc_cfg = { .num_bits =10 , .num_channels =8 , + .init = rockchip_saradc_init_v1, + .read = rockchip_saradc_read_v1, };static const struct of_device_id of_rockchip_saradc_match[] = {
Signature · 1 line
2.38.2
PATCH 3/3 aiodev: rockchip_saradc: Add support for RK3588
In reply to Alexander ShiyanThis adds RK3588 SARADC support to the driver.
Signed-off-by Alexander Shiyan <[email protected]>
--- drivers/aiodev/rockchip_saradc.c | 81 +++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 12 deletions(-)
drivers/aiodev/rockchip_saradc.c +69 -12
@@ -9,18 +9,30 @@#include <common.h> #include <aiodev.h> #include <regulator.h> +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/reset.h> -#define SARADC_DATA 0x00 - -#define SARADC_CTRL 0x08 -#define SARADC_CTRL_IRQ_STATUS (1 << 6) -#define SARADC_CTRL_IRQ_ENABLE (1 << 5) -#define SARADC_CTRL_POWER_CTRL (1 << 3) -#define SARADC_CTRL_CHN_MASK 0x07 - -#define SARADC_DLY_PU_SOC 0x0c +/* v1 registers */ +#define SARADC_DATA 0x00 +#define SARADC_CTRL 0x08 +# define SARADC_CTRL_IRQ_STATUS (1 << 6) +# define SARADC_CTRL_IRQ_ENABLE (1 << 5) +# define SARADC_CTRL_POWER_CTRL (1 << 3) +#define SARADC_CTRL_CHN_MASK 0x07 +#define SARADC_DLY_PU_SOC 0x0c + +/* v2 registers */ +#define SARADC2_CONV_CON 0x000 +# define SARADC2_CONV_CHANNELS GENMASK(3, 0) +# define SARADC2_START BIT(4) +# define SARADC2_SINGLE_MODE BIT(5) +#define SARADC_T_PD_SOC 0x004 +#define SARADC_T_DAS_SOC 0x00c +#define SARADC2_END_INT_EN 0x104 +# define SARADC2_EN_END_INT BIT(0) +#define SARADC2_END_INT_ST 0x110 +#define SARADC2_DATA_BASE 0x120#define SARADC_TIMEOUT_NS (100 * MSECOND)
@@ -72,9 +84,7 @@ static void rockchip_saradc_init_v1(struct rockchip_saradc_data *data)static int rockchip_saradc_read_v1 (struct aiochannel *chan,int *val) {struct rockchip_saradc_data *data; -u32 value =0 ; -u32 control =0 ; -u32 mask; +u32 value, control, mask;u64 start; data = container_of(chan->aiodev, struct rockchip_saradc_data, aiodev);
@@ -103,6 +113,46 @@ static int rockchip_saradc_read_v1(struct aiochannel *chan, int *val)return 0 ; } +static int rockchip_saradc_read_v2 (struct aiochannel *chan,int *val) +{ +struct rockchip_saradc_data *data; +u32 value, status, mask; +u64 start; + + data = container_of(chan->aiodev, struct rockchip_saradc_data, aiodev); + +rockchip_saradc_reset_controller (data->reset); + +rockchip_saradc_reg_wr (data,0xc ,SARADC_T_DAS_SOC ); +rockchip_saradc_reg_wr (data,0x20 ,SARADC_T_PD_SOC ); + value =FIELD_PREP (SARADC2_EN_END_INT ,1 ); + value |=SARADC2_EN_END_INT <<16 ; +rockchip_saradc_reg_wr (data, value,SARADC2_END_INT_EN ); + value =FIELD_PREP (SARADC2_START ,1 ) | +FIELD_PREP (SARADC2_SINGLE_MODE ,1 ) | +FIELD_PREP (SARADC2_CONV_CHANNELS , chan->index); + value |= (SARADC2_START |SARADC2_SINGLE_MODE |SARADC2_CONV_CHANNELS ) <<16 ; +rockchip_saradc_reg_wr (data, value,SARADC2_CONV_CON ); + + start =get_time_ns (); +do { + status =rockchip_saradc_reg_rd (data,SARADC2_END_INT_ST ); + +if (is_timeout (start,SARADC_TIMEOUT_NS )) +return -ETIMEDOUT ; + }while (!(status &SARADC2_EN_END_INT )); + + mask = (1 << data->config->num_bits) -1 ; + value =rockchip_saradc_reg_rd (data,SARADC2_DATA_BASE + chan->index *4 ); + value &= mask; + +rockchip_saradc_reg_wr (data,SARADC2_EN_END_INT ,SARADC2_END_INT_ST ); + + *val = (value * data->ref_voltage_mv) / mask; + +return 0 ; +} +static int rockchip_saradc_probe (struct device *dev) {struct rockchip_saradc_data *data;
@@ -211,8 +261,15 @@ static const struct rockchip_saradc_cfg rk3568_saradc_cfg = { .read = rockchip_saradc_read_v1, }; +static const struct rockchip_saradc_cfg rk3588_saradc_cfg = { + .num_bits =12 , + .num_channels =8 , + .read = rockchip_saradc_read_v2, +}; +static const struct of_device_id of_rockchip_saradc_match[] = { { .compatible ="rockchip,rk3568-saradc" , .data = &rk3568_saradc_cfg }, + { .compatible ="rockchip,rk3588-saradc" , .data = &rk3588_saradc_cfg }, {/* end */ } };MODULE_DEVICE_TABLE (of, of_rockchip_saradc_match);
Signature · 1 line
2.38.2
Hi Alexander,
Quoted 45 lines · Alexander Shiyan
This adds reset control support for the Rockchip ADC driver.
Signed-off-by Alexander Shiyan <[email protected]>--- drivers/aiodev/rockchip_saradc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)drivers/aiodev/rockchip_saradc.c +10
-1@@ -8,8 +8,9 @@#include <common.h> #include <aiodev.h> -#include <linux/clk.h> #include <regulator.h> +#include <linux/clk.h> +#include <linux/reset.h> #define SARADC_DATA 0x00@@ -37,6 +38,7 @@ struct rockchip_saradc_data {struct clk *pclk;struct aiodevice aiodev;struct aiochannel *channels; +struct reset_control *reset; }; static inline void rockchip_saradc_reg_wr(struct rockchip_saradc_data *data,@@ -51,6 +53,13 @@ static inline u32 rockchip_saradc_reg_rd(struct rockchip_saradc_data *data,return readl (data->base + reg); } +static void rockchip_saradc_reset_controller (struct reset_control *reset) +{ +reset_control_assert (reset); +udelay (20 ); +reset_control_deassert (reset); +} +static int rockchip_saradc_read (struct aiochannel *chan,int *val) {struct rockchip_saradc_data *data;
drivers/aiodev/rockchip_saradc.c static int rockchip_saradc_probe(struct device *dev) · line 175
Quoted 4 lines
drivers/aiodev/rockchip_saradc.c +1
-0@@ -163,14 +172,20 @@ static int rockchip_saradc_probe(struct device *dev)rockchip_saradc_reg_wr (data,0 ,SARADC_CTRL ); + data->reset =reset_control_get (dev,"saradc-apb" );
reset_control_get() might return an error pointer. You need to check that before passing it to reset_control_assert().
Sascha
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |