diff options
| author | Haojian Zhuang <haojian.zhuang@marvell.com> | 2012-03-01 00:04:44 -0500 |
|---|---|---|
| committer | Haojian Zhuang <haojian.zhuang@gmail.com> | 2012-03-06 20:32:03 -0500 |
| commit | 63fe122bce0655ffdbbe3d23b1ee445c44ce65c2 (patch) | |
| tree | 9562da38ea84a99d8ef670699274566ff7a6ab6e /drivers/i2c | |
| parent | 699c20f3e6310aa2ff18610c7d0885ed54d64337 (diff) | |
i2c: pxa: add OF support
Append these properties in below.
mrvl,i2c-polling
mrvl,i2c-fast-mode
Still keep slave, slave_addr and class in platform data.
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 95 |
1 files changed, 74 insertions, 21 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index d60364650990..f6733267fa9c 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
| 30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
| 31 | #include <linux/i2c-pxa.h> | 31 | #include <linux/i2c-pxa.h> |
| 32 | #include <linux/of.h> | ||
| 33 | #include <linux/of_device.h> | ||
| 32 | #include <linux/of_i2c.h> | 34 | #include <linux/of_i2c.h> |
| 33 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
| 34 | #include <linux/err.h> | 36 | #include <linux/err.h> |
| @@ -1044,23 +1046,60 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = { | |||
| 1044 | .functionality = i2c_pxa_functionality, | 1046 | .functionality = i2c_pxa_functionality, |
| 1045 | }; | 1047 | }; |
| 1046 | 1048 | ||
| 1047 | static int i2c_pxa_probe(struct platform_device *dev) | 1049 | static struct of_device_id i2c_pxa_dt_ids[] = { |
| 1050 | { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX }, | ||
| 1051 | { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX }, | ||
| 1052 | { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX }, | ||
| 1053 | {} | ||
| 1054 | }; | ||
| 1055 | MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids); | ||
| 1056 | |||
| 1057 | static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c, | ||
| 1058 | enum pxa_i2c_types *i2c_types) | ||
| 1048 | { | 1059 | { |
| 1049 | struct pxa_i2c *i2c; | 1060 | struct device_node *np = pdev->dev.of_node; |
| 1050 | struct resource *res; | 1061 | const struct of_device_id *of_id = |
| 1051 | struct i2c_pxa_platform_data *plat = dev->dev.platform_data; | 1062 | of_match_device(i2c_pxa_dt_ids, &pdev->dev); |
| 1052 | const struct platform_device_id *id = platform_get_device_id(dev); | ||
| 1053 | enum pxa_i2c_types i2c_type = id->driver_data; | ||
| 1054 | int ret; | 1063 | int ret; |
| 1055 | int irq; | ||
| 1056 | 1064 | ||
| 1057 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 1065 | if (!of_id) |
| 1058 | irq = platform_get_irq(dev, 0); | 1066 | return 1; |
| 1059 | if (res == NULL || irq < 0) | 1067 | ret = of_alias_get_id(np, "i2c"); |
| 1060 | return -ENODEV; | 1068 | if (ret < 0) { |
| 1069 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); | ||
| 1070 | return ret; | ||
| 1071 | } | ||
| 1072 | pdev->id = ret; | ||
| 1073 | if (of_get_property(np, "mrvl,i2c-polling", NULL)) | ||
| 1074 | i2c->use_pio = 1; | ||
| 1075 | if (of_get_property(np, "mrvl,i2c-fast-mode", NULL)) | ||
| 1076 | i2c->fast_mode = 1; | ||
| 1077 | *i2c_types = (u32)(of_id->data); | ||
| 1078 | return 0; | ||
| 1079 | } | ||
| 1061 | 1080 | ||
| 1062 | if (!request_mem_region(res->start, resource_size(res), res->name)) | 1081 | static int i2c_pxa_probe_pdata(struct platform_device *pdev, |
| 1063 | return -ENOMEM; | 1082 | struct pxa_i2c *i2c, |
| 1083 | enum pxa_i2c_types *i2c_types) | ||
| 1084 | { | ||
| 1085 | struct i2c_pxa_platform_data *plat = pdev->dev.platform_data; | ||
| 1086 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
| 1087 | |||
| 1088 | *i2c_types = id->driver_data; | ||
| 1089 | if (plat) { | ||
| 1090 | i2c->use_pio = plat->use_pio; | ||
| 1091 | i2c->fast_mode = plat->fast_mode; | ||
| 1092 | } | ||
| 1093 | return 0; | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | static int i2c_pxa_probe(struct platform_device *dev) | ||
| 1097 | { | ||
| 1098 | struct i2c_pxa_platform_data *plat = dev->dev.platform_data; | ||
| 1099 | enum pxa_i2c_types i2c_type; | ||
| 1100 | struct pxa_i2c *i2c; | ||
| 1101 | struct resource *res = NULL; | ||
| 1102 | int ret, irq; | ||
| 1064 | 1103 | ||
| 1065 | i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL); | 1104 | i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL); |
| 1066 | if (!i2c) { | 1105 | if (!i2c) { |
| @@ -1068,6 +1107,24 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
| 1068 | goto emalloc; | 1107 | goto emalloc; |
| 1069 | } | 1108 | } |
| 1070 | 1109 | ||
| 1110 | ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type); | ||
| 1111 | if (ret > 0) | ||
| 1112 | ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type); | ||
| 1113 | if (ret < 0) | ||
| 1114 | goto eclk; | ||
| 1115 | |||
| 1116 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
| 1117 | irq = platform_get_irq(dev, 0); | ||
| 1118 | if (res == NULL || irq < 0) { | ||
| 1119 | ret = -ENODEV; | ||
| 1120 | goto eclk; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | if (!request_mem_region(res->start, resource_size(res), res->name)) { | ||
| 1124 | ret = -ENOMEM; | ||
| 1125 | goto eclk; | ||
| 1126 | } | ||
| 1127 | |||
| 1071 | i2c->adap.owner = THIS_MODULE; | 1128 | i2c->adap.owner = THIS_MODULE; |
| 1072 | i2c->adap.retries = 5; | 1129 | i2c->adap.retries = 5; |
| 1073 | 1130 | ||
| @@ -1109,21 +1166,16 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
| 1109 | 1166 | ||
| 1110 | i2c->slave_addr = I2C_PXA_SLAVE_ADDR; | 1167 | i2c->slave_addr = I2C_PXA_SLAVE_ADDR; |
| 1111 | 1168 | ||
| 1112 | #ifdef CONFIG_I2C_PXA_SLAVE | ||
| 1113 | if (plat) { | 1169 | if (plat) { |
| 1170 | #ifdef CONFIG_I2C_PXA_SLAVE | ||
| 1114 | i2c->slave_addr = plat->slave_addr; | 1171 | i2c->slave_addr = plat->slave_addr; |
| 1115 | i2c->slave = plat->slave; | 1172 | i2c->slave = plat->slave; |
| 1116 | } | ||
| 1117 | #endif | 1173 | #endif |
| 1118 | |||
| 1119 | clk_enable(i2c->clk); | ||
| 1120 | |||
| 1121 | if (plat) { | ||
| 1122 | i2c->adap.class = plat->class; | 1174 | i2c->adap.class = plat->class; |
| 1123 | i2c->use_pio = plat->use_pio; | ||
| 1124 | i2c->fast_mode = plat->fast_mode; | ||
| 1125 | } | 1175 | } |
| 1126 | 1176 | ||
| 1177 | clk_enable(i2c->clk); | ||
| 1178 | |||
| 1127 | if (i2c->use_pio) { | 1179 | if (i2c->use_pio) { |
| 1128 | i2c->adap.algo = &i2c_pxa_pio_algorithm; | 1180 | i2c->adap.algo = &i2c_pxa_pio_algorithm; |
| 1129 | } else { | 1181 | } else { |
| @@ -1234,6 +1286,7 @@ static struct platform_driver i2c_pxa_driver = { | |||
| 1234 | .name = "pxa2xx-i2c", | 1286 | .name = "pxa2xx-i2c", |
| 1235 | .owner = THIS_MODULE, | 1287 | .owner = THIS_MODULE, |
| 1236 | .pm = I2C_PXA_DEV_PM_OPS, | 1288 | .pm = I2C_PXA_DEV_PM_OPS, |
| 1289 | .of_match_table = i2c_pxa_dt_ids, | ||
| 1237 | }, | 1290 | }, |
| 1238 | .id_table = i2c_pxa_id_table, | 1291 | .id_table = i2c_pxa_id_table, |
| 1239 | }; | 1292 | }; |
