diff options
-rw-r--r-- | arch/arm/plat-omap/include/plat/mcbsp.h | 15 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 120 |
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 | ||
378 | int omap_mcbsp_init(void); | 378 | int omap_mcbsp_init(void); |
379 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); | 379 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); |
380 | #ifdef CONFIG_ARCH_OMAP3 | ||
381 | void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); | 380 | void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); |
382 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); | 381 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); |
383 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); | 382 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); |
@@ -386,18 +385,6 @@ u16 omap_mcbsp_get_fifo_size(unsigned int id); | |||
386 | u16 omap_mcbsp_get_tx_delay(unsigned int id); | 385 | u16 omap_mcbsp_get_tx_delay(unsigned int id); |
387 | u16 omap_mcbsp_get_rx_delay(unsigned int id); | 386 | u16 omap_mcbsp_get_rx_delay(unsigned int id); |
388 | int omap_mcbsp_get_dma_op_mode(unsigned int id); | 387 | int omap_mcbsp_get_dma_op_mode(unsigned int id); |
389 | #else | ||
390 | static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) | ||
391 | { } | ||
392 | static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) | ||
393 | { } | ||
394 | static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } | ||
395 | static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } | ||
396 | static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; } | ||
397 | static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; } | ||
398 | static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; } | ||
399 | static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } | ||
400 | #endif | ||
401 | int omap_mcbsp_request(unsigned int id); | 388 | int omap_mcbsp_request(unsigned int id); |
402 | void omap_mcbsp_free(unsigned int id); | 389 | void omap_mcbsp_free(unsigned int id); |
403 | void omap_mcbsp_start(unsigned int id, int tx, int rx); | 390 | void 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 | } |
493 | EXPORT_SYMBOL(omap_st_is_enabled); | 493 | EXPORT_SYMBOL(omap_st_is_enabled); |
494 | 494 | ||
495 | #else | ||
496 | static inline void omap_st_start(struct omap_mcbsp *mcbsp) {} | ||
497 | static 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 | } |
660 | EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); | 667 | EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); |
661 | 668 | ||
662 | #else | ||
663 | static inline void omap_st_start(struct omap_mcbsp *mcbsp) {} | ||
664 | static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {} | ||
665 | #endif | ||
666 | |||
667 | int omap_mcbsp_request(unsigned int id) | 669 | int 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 | ||
1029 | static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); | 1030 | static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); |
1030 | 1031 | ||
1032 | static 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 | |||
1039 | static const struct attribute_group additional_attr_group = { | ||
1040 | .attrs = (struct attribute **)additional_attrs, | ||
1041 | }; | ||
1042 | |||
1043 | #ifdef CONFIG_ARCH_OMAP3 | ||
1031 | static ssize_t st_taps_show(struct device *dev, | 1044 | static 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 | ||
1087 | static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store); | 1100 | static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store); |
1088 | 1101 | ||
1089 | static 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 | |||
1096 | static const struct attribute_group additional_attr_group = { | ||
1097 | .attrs = (struct attribute **)additional_attrs, | ||
1098 | }; | ||
1099 | |||
1100 | static inline int __devinit omap_additional_add(struct device *dev) | ||
1101 | { | ||
1102 | return sysfs_create_group(&dev->kobj, &additional_attr_group); | ||
1103 | } | ||
1104 | |||
1105 | static inline void __devexit omap_additional_remove(struct device *dev) | ||
1106 | { | ||
1107 | sysfs_remove_group(&dev->kobj, &additional_attr_group); | ||
1108 | } | ||
1109 | |||
1110 | static const struct attribute *sidetone_attrs[] = { | 1102 | static 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 | ||
1168 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) | 1160 | static 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 | ||
1201 | static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) | 1169 | static 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 |
1211 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {} | 1176 | static 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 | ||
1309 | err_thres: | ||
1310 | clk_put(mcbsp->fclk); | ||
1319 | err_res: | 1311 | err_res: |
1320 | iounmap(mcbsp->io_base); | 1312 | iounmap(mcbsp->io_base); |
1321 | err_ioremap: | 1313 | err_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); |