aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEduardo Valentin <eduardo.valentin@nokia.com>2009-08-20 09:18:11 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-20 15:10:26 -0400
commita1a56f5faa41327116bf960a8e79f21a8ea35dce (patch)
treeca6e8fba492f5a3caddf421d0c4f573d863bef99
parent7aa9ff56cae7a6a4fa2e1a503cc5f8bbd887d6e3 (diff)
OMAP: McBSP: Create and export max_(r|t)x_thres property
This patch export through sysfs two properties to configure maximum threshold for transmission and reception on each mcbsp instance. Also, it exports two helper functions to allow mcbsp users to read this values. Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-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);