Skip to content

Commit 06f7d74

Browse files
committed
Merge branch 'at91-4.19-trunk/i2c' into linux-4.19-at91
2 parents fa90dac + b0faf02 commit 06f7d74

2 files changed

Lines changed: 85 additions & 1 deletion

File tree

Documentation/devicetree/bindings/i2c/i2c-at91.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ I2C for Atmel platforms
33
Required properties :
44
- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c",
55
"atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c",
6-
"atmel,at91sam9x5-i2c", "atmel,sama5d4-i2c" or "atmel,sama5d2-i2c"
6+
"atmel,at91sam9x5-i2c", "atmel,sama5d4-i2c", "atmel,sama5d2-i2c" or
7+
"microchip,sam9x60-i2c"
78
- reg: physical base address of the controller and length of memory mapped
89
region.
910
- interrupts: interrupt number to the cpu.
@@ -19,6 +20,12 @@ Optional properties:
1920
capable I2C controllers.
2021
- i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c"
2122
and "atmel,sama5d2-i2c".
23+
- enable-dig-filt: Enable the built-in digital filter on the i2c lines,
24+
specifically required depending on the hardware PCB/board and if the
25+
version of the controller includes it.
26+
- enable-ana-filt: Enable the built-in analogic filter on the i2c lines,
27+
specifically required depending on the hardware PCB/board and if the
28+
version of the controller includes it.
2229
- Child nodes conforming to i2c bus binding
2330

2431
Examples :
@@ -55,6 +62,8 @@ i2c0: i2c@f8034600 {
5562
clocks = <&flx0>;
5663
atmel,fifo-size = <16>;
5764
i2c-sda-hold-time-ns = <336>;
65+
enable-dig-filt;
66+
enable-ana-filt;
5867

5968
wm8731: wm8731@1a {
6069
compatible = "wm8731";

drivers/i2c/busses/i2c-at91.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@
9090
#define AT91_TWI_ACR_DATAL(len) ((len) & 0xff)
9191
#define AT91_TWI_ACR_DIR BIT(8)
9292

93+
#define AT91_TWI_FILTR 0x0044
94+
#define AT91_TWI_FILTR_FILT BIT(0)
95+
#define AT91_TWI_FILTR_PADFEN BIT(1)
96+
#define AT91_TWI_FILTR_PADFCFG BIT(2)
97+
#define AT91_TWI_FILTR_THRES(v) ((v) << 8)
98+
#define AT91_TWI_FILTR_THRES_MASK GENMASK(10, 8)
99+
93100
#define AT91_TWI_FMR 0x0050 /* FIFO Mode Register */
94101
#define AT91_TWI_FMR_TXRDYM(mode) (((mode) & 0x3) << 0)
95102
#define AT91_TWI_FMR_TXRDYM_MASK (0x3 << 0)
@@ -114,6 +121,9 @@ struct at91_twi_pdata {
114121
bool has_unre_flag;
115122
bool has_alt_cmd;
116123
bool has_hold_field;
124+
bool has_dig_filtr;
125+
bool has_adv_dig_filtr;
126+
bool has_ana_filtr;
117127
struct at_dma_slave dma_slave;
118128
};
119129

@@ -146,6 +156,8 @@ struct at91_twi_dev {
146156
bool recv_len_abort;
147157
u32 fifo_size;
148158
struct at91_twi_dma dma;
159+
bool enable_dig_filt;
160+
bool enable_ana_filt;
149161
};
150162

151163
static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
@@ -176,6 +188,9 @@ static void at91_twi_irq_restore(struct at91_twi_dev *dev)
176188

177189
static void at91_init_twi_bus(struct at91_twi_dev *dev)
178190
{
191+
struct at91_twi_pdata *pdata = dev->pdata;
192+
u32 filtr = 0;
193+
179194
at91_disable_twi_interrupts(dev);
180195
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
181196
/* FIFO should be enabled immediately after the software reset */
@@ -184,6 +199,22 @@ static void at91_init_twi_bus(struct at91_twi_dev *dev)
184199
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
185200
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);
186201
at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
202+
203+
/* enable digital filter */
204+
if (pdata->has_dig_filtr && dev->enable_dig_filt)
205+
filtr |= AT91_TWI_FILTR_FILT;
206+
207+
/* enable advanced digital filter */
208+
if (pdata->has_adv_dig_filtr && dev->enable_dig_filt)
209+
filtr |= AT91_TWI_FILTR_FILT |
210+
(AT91_TWI_FILTR_THRES(7) & AT91_TWI_FILTR_THRES_MASK);
211+
212+
/* enable analog filter */
213+
if (pdata->has_ana_filtr && dev->enable_ana_filt)
214+
filtr |= AT91_TWI_FILTR_PADFEN | AT91_TWI_FILTR_PADFCFG;
215+
216+
if (filtr)
217+
at91_twi_write(dev, AT91_TWI_FILTR, filtr);
187218
}
188219

189220
/*
@@ -831,6 +862,9 @@ static struct at91_twi_pdata at91rm9200_config = {
831862
.has_unre_flag = true,
832863
.has_alt_cmd = false,
833864
.has_hold_field = false,
865+
.has_dig_filtr = false,
866+
.has_adv_dig_filtr = false,
867+
.has_ana_filtr = false,
834868
};
835869

836870
static struct at91_twi_pdata at91sam9261_config = {
@@ -839,6 +873,9 @@ static struct at91_twi_pdata at91sam9261_config = {
839873
.has_unre_flag = false,
840874
.has_alt_cmd = false,
841875
.has_hold_field = false,
876+
.has_dig_filtr = false,
877+
.has_adv_dig_filtr = false,
878+
.has_ana_filtr = false,
842879
};
843880

844881
static struct at91_twi_pdata at91sam9260_config = {
@@ -847,6 +884,9 @@ static struct at91_twi_pdata at91sam9260_config = {
847884
.has_unre_flag = false,
848885
.has_alt_cmd = false,
849886
.has_hold_field = false,
887+
.has_dig_filtr = false,
888+
.has_adv_dig_filtr = false,
889+
.has_ana_filtr = false,
850890
};
851891

852892
static struct at91_twi_pdata at91sam9g20_config = {
@@ -855,6 +895,9 @@ static struct at91_twi_pdata at91sam9g20_config = {
855895
.has_unre_flag = false,
856896
.has_alt_cmd = false,
857897
.has_hold_field = false,
898+
.has_dig_filtr = false,
899+
.has_adv_dig_filtr = false,
900+
.has_ana_filtr = false,
858901
};
859902

860903
static struct at91_twi_pdata at91sam9g10_config = {
@@ -863,6 +906,9 @@ static struct at91_twi_pdata at91sam9g10_config = {
863906
.has_unre_flag = false,
864907
.has_alt_cmd = false,
865908
.has_hold_field = false,
909+
.has_dig_filtr = false,
910+
.has_adv_dig_filtr = false,
911+
.has_ana_filtr = false,
866912
};
867913

868914
static const struct platform_device_id at91_twi_devtypes[] = {
@@ -893,6 +939,9 @@ static struct at91_twi_pdata at91sam9x5_config = {
893939
.has_unre_flag = false,
894940
.has_alt_cmd = false,
895941
.has_hold_field = false,
942+
.has_dig_filtr = false,
943+
.has_adv_dig_filtr = false,
944+
.has_ana_filtr = false,
896945
};
897946

898947
static struct at91_twi_pdata sama5d4_config = {
@@ -901,6 +950,9 @@ static struct at91_twi_pdata sama5d4_config = {
901950
.has_unre_flag = false,
902951
.has_alt_cmd = false,
903952
.has_hold_field = true,
953+
.has_dig_filtr = true,
954+
.has_adv_dig_filtr = false,
955+
.has_ana_filtr = false,
904956
};
905957

906958
static struct at91_twi_pdata sama5d2_config = {
@@ -909,6 +961,20 @@ static struct at91_twi_pdata sama5d2_config = {
909961
.has_unre_flag = true,
910962
.has_alt_cmd = true,
911963
.has_hold_field = true,
964+
.has_dig_filtr = true,
965+
.has_adv_dig_filtr = true,
966+
.has_ana_filtr = true,
967+
};
968+
969+
static struct at91_twi_pdata sam9x60_config = {
970+
.clk_max_div = 7,
971+
.clk_offset = 4,
972+
.has_unre_flag = true,
973+
.has_alt_cmd = true,
974+
.has_hold_field = true,
975+
.has_dig_filtr = true,
976+
.has_adv_dig_filtr = true,
977+
.has_ana_filtr = true,
912978
};
913979

914980
static const struct of_device_id atmel_twi_dt_ids[] = {
@@ -936,6 +1002,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {
9361002
}, {
9371003
.compatible = "atmel,sama5d2-i2c",
9381004
.data = &sama5d2_config,
1005+
}, {
1006+
.compatible = "microchip,sam9x60-i2c",
1007+
.data = &sam9x60_config,
9391008
}, {
9401009
/* sentinel */
9411010
}
@@ -1105,6 +1174,12 @@ static int at91_twi_probe(struct platform_device *pdev)
11051174
if (rc)
11061175
bus_clk_rate = DEFAULT_TWI_CLK_HZ;
11071176

1177+
dev->enable_dig_filt = of_property_read_bool(pdev->dev.of_node,
1178+
"enable-dig-filt");
1179+
1180+
dev->enable_ana_filt = of_property_read_bool(pdev->dev.of_node,
1181+
"enable-ana-filt");
1182+
11081183
at91_calc_twi_clock(dev, bus_clk_rate);
11091184
at91_init_twi_bus(dev);
11101185

0 commit comments

Comments
 (0)