diff options
author | Peter Ujfalusi <peter.ujfalusi@nokia.com> | 2009-08-20 09:18:14 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-08-20 15:10:27 -0400 |
commit | 98cb20e88957faf9c99e194242caac7f55dd47e4 (patch) | |
tree | e87f54f9cf9cba27a88711d336d4f4b6bdb3b396 /arch/arm/plat-omap/mcbsp.c | |
parent | 4c8200aeb04b8aeaf8c7425f49caf761e2cda95a (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>
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 84 |
1 files changed, 84 insertions, 0 deletions
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 | } |
284 | EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); | 284 | EXPORT_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 | */ | ||
290 | int 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 | } | ||
307 | EXPORT_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); | |||
1077 | THRESHOLD_PROP_BUILDER(max_tx_thres); | 1100 | THRESHOLD_PROP_BUILDER(max_tx_thres); |
1078 | THRESHOLD_PROP_BUILDER(max_rx_thres); | 1101 | THRESHOLD_PROP_BUILDER(max_rx_thres); |
1079 | 1102 | ||
1103 | static 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 | |||
1124 | static 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 | |||
1150 | unlock: | ||
1151 | spin_unlock_irq(&mcbsp->lock); | ||
1152 | |||
1153 | return size; | ||
1154 | } | ||
1155 | |||
1156 | static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); | ||
1157 | |||
1080 | static const struct attribute *additional_attrs[] = { | 1158 | static 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 | ||
1100 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) | 1179 | static 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"); |