diff options
| -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); |
