aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/mcbsp.c5
-rw-r--r--arch/arm/plat-omap/include/mach/mcbsp.h11
-rw-r--r--arch/arm/plat-omap/mcbsp.c122
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
353struct omap_mcbsp { 356struct 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};
385extern struct omap_mcbsp **mcbsp_ptr; 392extern struct omap_mcbsp **mcbsp_ptr;
386extern int omap_mcbsp_count; 393extern 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
393void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); 400void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
394void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); 401void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
402u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
403u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
395#else 404#else
396static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) 405static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
397{ } 406{ }
398static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) 407static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
399{ } 408{ }
409static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
410static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
400#endif 411#endif
401int omap_mcbsp_request(unsigned int id); 412int omap_mcbsp_request(unsigned int id);
402void omap_mcbsp_free(unsigned int id); 413void 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}
248EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); 248EXPORT_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 */
254u16 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}
266EXPORT_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 */
272u16 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}
284EXPORT_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}
1006EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); 1042EXPORT_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) \
1048static 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 \
1056static 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 \
1075static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
1076
1077THRESHOLD_PROP_BUILDER(max_tx_thres);
1078THRESHOLD_PROP_BUILDER(max_rx_thres);
1079
1080static const struct attribute *threshold_attrs[] = {
1081 &dev_attr_max_tx_thres.attr,
1082 &dev_attr_max_rx_thres.attr,
1083 NULL,
1084};
1085
1086static const struct attribute_group threshold_attr_group = {
1087 .attrs = (struct attribute **)threshold_attrs,
1088};
1089
1090static inline int __devinit omap_thres_add(struct device *dev)
1091{
1092 return sysfs_create_group(&dev->kobj, &threshold_attr_group);
1093}
1094
1095static inline void __devexit omap_thres_remove(struct device *dev)
1096{
1097 sysfs_remove_group(&dev->kobj, &threshold_attr_group);
1098}
1099
1100static 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
1114static 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
1120static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
1121static 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
1080err_fclk: 1200err_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);