aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h15
-rw-r--r--arch/arm/plat-omap/mcbsp.c120
2 files changed, 59 insertions, 76 deletions
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index eed20ef869f9..0fad63c7df18 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -354,10 +354,10 @@ struct omap_mcbsp {
354 struct clk *fclk; 354 struct clk *fclk;
355#ifdef CONFIG_ARCH_OMAP3 355#ifdef CONFIG_ARCH_OMAP3
356 struct omap_mcbsp_st_data *st_data; 356 struct omap_mcbsp_st_data *st_data;
357#endif
357 int dma_op_mode; 358 int dma_op_mode;
358 u16 max_tx_thres; 359 u16 max_tx_thres;
359 u16 max_rx_thres; 360 u16 max_rx_thres;
360#endif
361 void *reg_cache; 361 void *reg_cache;
362}; 362};
363 363
@@ -377,7 +377,6 @@ extern int omap_mcbsp_count, omap_mcbsp_cache_size;
377 377
378int omap_mcbsp_init(void); 378int omap_mcbsp_init(void);
379void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); 379void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
380#ifdef CONFIG_ARCH_OMAP3
381void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); 380void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
382void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); 381void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
383u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); 382u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
@@ -386,18 +385,6 @@ u16 omap_mcbsp_get_fifo_size(unsigned int id);
386u16 omap_mcbsp_get_tx_delay(unsigned int id); 385u16 omap_mcbsp_get_tx_delay(unsigned int id);
387u16 omap_mcbsp_get_rx_delay(unsigned int id); 386u16 omap_mcbsp_get_rx_delay(unsigned int id);
388int omap_mcbsp_get_dma_op_mode(unsigned int id); 387int omap_mcbsp_get_dma_op_mode(unsigned int id);
389#else
390static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
391{ }
392static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
393{ }
394static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
395static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
396static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; }
397static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; }
398static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; }
399static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
400#endif
401int omap_mcbsp_request(unsigned int id); 388int omap_mcbsp_request(unsigned int id);
402void omap_mcbsp_free(unsigned int id); 389void omap_mcbsp_free(unsigned int id);
403void omap_mcbsp_start(unsigned int id, int tx, int rx); 390void omap_mcbsp_start(unsigned int id, int tx, int rx);
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);