Skip to content

Commit

Permalink
i2c: at91: add support for analog filtering
Browse files Browse the repository at this point in the history
Add support for analog filtering for i2c lines.
The sama5d2 and sam9x60 support this feature.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>
Reviewed-by: Peter Rosin <peda@axentia.se>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
  • Loading branch information
Eugen Hristev authored and Wolfram Sang committed Oct 24, 2019
1 parent 2be357a commit dda9671
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
9 changes: 9 additions & 0 deletions drivers/i2c/busses/i2c-at91-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static struct at91_twi_pdata at91rm9200_config = {
.has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static struct at91_twi_pdata at91sam9261_config = {
Expand All @@ -80,6 +81,7 @@ static struct at91_twi_pdata at91sam9261_config = {
.has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static struct at91_twi_pdata at91sam9260_config = {
Expand All @@ -90,6 +92,7 @@ static struct at91_twi_pdata at91sam9260_config = {
.has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static struct at91_twi_pdata at91sam9g20_config = {
Expand All @@ -100,6 +103,7 @@ static struct at91_twi_pdata at91sam9g20_config = {
.has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static struct at91_twi_pdata at91sam9g10_config = {
Expand All @@ -110,6 +114,7 @@ static struct at91_twi_pdata at91sam9g10_config = {
.has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static const struct platform_device_id at91_twi_devtypes[] = {
Expand Down Expand Up @@ -142,6 +147,7 @@ static struct at91_twi_pdata at91sam9x5_config = {
.has_hold_field = false,
.has_dig_filtr = false,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static struct at91_twi_pdata sama5d4_config = {
Expand All @@ -152,6 +158,7 @@ static struct at91_twi_pdata sama5d4_config = {
.has_hold_field = true,
.has_dig_filtr = true,
.has_adv_dig_filtr = false,
.has_ana_filtr = false,
};

static struct at91_twi_pdata sama5d2_config = {
Expand All @@ -162,6 +169,7 @@ static struct at91_twi_pdata sama5d2_config = {
.has_hold_field = true,
.has_dig_filtr = true,
.has_adv_dig_filtr = true,
.has_ana_filtr = true,
};

static struct at91_twi_pdata sam9x60_config = {
Expand All @@ -172,6 +180,7 @@ static struct at91_twi_pdata sam9x60_config = {
.has_hold_field = true,
.has_dig_filtr = true,
.has_adv_dig_filtr = true,
.has_ana_filtr = true,
};

static const struct of_device_id atmel_twi_dt_ids[] = {
Expand Down
18 changes: 14 additions & 4 deletions drivers/i2c/busses/i2c-at91-master.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
void at91_init_twi_bus_master(struct at91_twi_dev *dev)
{
struct at91_twi_pdata *pdata = dev->pdata;
u32 filtr = 0;

/* FIFO should be enabled immediately after the software reset */
if (dev->fifo_size)
Expand All @@ -42,13 +43,20 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev)

/* enable digital filter */
if (pdata->has_dig_filtr && dev->enable_dig_filt)
at91_twi_write(dev, AT91_TWI_FILTR, AT91_TWI_FILTR_FILT);
filtr |= AT91_TWI_FILTR_FILT;

/* enable advanced digital filter */
if (pdata->has_adv_dig_filtr && dev->enable_dig_filt)
at91_twi_write(dev, AT91_TWI_FILTR, AT91_TWI_FILTR_FILT |
(AT91_TWI_FILTR_THRES(dev->filter_width) &
AT91_TWI_FILTR_THRES_MASK));
filtr |= AT91_TWI_FILTR_FILT |
(AT91_TWI_FILTR_THRES(dev->filter_width) &
AT91_TWI_FILTR_THRES_MASK);

/* enable analog filter */
if (pdata->has_ana_filtr && dev->enable_ana_filt)
filtr |= AT91_TWI_FILTR_PADFEN;

if (filtr)
at91_twi_write(dev, AT91_TWI_FILTR, filtr);
}

/*
Expand Down Expand Up @@ -826,6 +834,8 @@ int at91_twi_probe_master(struct platform_device *pdev,
dev->enable_dig_filt = of_property_read_bool(pdev->dev.of_node,
"i2c-digital-filter");

dev->enable_ana_filt = of_property_read_bool(pdev->dev.of_node,
"i2c-analog-filter");
at91_calc_twi_clock(dev);

dev->adapter.algo = &at91_twi_algorithm;
Expand Down
3 changes: 3 additions & 0 deletions drivers/i2c/busses/i2c-at91.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@

#define AT91_TWI_FILTR 0x0044
#define AT91_TWI_FILTR_FILT BIT(0)
#define AT91_TWI_FILTR_PADFEN BIT(1)
#define AT91_TWI_FILTR_THRES(v) ((v) << 8)
#define AT91_TWI_FILTR_THRES_MAX 7
#define AT91_TWI_FILTR_THRES_MASK GENMASK(10, 8)
Expand Down Expand Up @@ -116,6 +117,7 @@ struct at91_twi_pdata {
bool has_hold_field;
bool has_dig_filtr;
bool has_adv_dig_filtr;
bool has_ana_filtr;
struct at_dma_slave dma_slave;
};

Expand Down Expand Up @@ -154,6 +156,7 @@ struct at91_twi_dev {
struct i2c_client *slave;
#endif
bool enable_dig_filt;
bool enable_ana_filt;
u32 filter_width;
};

Expand Down

0 comments on commit dda9671

Please sign in to comment.