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 | |
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>
-rw-r--r-- | arch/arm/plat-omap/include/mach/mcbsp.h | 8 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 84 |
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 */ |
259 | struct omap_mcbsp_reg_cfg { | 264 | struct 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); | |||
401 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); | 407 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); |
402 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); | 408 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); |
403 | u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); | 409 | u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); |
410 | int omap_mcbsp_get_dma_op_mode(unsigned int id); | ||
404 | #else | 411 | #else |
405 | static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) | 412 | static 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 | { } |
409 | static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } | 416 | 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; } | 417 | static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } |
418 | static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } | ||
411 | #endif | 419 | #endif |
412 | int omap_mcbsp_request(unsigned int id); | 420 | int omap_mcbsp_request(unsigned int id); |
413 | void omap_mcbsp_free(unsigned int id); | 421 | void 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 | } |
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"); |