diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 5 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/mcbsp.h | 11 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 122 |
3 files changed, 138 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index a5c0f0435cd6..f837114d1d69 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -129,6 +129,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
129 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | 129 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, |
130 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | 130 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, |
131 | .ops = &omap2_mcbsp_ops, | 131 | .ops = &omap2_mcbsp_ops, |
132 | .buffer_size = 0x7F, | ||
132 | }, | 133 | }, |
133 | { | 134 | { |
134 | .phys_base = OMAP34XX_MCBSP2_BASE, | 135 | .phys_base = OMAP34XX_MCBSP2_BASE, |
@@ -137,6 +138,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
137 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | 138 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, |
138 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | 139 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, |
139 | .ops = &omap2_mcbsp_ops, | 140 | .ops = &omap2_mcbsp_ops, |
141 | .buffer_size = 0x3FF, | ||
140 | }, | 142 | }, |
141 | { | 143 | { |
142 | .phys_base = OMAP34XX_MCBSP3_BASE, | 144 | .phys_base = OMAP34XX_MCBSP3_BASE, |
@@ -145,6 +147,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
145 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | 147 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, |
146 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | 148 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, |
147 | .ops = &omap2_mcbsp_ops, | 149 | .ops = &omap2_mcbsp_ops, |
150 | .buffer_size = 0x7F, | ||
148 | }, | 151 | }, |
149 | { | 152 | { |
150 | .phys_base = OMAP34XX_MCBSP4_BASE, | 153 | .phys_base = OMAP34XX_MCBSP4_BASE, |
@@ -153,6 +156,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
153 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | 156 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, |
154 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | 157 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, |
155 | .ops = &omap2_mcbsp_ops, | 158 | .ops = &omap2_mcbsp_ops, |
159 | .buffer_size = 0x7F, | ||
156 | }, | 160 | }, |
157 | { | 161 | { |
158 | .phys_base = OMAP34XX_MCBSP5_BASE, | 162 | .phys_base = OMAP34XX_MCBSP5_BASE, |
@@ -161,6 +165,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
161 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | 165 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, |
162 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | 166 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, |
163 | .ops = &omap2_mcbsp_ops, | 167 | .ops = &omap2_mcbsp_ops, |
168 | .buffer_size = 0x7F, | ||
164 | }, | 169 | }, |
165 | }; | 170 | }; |
166 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | 171 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) |
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 2544aa5bccd3..832330d7cb39 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h | |||
@@ -348,6 +348,9 @@ struct omap_mcbsp_platform_data { | |||
348 | u8 dma_rx_sync, dma_tx_sync; | 348 | u8 dma_rx_sync, dma_tx_sync; |
349 | u16 rx_irq, tx_irq; | 349 | u16 rx_irq, tx_irq; |
350 | struct omap_mcbsp_ops *ops; | 350 | struct omap_mcbsp_ops *ops; |
351 | #ifdef CONFIG_ARCH_OMAP34XX | ||
352 | u16 buffer_size; | ||
353 | #endif | ||
351 | }; | 354 | }; |
352 | 355 | ||
353 | struct omap_mcbsp { | 356 | struct omap_mcbsp { |
@@ -381,6 +384,10 @@ struct omap_mcbsp { | |||
381 | struct omap_mcbsp_platform_data *pdata; | 384 | struct omap_mcbsp_platform_data *pdata; |
382 | struct clk *iclk; | 385 | struct clk *iclk; |
383 | struct clk *fclk; | 386 | struct clk *fclk; |
387 | #ifdef CONFIG_ARCH_OMAP34XX | ||
388 | u16 max_tx_thres; | ||
389 | u16 max_rx_thres; | ||
390 | #endif | ||
384 | }; | 391 | }; |
385 | extern struct omap_mcbsp **mcbsp_ptr; | 392 | extern struct omap_mcbsp **mcbsp_ptr; |
386 | extern int omap_mcbsp_count; | 393 | extern int omap_mcbsp_count; |
@@ -392,11 +399,15 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config | |||
392 | #ifdef CONFIG_ARCH_OMAP34XX | 399 | #ifdef CONFIG_ARCH_OMAP34XX |
393 | void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); | 400 | void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); |
394 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); | 401 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); |
402 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); | ||
403 | u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); | ||
395 | #else | 404 | #else |
396 | static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) | 405 | static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) |
397 | { } | 406 | { } |
398 | static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) | 407 | static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) |
399 | { } | 408 | { } |
409 | static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } | ||
410 | static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } | ||
400 | #endif | 411 | #endif |
401 | int omap_mcbsp_request(unsigned int id); | 412 | int omap_mcbsp_request(unsigned int id); |
402 | void omap_mcbsp_free(unsigned int id); | 413 | void omap_mcbsp_free(unsigned int id); |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 081f2eace92d..0bbc912e548d 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -246,6 +246,42 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) | |||
246 | OMAP_MCBSP_WRITE(io_base, THRSH1, threshold); | 246 | OMAP_MCBSP_WRITE(io_base, THRSH1, threshold); |
247 | } | 247 | } |
248 | EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); | 248 | EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); |
249 | |||
250 | /* | ||
251 | * omap_mcbsp_get_max_tx_thres just return the current configured | ||
252 | * maximum threshold for transmission | ||
253 | */ | ||
254 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) | ||
255 | { | ||
256 | struct omap_mcbsp *mcbsp; | ||
257 | |||
258 | if (!omap_mcbsp_check_valid_id(id)) { | ||
259 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
260 | return -ENODEV; | ||
261 | } | ||
262 | mcbsp = id_to_mcbsp_ptr(id); | ||
263 | |||
264 | return mcbsp->max_tx_thres; | ||
265 | } | ||
266 | EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold); | ||
267 | |||
268 | /* | ||
269 | * omap_mcbsp_get_max_rx_thres just return the current configured | ||
270 | * maximum threshold for reception | ||
271 | */ | ||
272 | u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) | ||
273 | { | ||
274 | struct omap_mcbsp *mcbsp; | ||
275 | |||
276 | if (!omap_mcbsp_check_valid_id(id)) { | ||
277 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
278 | return -ENODEV; | ||
279 | } | ||
280 | mcbsp = id_to_mcbsp_ptr(id); | ||
281 | |||
282 | return mcbsp->max_rx_thres; | ||
283 | } | ||
284 | EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); | ||
249 | #endif | 285 | #endif |
250 | 286 | ||
251 | /* | 287 | /* |
@@ -1005,6 +1041,86 @@ void omap_mcbsp_set_spi_mode(unsigned int id, | |||
1005 | } | 1041 | } |
1006 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | 1042 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); |
1007 | 1043 | ||
1044 | #ifdef CONFIG_ARCH_OMAP34XX | ||
1045 | #define max_thres(m) (mcbsp->pdata->buffer_size) | ||
1046 | #define valid_threshold(m, val) ((val) <= max_thres(m)) | ||
1047 | #define THRESHOLD_PROP_BUILDER(prop) \ | ||
1048 | static ssize_t prop##_show(struct device *dev, \ | ||
1049 | struct device_attribute *attr, char *buf) \ | ||
1050 | { \ | ||
1051 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \ | ||
1052 | \ | ||
1053 | return sprintf(buf, "%u\n", mcbsp->prop); \ | ||
1054 | } \ | ||
1055 | \ | ||
1056 | static ssize_t prop##_store(struct device *dev, \ | ||
1057 | struct device_attribute *attr, \ | ||
1058 | const char *buf, size_t size) \ | ||
1059 | { \ | ||
1060 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \ | ||
1061 | unsigned long val; \ | ||
1062 | int status; \ | ||
1063 | \ | ||
1064 | status = strict_strtoul(buf, 0, &val); \ | ||
1065 | if (status) \ | ||
1066 | return status; \ | ||
1067 | \ | ||
1068 | if (!valid_threshold(mcbsp, val)) \ | ||
1069 | return -EDOM; \ | ||
1070 | \ | ||
1071 | mcbsp->prop = val; \ | ||
1072 | return size; \ | ||
1073 | } \ | ||
1074 | \ | ||
1075 | static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store); | ||
1076 | |||
1077 | THRESHOLD_PROP_BUILDER(max_tx_thres); | ||
1078 | THRESHOLD_PROP_BUILDER(max_rx_thres); | ||
1079 | |||
1080 | static const struct attribute *threshold_attrs[] = { | ||
1081 | &dev_attr_max_tx_thres.attr, | ||
1082 | &dev_attr_max_rx_thres.attr, | ||
1083 | NULL, | ||
1084 | }; | ||
1085 | |||
1086 | static const struct attribute_group threshold_attr_group = { | ||
1087 | .attrs = (struct attribute **)threshold_attrs, | ||
1088 | }; | ||
1089 | |||
1090 | static inline int __devinit omap_thres_add(struct device *dev) | ||
1091 | { | ||
1092 | return sysfs_create_group(&dev->kobj, &threshold_attr_group); | ||
1093 | } | ||
1094 | |||
1095 | static inline void __devexit omap_thres_remove(struct device *dev) | ||
1096 | { | ||
1097 | sysfs_remove_group(&dev->kobj, &threshold_attr_group); | ||
1098 | } | ||
1099 | |||
1100 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) | ||
1101 | { | ||
1102 | if (cpu_is_omap34xx()) { | ||
1103 | mcbsp->max_tx_thres = max_thres(mcbsp); | ||
1104 | mcbsp->max_rx_thres = max_thres(mcbsp); | ||
1105 | if (omap_thres_add(mcbsp->dev)) | ||
1106 | dev_warn(mcbsp->dev, | ||
1107 | "Unable to create threshold controls\n"); | ||
1108 | } else { | ||
1109 | mcbsp->max_tx_thres = -EINVAL; | ||
1110 | mcbsp->max_rx_thres = -EINVAL; | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) | ||
1115 | { | ||
1116 | if (cpu_is_omap34xx()) | ||
1117 | omap_thres_remove(mcbsp->dev); | ||
1118 | } | ||
1119 | #else | ||
1120 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {} | ||
1121 | static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {} | ||
1122 | #endif /* CONFIG_ARCH_OMAP34XX */ | ||
1123 | |||
1008 | /* | 1124 | /* |
1009 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. | 1125 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. |
1010 | * 730 has only 2 McBSP, and both of them are MPU peripherals. | 1126 | * 730 has only 2 McBSP, and both of them are MPU peripherals. |
@@ -1075,6 +1191,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | |||
1075 | mcbsp->dev = &pdev->dev; | 1191 | mcbsp->dev = &pdev->dev; |
1076 | mcbsp_ptr[id] = mcbsp; | 1192 | mcbsp_ptr[id] = mcbsp; |
1077 | platform_set_drvdata(pdev, mcbsp); | 1193 | platform_set_drvdata(pdev, mcbsp); |
1194 | |||
1195 | /* Initialize mcbsp properties for OMAP34XX if needed / applicable */ | ||
1196 | omap34xx_device_init(mcbsp); | ||
1197 | |||
1078 | return 0; | 1198 | return 0; |
1079 | 1199 | ||
1080 | err_fclk: | 1200 | err_fclk: |
@@ -1098,6 +1218,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) | |||
1098 | mcbsp->pdata->ops->free) | 1218 | mcbsp->pdata->ops->free) |
1099 | mcbsp->pdata->ops->free(mcbsp->id); | 1219 | mcbsp->pdata->ops->free(mcbsp->id); |
1100 | 1220 | ||
1221 | omap34xx_device_exit(mcbsp); | ||
1222 | |||
1101 | clk_disable(mcbsp->fclk); | 1223 | clk_disable(mcbsp->fclk); |
1102 | clk_disable(mcbsp->iclk); | 1224 | clk_disable(mcbsp->iclk); |
1103 | clk_put(mcbsp->fclk); | 1225 | clk_put(mcbsp->fclk); |