aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@bitmer.com>2011-09-26 03:45:42 -0400
committerTony Lindgren <tony@atomide.com>2011-09-26 20:48:10 -0400
commit7bba67ab3aa629f88e17786b07177b76b925cb0e (patch)
tree40af7b5d16397d15b5266e0ce74a8b7061c8fa4c /arch/arm/plat-omap/mcbsp.c
parent88408230d2fe752ffca0f292b092642cc5c153f1 (diff)
ARM: OMAP: mcbsp: Make threshold based transfer code generic
Remove CONFIG_ARCH_OMAP3 conditional compilation and cpu_is_omap34xx test around buffer threshold based transfer and DMA operating mode control. Use instead the buffer_size in platform data to determine when these sysfs controls are exposed and when to access related McBSP registers. Rationale for this is to make code generic and to allow to use it on OMAP4 that also supports threshold based transfers. Currently buffer_size variable is set only for OMAP3 SoCs but it is easy to extend to OMAP4 and any later OMAP version. Signed-off-by: Jarkko Nikula <jarkko.nikula@bitmer.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r--arch/arm/plat-omap/mcbsp.c120
1 files changed, 58 insertions, 62 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 97bcbfac068a..234ab16e8399 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -492,6 +492,11 @@ int omap_st_is_enabled(unsigned int id)
492} 492}
493EXPORT_SYMBOL(omap_st_is_enabled); 493EXPORT_SYMBOL(omap_st_is_enabled);
494 494
495#else
496static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
497static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
498#endif
499
495/* 500/*
496 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words. 501 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
497 * The threshold parameter is 1 based, and it is converted (threshold - 1) 502 * The threshold parameter is 1 based, and it is converted (threshold - 1)
@@ -501,14 +506,13 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
501{ 506{
502 struct omap_mcbsp *mcbsp; 507 struct omap_mcbsp *mcbsp;
503 508
504 if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
505 return;
506
507 if (!omap_mcbsp_check_valid_id(id)) { 509 if (!omap_mcbsp_check_valid_id(id)) {
508 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 510 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
509 return; 511 return;
510 } 512 }
511 mcbsp = id_to_mcbsp_ptr(id); 513 mcbsp = id_to_mcbsp_ptr(id);
514 if (mcbsp->pdata->buffer_size == 0)
515 return;
512 516
513 if (threshold && threshold <= mcbsp->max_tx_thres) 517 if (threshold && threshold <= mcbsp->max_tx_thres)
514 MCBSP_WRITE(mcbsp, THRSH2, threshold - 1); 518 MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
@@ -524,14 +528,13 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
524{ 528{
525 struct omap_mcbsp *mcbsp; 529 struct omap_mcbsp *mcbsp;
526 530
527 if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
528 return;
529
530 if (!omap_mcbsp_check_valid_id(id)) { 531 if (!omap_mcbsp_check_valid_id(id)) {
531 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 532 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
532 return; 533 return;
533 } 534 }
534 mcbsp = id_to_mcbsp_ptr(id); 535 mcbsp = id_to_mcbsp_ptr(id);
536 if (mcbsp->pdata->buffer_size == 0)
537 return;
535 538
536 if (threshold && threshold <= mcbsp->max_rx_thres) 539 if (threshold && threshold <= mcbsp->max_rx_thres)
537 MCBSP_WRITE(mcbsp, THRSH1, threshold - 1); 540 MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
@@ -601,6 +604,8 @@ u16 omap_mcbsp_get_tx_delay(unsigned int id)
601 return -ENODEV; 604 return -ENODEV;
602 } 605 }
603 mcbsp = id_to_mcbsp_ptr(id); 606 mcbsp = id_to_mcbsp_ptr(id);
607 if (mcbsp->pdata->buffer_size == 0)
608 return 0;
604 609
605 /* Returns the number of free locations in the buffer */ 610 /* Returns the number of free locations in the buffer */
606 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); 611 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
@@ -624,6 +629,8 @@ u16 omap_mcbsp_get_rx_delay(unsigned int id)
624 return -ENODEV; 629 return -ENODEV;
625 } 630 }
626 mcbsp = id_to_mcbsp_ptr(id); 631 mcbsp = id_to_mcbsp_ptr(id);
632 if (mcbsp->pdata->buffer_size == 0)
633 return 0;
627 634
628 /* Returns the number of used locations in the buffer */ 635 /* Returns the number of used locations in the buffer */
629 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT); 636 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
@@ -659,11 +666,6 @@ int omap_mcbsp_get_dma_op_mode(unsigned int id)
659} 666}
660EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); 667EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
661 668
662#else
663static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
664static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
665#endif
666
667int omap_mcbsp_request(unsigned int id) 669int omap_mcbsp_request(unsigned int id)
668{ 670{
669 struct omap_mcbsp *mcbsp; 671 struct omap_mcbsp *mcbsp;
@@ -937,7 +939,6 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux)
937} 939}
938#endif 940#endif
939 941
940#ifdef CONFIG_ARCH_OMAP3
941#define max_thres(m) (mcbsp->pdata->buffer_size) 942#define max_thres(m) (mcbsp->pdata->buffer_size)
942#define valid_threshold(m, val) ((val) <= max_thres(m)) 943#define valid_threshold(m, val) ((val) <= max_thres(m))
943#define THRESHOLD_PROP_BUILDER(prop) \ 944#define THRESHOLD_PROP_BUILDER(prop) \
@@ -1028,6 +1029,18 @@ unlock:
1028 1029
1029static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); 1030static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1030 1031
1032static const struct attribute *additional_attrs[] = {
1033 &dev_attr_max_tx_thres.attr,
1034 &dev_attr_max_rx_thres.attr,
1035 &dev_attr_dma_op_mode.attr,
1036 NULL,
1037};
1038
1039static const struct attribute_group additional_attr_group = {
1040 .attrs = (struct attribute **)additional_attrs,
1041};
1042
1043#ifdef CONFIG_ARCH_OMAP3
1031static ssize_t st_taps_show(struct device *dev, 1044static ssize_t st_taps_show(struct device *dev,
1032 struct device_attribute *attr, char *buf) 1045 struct device_attribute *attr, char *buf)
1033{ 1046{
@@ -1086,27 +1099,6 @@ out:
1086 1099
1087static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store); 1100static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
1088 1101
1089static const struct attribute *additional_attrs[] = {
1090 &dev_attr_max_tx_thres.attr,
1091 &dev_attr_max_rx_thres.attr,
1092 &dev_attr_dma_op_mode.attr,
1093 NULL,
1094};
1095
1096static const struct attribute_group additional_attr_group = {
1097 .attrs = (struct attribute **)additional_attrs,
1098};
1099
1100static inline int __devinit omap_additional_add(struct device *dev)
1101{
1102 return sysfs_create_group(&dev->kobj, &additional_attr_group);
1103}
1104
1105static inline void __devexit omap_additional_remove(struct device *dev)
1106{
1107 sysfs_remove_group(&dev->kobj, &additional_attr_group);
1108}
1109
1110static const struct attribute *sidetone_attrs[] = { 1102static const struct attribute *sidetone_attrs[] = {
1111 &dev_attr_st_taps.attr, 1103 &dev_attr_st_taps.attr,
1112 NULL, 1104 NULL,
@@ -1167,45 +1159,18 @@ static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
1167 1159
1168static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) 1160static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1169{ 1161{
1170 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; 1162 if (cpu_is_omap34xx())
1171 if (cpu_is_omap34xx()) {
1172 /*
1173 * Initially configure the maximum thresholds to a safe value.
1174 * The McBSP FIFO usage with these values should not go under
1175 * 16 locations.
1176 * If the whole FIFO without safety buffer is used, than there
1177 * is a possibility that the DMA will be not able to push the
1178 * new data on time, causing channel shifts in runtime.
1179 */
1180 mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
1181 mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
1182 /*
1183 * REVISIT: Set dmap_op_mode to THRESHOLD as default
1184 * for mcbsp2 instances.
1185 */
1186 if (omap_additional_add(mcbsp->dev))
1187 dev_warn(mcbsp->dev,
1188 "Unable to create additional controls\n");
1189
1190 if (mcbsp->id == 2 || mcbsp->id == 3) 1163 if (mcbsp->id == 2 || mcbsp->id == 3)
1191 if (omap_st_add(mcbsp)) 1164 if (omap_st_add(mcbsp))
1192 dev_warn(mcbsp->dev, 1165 dev_warn(mcbsp->dev,
1193 "Unable to create sidetone controls\n"); 1166 "Unable to create sidetone controls\n");
1194
1195 } else {
1196 mcbsp->max_tx_thres = -EINVAL;
1197 mcbsp->max_rx_thres = -EINVAL;
1198 }
1199} 1167}
1200 1168
1201static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) 1169static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
1202{ 1170{
1203 if (cpu_is_omap34xx()) { 1171 if (cpu_is_omap34xx())
1204 omap_additional_remove(mcbsp->dev);
1205
1206 if (mcbsp->id == 2 || mcbsp->id == 3) 1172 if (mcbsp->id == 2 || mcbsp->id == 3)
1207 omap_st_remove(mcbsp); 1173 omap_st_remove(mcbsp);
1208 }
1209} 1174}
1210#else 1175#else
1211static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {} 1176static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
@@ -1311,11 +1276,38 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
1311 platform_set_drvdata(pdev, mcbsp); 1276 platform_set_drvdata(pdev, mcbsp);
1312 pm_runtime_enable(mcbsp->dev); 1277 pm_runtime_enable(mcbsp->dev);
1313 1278
1279 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1280 if (mcbsp->pdata->buffer_size) {
1281 /*
1282 * Initially configure the maximum thresholds to a safe value.
1283 * The McBSP FIFO usage with these values should not go under
1284 * 16 locations.
1285 * If the whole FIFO without safety buffer is used, than there
1286 * is a possibility that the DMA will be not able to push the
1287 * new data on time, causing channel shifts in runtime.
1288 */
1289 mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
1290 mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
1291
1292 ret = sysfs_create_group(&mcbsp->dev->kobj,
1293 &additional_attr_group);
1294 if (ret) {
1295 dev_err(mcbsp->dev,
1296 "Unable to create additional controls\n");
1297 goto err_thres;
1298 }
1299 } else {
1300 mcbsp->max_tx_thres = -EINVAL;
1301 mcbsp->max_rx_thres = -EINVAL;
1302 }
1303
1314 /* Initialize mcbsp properties for OMAP34XX if needed / applicable */ 1304 /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
1315 omap34xx_device_init(mcbsp); 1305 omap34xx_device_init(mcbsp);
1316 1306
1317 return 0; 1307 return 0;
1318 1308
1309err_thres:
1310 clk_put(mcbsp->fclk);
1319err_res: 1311err_res:
1320 iounmap(mcbsp->io_base); 1312 iounmap(mcbsp->io_base);
1321err_ioremap: 1313err_ioremap:
@@ -1335,6 +1327,10 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
1335 mcbsp->pdata->ops->free) 1327 mcbsp->pdata->ops->free)
1336 mcbsp->pdata->ops->free(mcbsp->id); 1328 mcbsp->pdata->ops->free(mcbsp->id);
1337 1329
1330 if (mcbsp->pdata->buffer_size)
1331 sysfs_remove_group(&mcbsp->dev->kobj,
1332 &additional_attr_group);
1333
1338 omap34xx_device_exit(mcbsp); 1334 omap34xx_device_exit(mcbsp);
1339 1335
1340 clk_put(mcbsp->fclk); 1336 clk_put(mcbsp->fclk);