aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2009-08-20 09:18:14 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-20 15:10:27 -0400
commit98cb20e88957faf9c99e194242caac7f55dd47e4 (patch)
treee87f54f9cf9cba27a88711d336d4f4b6bdb3b396
parent4c8200aeb04b8aeaf8c7425f49caf761e2cda95a (diff)
OMAP: McBSP: Add link DMA mode selection
It adds a new sysfs file, where the user can configure the mcbsp mode to use. If the mcbsp channel is in use, it does not allow the change. Than in omap_pcm_open we can call the omap_mcbsp_get_opmode to get the mode, store it, than use it to implement the different modes. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> 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/plat-omap/include/mach/mcbsp.h8
-rw-r--r--arch/arm/plat-omap/mcbsp.c84
2 files changed, 92 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index 832330d7cb39..bd5b759991c8 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -255,6 +255,11 @@
255/********************** McBSP SYSCONFIG bit definitions ********************/ 255/********************** McBSP SYSCONFIG bit definitions ********************/
256#define SOFTRST 0x0002 256#define SOFTRST 0x0002
257 257
258/********************** McBSP DMA operating modes **************************/
259#define MCBSP_DMA_MODE_ELEMENT 0
260#define MCBSP_DMA_MODE_THRESHOLD 1
261#define MCBSP_DMA_MODE_FRAME 2
262
258/* we don't do multichannel for now */ 263/* we don't do multichannel for now */
259struct omap_mcbsp_reg_cfg { 264struct omap_mcbsp_reg_cfg {
260 u16 spcr2; 265 u16 spcr2;
@@ -385,6 +390,7 @@ struct omap_mcbsp {
385 struct clk *iclk; 390 struct clk *iclk;
386 struct clk *fclk; 391 struct clk *fclk;
387#ifdef CONFIG_ARCH_OMAP34XX 392#ifdef CONFIG_ARCH_OMAP34XX
393 int dma_op_mode;
388 u16 max_tx_thres; 394 u16 max_tx_thres;
389 u16 max_rx_thres; 395 u16 max_rx_thres;
390#endif 396#endif
@@ -401,6 +407,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
401void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); 407void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
402u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); 408u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
403u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); 409u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
410int omap_mcbsp_get_dma_op_mode(unsigned int id);
404#else 411#else
405static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) 412static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
406{ } 413{ }
@@ -408,6 +415,7 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
408{ } 415{ }
409static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } 416static 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; } 417static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
418static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
411#endif 419#endif
412int omap_mcbsp_request(unsigned int id); 420int omap_mcbsp_request(unsigned int id);
413void omap_mcbsp_free(unsigned int id); 421void omap_mcbsp_free(unsigned int id);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index ccaa9aedb0a2..9e699947a693 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -282,6 +282,29 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
282 return mcbsp->max_rx_thres; 282 return mcbsp->max_rx_thres;
283} 283}
284EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); 284EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
285
286/*
287 * omap_mcbsp_get_dma_op_mode just return the current configured
288 * operating mode for the mcbsp channel
289 */
290int omap_mcbsp_get_dma_op_mode(unsigned int id)
291{
292 struct omap_mcbsp *mcbsp;
293 int dma_op_mode;
294
295 if (!omap_mcbsp_check_valid_id(id)) {
296 printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
297 return -ENODEV;
298 }
299 mcbsp = id_to_mcbsp_ptr(id);
300
301 spin_lock_irq(&mcbsp->lock);
302 dma_op_mode = mcbsp->dma_op_mode;
303 spin_unlock_irq(&mcbsp->lock);
304
305 return dma_op_mode;
306}
307EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
285#endif 308#endif
286 309
287/* 310/*
@@ -1077,9 +1100,65 @@ static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
1077THRESHOLD_PROP_BUILDER(max_tx_thres); 1100THRESHOLD_PROP_BUILDER(max_tx_thres);
1078THRESHOLD_PROP_BUILDER(max_rx_thres); 1101THRESHOLD_PROP_BUILDER(max_rx_thres);
1079 1102
1103static ssize_t dma_op_mode_show(struct device *dev,
1104 struct device_attribute *attr, char *buf)
1105{
1106 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1107 int dma_op_mode;
1108
1109 spin_lock_irq(&mcbsp->lock);
1110 dma_op_mode = mcbsp->dma_op_mode;
1111 spin_unlock_irq(&mcbsp->lock);
1112
1113 return sprintf(buf, "current mode: %d\n"
1114 "possible mode values are:\n"
1115 "%d - %s\n"
1116 "%d - %s\n"
1117 "%d - %s\n",
1118 dma_op_mode,
1119 MCBSP_DMA_MODE_ELEMENT, "element mode",
1120 MCBSP_DMA_MODE_THRESHOLD, "threshold mode",
1121 MCBSP_DMA_MODE_FRAME, "frame mode");
1122}
1123
1124static ssize_t dma_op_mode_store(struct device *dev,
1125 struct device_attribute *attr,
1126 const char *buf, size_t size)
1127{
1128 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1129 unsigned long val;
1130 int status;
1131
1132 status = strict_strtoul(buf, 0, &val);
1133 if (status)
1134 return status;
1135
1136 spin_lock_irq(&mcbsp->lock);
1137
1138 if (!mcbsp->free) {
1139 size = -EBUSY;
1140 goto unlock;
1141 }
1142
1143 if (val > MCBSP_DMA_MODE_FRAME || val < MCBSP_DMA_MODE_ELEMENT) {
1144 size = -EINVAL;
1145 goto unlock;
1146 }
1147
1148 mcbsp->dma_op_mode = val;
1149
1150unlock:
1151 spin_unlock_irq(&mcbsp->lock);
1152
1153 return size;
1154}
1155
1156static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1157
1080static const struct attribute *additional_attrs[] = { 1158static const struct attribute *additional_attrs[] = {
1081 &dev_attr_max_tx_thres.attr, 1159 &dev_attr_max_tx_thres.attr,
1082 &dev_attr_max_rx_thres.attr, 1160 &dev_attr_max_rx_thres.attr,
1161 &dev_attr_dma_op_mode.attr,
1083 NULL, 1162 NULL,
1084}; 1163};
1085 1164
@@ -1099,9 +1178,14 @@ static inline void __devexit omap_additional_remove(struct device *dev)
1099 1178
1100static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) 1179static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1101{ 1180{
1181 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1102 if (cpu_is_omap34xx()) { 1182 if (cpu_is_omap34xx()) {
1103 mcbsp->max_tx_thres = max_thres(mcbsp); 1183 mcbsp->max_tx_thres = max_thres(mcbsp);
1104 mcbsp->max_rx_thres = max_thres(mcbsp); 1184 mcbsp->max_rx_thres = max_thres(mcbsp);
1185 /*
1186 * REVISIT: Set dmap_op_mode to THRESHOLD as default
1187 * for mcbsp2 instances.
1188 */
1105 if (omap_additional_add(mcbsp->dev)) 1189 if (omap_additional_add(mcbsp->dev))
1106 dev_warn(mcbsp->dev, 1190 dev_warn(mcbsp->dev,
1107 "Unable to create additional controls\n"); 1191 "Unable to create additional controls\n");