Commit e1811f97 authored by Josh Wu's avatar Josh Wu Committed by Jonathan Cameron

iio: at91: introduce the multiple compatible string for different IPs.

As use the multiple compatible string, we can remove hardware register in dt.

CC: devicetree@vger.kernel.org
Signed-off-by: default avatarJosh Wu <josh.wu@atmel.com>
Acked-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 2d2da9fc
* AT91's Analog to Digital Converter (ADC) * AT91's Analog to Digital Converter (ADC)
Required properties: Required properties:
- compatible: Should be "atmel,at91sam9260-adc" - compatible: Should be "atmel,<chip>-adc"
<chip> can be "at91sam9260", "at91sam9g45" or "at91sam9x5"
- reg: Should contain ADC registers location and length - reg: Should contain ADC registers location and length
- interrupts: Should contain the IRQ line for the ADC - interrupts: Should contain the IRQ line for the ADC
- atmel,adc-channel-base: Offset of the first channel data register
- atmel,adc-channels-used: Bitmask of the channels muxed and enable for this - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
device device
- atmel,adc-drdy-mask: Mask of the DRDY interruption in the ADC
- atmel,adc-num-channels: Number of channels available in the ADC - atmel,adc-num-channels: Number of channels available in the ADC
- atmel,adc-startup-time: Startup Time of the ADC in microseconds as - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
defined in the datasheet defined in the datasheet
- atmel,adc-status-register: Offset of the Interrupt Status Register
- atmel,adc-trigger-register: Offset of the Trigger Register
- atmel,adc-vref: Reference voltage in millivolts for the conversions - atmel,adc-vref: Reference voltage in millivolts for the conversions
- atmel,adc-res: List of resolution in bits supported by the ADC. List size - atmel,adc-res: List of resolution in bits supported by the ADC. List size
must be two at least. must be two at least.
......
...@@ -48,6 +48,9 @@ ...@@ -48,6 +48,9 @@
#define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */ #define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */
#define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */ #define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */
#define AT91_ADC_SR_9X5 0x30 /* Status Register for 9x5 */
#define AT91_ADC_SR_DRDY_9X5 (1 << 24) /* Data Ready */
#define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */ #define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */
#define AT91_ADC_LDATA (0x3ff) #define AT91_ADC_LDATA (0x3ff)
...@@ -58,4 +61,10 @@ ...@@ -58,4 +61,10 @@
#define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ #define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */
#define AT91_ADC_DATA (0x3ff) #define AT91_ADC_DATA (0x3ff)
#define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */
#define AT91_ADC_TRGR_9260 AT91_ADC_MR
#define AT91_ADC_TRGR_9G45 0x08
#define AT91_ADC_TRGR_9X5 0xC0
#endif #endif
...@@ -39,6 +39,10 @@ ...@@ -39,6 +39,10 @@
#define at91_adc_writel(st, reg, val) \ #define at91_adc_writel(st, reg, val) \
(writel_relaxed(val, st->reg_base + reg)) (writel_relaxed(val, st->reg_base + reg))
struct at91_adc_caps {
struct at91_adc_reg_desc registers;
};
struct at91_adc_state { struct at91_adc_state {
struct clk *adc_clk; struct clk *adc_clk;
u16 *buffer; u16 *buffer;
...@@ -62,6 +66,7 @@ struct at91_adc_state { ...@@ -62,6 +66,7 @@ struct at91_adc_state {
u32 res; /* resolution used for convertions */ u32 res; /* resolution used for convertions */
bool low_res; /* the resolution corresponds to the lowest one */ bool low_res; /* the resolution corresponds to the lowest one */
wait_queue_head_t wq_data_avail; wait_queue_head_t wq_data_avail;
struct at91_adc_caps *caps;
}; };
static irqreturn_t at91_adc_trigger_handler(int irq, void *p) static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
...@@ -429,6 +434,8 @@ static int at91_adc_of_get_resolution(struct at91_adc_state *st, ...@@ -429,6 +434,8 @@ static int at91_adc_of_get_resolution(struct at91_adc_state *st,
return ret; return ret;
} }
static const struct of_device_id at91_adc_dt_ids[];
static int at91_adc_probe_dt(struct at91_adc_state *st, static int at91_adc_probe_dt(struct at91_adc_state *st,
struct platform_device *pdev) struct platform_device *pdev)
{ {
...@@ -441,6 +448,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st, ...@@ -441,6 +448,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
if (!node) if (!node)
return -EINVAL; return -EINVAL;
st->caps = (struct at91_adc_caps *)
of_match_device(at91_adc_dt_ids, &pdev->dev)->data;
st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers"); st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers");
if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) { if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) {
...@@ -481,43 +491,7 @@ static int at91_adc_probe_dt(struct at91_adc_state *st, ...@@ -481,43 +491,7 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
if (ret) if (ret)
goto error_ret; goto error_ret;
st->registers = devm_kzalloc(&idev->dev, st->registers = &st->caps->registers;
sizeof(struct at91_adc_reg_desc),
GFP_KERNEL);
if (!st->registers) {
dev_err(&idev->dev, "Could not allocate register memory.\n");
ret = -ENOMEM;
goto error_ret;
}
if (of_property_read_u32(node, "atmel,adc-channel-base", &prop)) {
dev_err(&idev->dev, "Missing adc-channel-base property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->registers->channel_base = prop;
if (of_property_read_u32(node, "atmel,adc-drdy-mask", &prop)) {
dev_err(&idev->dev, "Missing adc-drdy-mask property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->registers->drdy_mask = prop;
if (of_property_read_u32(node, "atmel,adc-status-register", &prop)) {
dev_err(&idev->dev, "Missing adc-status-register property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->registers->status_register = prop;
if (of_property_read_u32(node, "atmel,adc-trigger-register", &prop)) {
dev_err(&idev->dev, "Missing adc-trigger-register property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->registers->trigger_register = prop;
st->trigger_number = of_get_child_count(node); st->trigger_number = of_get_child_count(node);
st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number * st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number *
sizeof(struct at91_adc_trigger), sizeof(struct at91_adc_trigger),
...@@ -766,8 +740,37 @@ static int at91_adc_remove(struct platform_device *pdev) ...@@ -766,8 +740,37 @@ static int at91_adc_remove(struct platform_device *pdev)
} }
#ifdef CONFIG_OF #ifdef CONFIG_OF
static struct at91_adc_caps at91sam9260_caps = {
.registers = {
.channel_base = AT91_ADC_CHR(0),
.drdy_mask = AT91_ADC_DRDY,
.status_register = AT91_ADC_SR,
.trigger_register = AT91_ADC_TRGR_9260,
},
};
static struct at91_adc_caps at91sam9g45_caps = {
.registers = {
.channel_base = AT91_ADC_CHR(0),
.drdy_mask = AT91_ADC_DRDY,
.status_register = AT91_ADC_SR,
.trigger_register = AT91_ADC_TRGR_9G45,
},
};
static struct at91_adc_caps at91sam9x5_caps = {
.registers = {
.channel_base = AT91_ADC_CDR0_9X5,
.drdy_mask = AT91_ADC_SR_DRDY_9X5,
.status_register = AT91_ADC_SR_9X5,
.trigger_register = AT91_ADC_TRGR_9X5,
},
};
static const struct of_device_id at91_adc_dt_ids[] = { static const struct of_device_id at91_adc_dt_ids[] = {
{ .compatible = "atmel,at91sam9260-adc" }, { .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps },
{ .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps },
{ .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment