Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: sirf: Add audio usp interface driver

This patch adds ASoC support for SiRF SoCs USP interface.
Features include:
1. Only support slave mode.
2. Support I2S and DSP_A mode.
3. Support S16_LE, S24_LE and S24_3LE formats.
4. Support stereo and mono mode.
5. The biggest Support is 192Khz sample rate.

Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Mark Brown <broonie@linaro.org>

authored by

Rongjun Ying and committed by
Mark Brown
2bd8d1d5 7171511e

+716
+6
sound/soc/sirf/Kconfig
··· 12 12 config SND_SOC_SIRF_AUDIO_PORT 13 13 select REGMAP_MMIO 14 14 tristate 15 + 16 + config SND_SOC_SIRF_USP 17 + tristate "SoC Audio (I2S protocol) for SiRF SoC USP interface" 18 + depends on SND_SOC_SIRF 19 + select REGMAP_MMIO 20 + tristate
+2
sound/soc/sirf/Makefile
··· 1 1 snd-soc-sirf-audio-objs := sirf-audio.o 2 2 snd-soc-sirf-audio-port-objs := sirf-audio-port.o 3 + snd-soc-sirf-usp-objs := sirf-usp.o 3 4 4 5 obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o 5 6 obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o 7 + obj-$(CONFIG_SND_SOC_SIRF_USP) += snd-soc-sirf-usp.o
+415
sound/soc/sirf/sirf-usp.c
··· 1 + /* 2 + * SiRF USP in I2S/DSP mode 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + #include <linux/module.h> 9 + #include <linux/io.h> 10 + #include <linux/of.h> 11 + #include <linux/clk.h> 12 + #include <linux/pm_runtime.h> 13 + #include <sound/soc.h> 14 + #include <sound/pcm_params.h> 15 + #include <sound/dmaengine_pcm.h> 16 + 17 + #include "sirf-usp.h" 18 + 19 + struct sirf_usp { 20 + struct regmap *regmap; 21 + struct clk *clk; 22 + u32 mode1_reg; 23 + u32 mode2_reg; 24 + int daifmt_format; 25 + struct snd_dmaengine_dai_dma_data playback_dma_data; 26 + struct snd_dmaengine_dai_dma_data capture_dma_data; 27 + }; 28 + 29 + static void sirf_usp_tx_enable(struct sirf_usp *usp) 30 + { 31 + regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, 32 + USP_TX_FIFO_RESET, USP_TX_FIFO_RESET); 33 + regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); 34 + 35 + regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, 36 + USP_TX_FIFO_START, USP_TX_FIFO_START); 37 + 38 + regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, 39 + USP_TX_ENA, USP_TX_ENA); 40 + } 41 + 42 + static void sirf_usp_tx_disable(struct sirf_usp *usp) 43 + { 44 + regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, 45 + USP_TX_ENA, ~USP_TX_ENA); 46 + /* FIFO stop */ 47 + regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); 48 + } 49 + 50 + static void sirf_usp_rx_enable(struct sirf_usp *usp) 51 + { 52 + regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, 53 + USP_RX_FIFO_RESET, USP_RX_FIFO_RESET); 54 + regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); 55 + 56 + regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, 57 + USP_RX_FIFO_START, USP_RX_FIFO_START); 58 + 59 + regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, 60 + USP_RX_ENA, USP_RX_ENA); 61 + } 62 + 63 + static void sirf_usp_rx_disable(struct sirf_usp *usp) 64 + { 65 + regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, 66 + USP_RX_ENA, ~USP_RX_ENA); 67 + /* FIFO stop */ 68 + regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); 69 + } 70 + 71 + static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai) 72 + { 73 + struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 74 + snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data, 75 + &usp->capture_dma_data); 76 + return 0; 77 + } 78 + 79 + static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai, 80 + unsigned int fmt) 81 + { 82 + struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 83 + 84 + /* set master/slave audio interface */ 85 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 86 + case SND_SOC_DAIFMT_CBM_CFM: 87 + break; 88 + default: 89 + dev_err(dai->dev, "Only CBM and CFM supported\n"); 90 + return -EINVAL; 91 + } 92 + 93 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 94 + case SND_SOC_DAIFMT_I2S: 95 + case SND_SOC_DAIFMT_DSP_A: 96 + usp->daifmt_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK); 97 + break; 98 + default: 99 + dev_err(dai->dev, "Only I2S and DSP_A format supported\n"); 100 + return -EINVAL; 101 + } 102 + 103 + return 0; 104 + } 105 + 106 + static int sirf_usp_i2s_startup(struct snd_pcm_substream *substream, 107 + struct snd_soc_dai *dai) 108 + { 109 + struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 110 + 111 + /* Configure RISC mode */ 112 + regmap_update_bits(usp->regmap, USP_RISC_DSP_MODE, 113 + USP_RISC_DSP_SEL, ~USP_RISC_DSP_SEL); 114 + 115 + /* 116 + * Configure DMA IO Length register 117 + * Set no limit, USP can receive data continuously until it is diabled 118 + */ 119 + regmap_write(usp->regmap, USP_TX_DMA_IO_LEN, 0); 120 + regmap_write(usp->regmap, USP_RX_DMA_IO_LEN, 0); 121 + 122 + regmap_write(usp->regmap, USP_RX_FRAME_CTRL, USP_SINGLE_SYNC_MODE); 123 + 124 + regmap_write(usp->regmap, USP_TX_FRAME_CTRL, USP_TXC_SLAVE_CLK_SAMPLE); 125 + 126 + /* Configure Mode2 register */ 127 + regmap_write(usp->regmap, USP_MODE2, (1 << USP_RXD_DELAY_LEN_OFFSET) | 128 + (0 << USP_TXD_DELAY_LEN_OFFSET)); 129 + 130 + /* Configure Mode1 register */ 131 + regmap_write(usp->regmap, USP_MODE1, 132 + USP_SYNC_MODE | USP_EN | USP_TXD_ACT_EDGE_FALLING | 133 + USP_RFS_ACT_LEVEL_LOGIC1 | USP_TFS_ACT_LEVEL_LOGIC1 | 134 + USP_TX_UFLOW_REPEAT_ZERO); 135 + 136 + /* Configure RX DMA IO Control register */ 137 + regmap_write(usp->regmap, USP_RX_DMA_IO_CTRL, 0); 138 + 139 + /* Congiure RX FIFO Control register */ 140 + regmap_write(usp->regmap, USP_RX_FIFO_CTRL, 141 + (USP_RX_FIFO_THRESHOLD << USP_RX_FIFO_THD_OFFSET) | 142 + (USP_TX_RX_FIFO_WIDTH_DWORD << USP_RX_FIFO_WIDTH_OFFSET)); 143 + 144 + /* Congiure RX FIFO Level Check register */ 145 + regmap_write(usp->regmap, USP_RX_FIFO_LEVEL_CHK, 146 + RX_FIFO_SC(0x04) | RX_FIFO_LC(0x0E) | RX_FIFO_HC(0x1B)); 147 + 148 + /* Configure TX DMA IO Control register*/ 149 + regmap_write(usp->regmap, USP_TX_DMA_IO_CTRL, 0); 150 + 151 + /* Configure TX FIFO Control register */ 152 + regmap_write(usp->regmap, USP_TX_FIFO_CTRL, 153 + (USP_TX_FIFO_THRESHOLD << USP_TX_FIFO_THD_OFFSET) | 154 + (USP_TX_RX_FIFO_WIDTH_DWORD << USP_TX_FIFO_WIDTH_OFFSET)); 155 + /* Congiure TX FIFO Level Check register */ 156 + regmap_write(usp->regmap, USP_TX_FIFO_LEVEL_CHK, 157 + TX_FIFO_SC(0x1B) | TX_FIFO_LC(0x0E) | TX_FIFO_HC(0x04)); 158 + 159 + return 0; 160 + } 161 + 162 + static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream, 163 + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 164 + { 165 + struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 166 + u32 data_len, frame_len, shifter_len; 167 + 168 + switch (params_format(params)) { 169 + case SNDRV_PCM_FORMAT_S16_LE: 170 + data_len = 16; 171 + frame_len = 16; 172 + break; 173 + case SNDRV_PCM_FORMAT_S24_LE: 174 + data_len = 24; 175 + frame_len = 32; 176 + break; 177 + case SNDRV_PCM_FORMAT_S24_3LE: 178 + data_len = 24; 179 + frame_len = 24; 180 + break; 181 + default: 182 + dev_err(dai->dev, "Format unsupported\n"); 183 + return -EINVAL; 184 + } 185 + 186 + shifter_len = data_len; 187 + 188 + switch (usp->daifmt_format) { 189 + case SND_SOC_DAIFMT_I2S: 190 + regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, 191 + USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG); 192 + break; 193 + case SND_SOC_DAIFMT_DSP_A: 194 + regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, 195 + USP_I2S_SYNC_CHG, 0); 196 + frame_len = data_len * params_channels(params); 197 + data_len = frame_len; 198 + break; 199 + default: 200 + dev_err(dai->dev, "Only support I2S and DSP_A mode\n"); 201 + return -EINVAL; 202 + } 203 + 204 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 205 + regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL, 206 + USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK 207 + | USP_TXC_SHIFTER_LEN_MASK, 208 + ((data_len - 1) << USP_TXC_DATA_LEN_OFFSET) 209 + | ((frame_len - 1) << USP_TXC_FRAME_LEN_OFFSET) 210 + | ((shifter_len - 1) << USP_TXC_SHIFTER_LEN_OFFSET)); 211 + else 212 + regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, 213 + USP_RXC_DATA_LEN_MASK | USP_RXC_FRAME_LEN_MASK 214 + | USP_RXC_SHIFTER_LEN_MASK, 215 + ((data_len - 1) << USP_RXC_DATA_LEN_OFFSET) 216 + | ((frame_len - 1) << USP_RXC_FRAME_LEN_OFFSET) 217 + | ((shifter_len - 1) << USP_RXC_SHIFTER_LEN_OFFSET)); 218 + 219 + regmap_update_bits(usp->regmap, USP_MODE1, 220 + USP_CLOCK_MODE_SLAVE, USP_CLOCK_MODE_SLAVE); 221 + regmap_update_bits(usp->regmap, USP_MODE2, 222 + USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE, 223 + USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE); 224 + 225 + return 0; 226 + } 227 + 228 + static int sirf_usp_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 229 + struct snd_soc_dai *dai) 230 + { 231 + struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 232 + 233 + switch (cmd) { 234 + case SNDRV_PCM_TRIGGER_START: 235 + case SNDRV_PCM_TRIGGER_RESUME: 236 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 237 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 238 + sirf_usp_tx_enable(usp); 239 + else 240 + sirf_usp_rx_enable(usp); 241 + break; 242 + case SNDRV_PCM_TRIGGER_STOP: 243 + case SNDRV_PCM_TRIGGER_SUSPEND: 244 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 245 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 246 + sirf_usp_tx_disable(usp); 247 + else 248 + sirf_usp_rx_disable(usp); 249 + break; 250 + } 251 + 252 + return 0; 253 + } 254 + 255 + static const struct snd_soc_dai_ops sirf_usp_pcm_dai_ops = { 256 + .startup = sirf_usp_i2s_startup, 257 + .trigger = sirf_usp_pcm_trigger, 258 + .set_fmt = sirf_usp_pcm_set_dai_fmt, 259 + .hw_params = sirf_usp_pcm_hw_params, 260 + }; 261 + 262 + static struct snd_soc_dai_driver sirf_usp_pcm_dai = { 263 + .probe = sirf_usp_pcm_dai_probe, 264 + .name = "sirf-usp-pcm", 265 + .id = 0, 266 + .playback = { 267 + .stream_name = "SiRF USP PCM Playback", 268 + .channels_min = 1, 269 + .channels_max = 2, 270 + .rates = SNDRV_PCM_RATE_8000_192000, 271 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 272 + SNDRV_PCM_FMTBIT_S24_3LE, 273 + }, 274 + .capture = { 275 + .stream_name = "SiRF USP PCM Capture", 276 + .channels_min = 1, 277 + .channels_max = 2, 278 + .rates = SNDRV_PCM_RATE_8000_192000, 279 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 280 + SNDRV_PCM_FMTBIT_S24_3LE, 281 + }, 282 + .ops = &sirf_usp_pcm_dai_ops, 283 + }; 284 + 285 + #ifdef CONFIG_PM_RUNTIME 286 + static int sirf_usp_pcm_runtime_suspend(struct device *dev) 287 + { 288 + struct sirf_usp *usp = dev_get_drvdata(dev); 289 + clk_disable_unprepare(usp->clk); 290 + return 0; 291 + } 292 + 293 + static int sirf_usp_pcm_runtime_resume(struct device *dev) 294 + { 295 + struct sirf_usp *usp = dev_get_drvdata(dev); 296 + return clk_prepare_enable(usp->clk); 297 + } 298 + #endif 299 + 300 + #ifdef CONFIG_PM_SLEEP 301 + static int sirf_usp_pcm_suspend(struct device *dev) 302 + { 303 + struct sirf_usp *usp = dev_get_drvdata(dev); 304 + 305 + if (!pm_runtime_status_suspended(dev)) { 306 + regmap_read(usp->regmap, USP_MODE1, &usp->mode1_reg); 307 + regmap_read(usp->regmap, USP_MODE2, &usp->mode2_reg); 308 + sirf_usp_pcm_runtime_suspend(dev); 309 + } 310 + return 0; 311 + } 312 + 313 + static int sirf_usp_pcm_resume(struct device *dev) 314 + { 315 + struct sirf_usp *usp = dev_get_drvdata(dev); 316 + int ret; 317 + 318 + if (!pm_runtime_status_suspended(dev)) { 319 + ret = sirf_usp_pcm_runtime_resume(dev); 320 + if (ret) 321 + return ret; 322 + regmap_write(usp->regmap, USP_MODE1, usp->mode1_reg); 323 + regmap_write(usp->regmap, USP_MODE2, usp->mode2_reg); 324 + } 325 + return 0; 326 + } 327 + #endif 328 + 329 + static const struct snd_soc_component_driver sirf_usp_component = { 330 + .name = "sirf-usp", 331 + }; 332 + 333 + static const struct regmap_config sirf_usp_regmap_config = { 334 + .reg_bits = 32, 335 + .reg_stride = 4, 336 + .val_bits = 32, 337 + .max_register = USP_RX_FIFO_DATA, 338 + .cache_type = REGCACHE_NONE, 339 + }; 340 + 341 + static int sirf_usp_pcm_probe(struct platform_device *pdev) 342 + { 343 + int ret; 344 + struct sirf_usp *usp; 345 + void __iomem *base; 346 + struct resource *mem_res; 347 + 348 + usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), 349 + GFP_KERNEL); 350 + if (!usp) 351 + return -ENOMEM; 352 + 353 + platform_set_drvdata(pdev, usp); 354 + 355 + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 356 + base = devm_ioremap(&pdev->dev, mem_res->start, 357 + resource_size(mem_res)); 358 + if (base == NULL) 359 + return -ENOMEM; 360 + usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, 361 + &sirf_usp_regmap_config); 362 + if (IS_ERR(usp->regmap)) 363 + return PTR_ERR(usp->regmap); 364 + 365 + usp->clk = devm_clk_get(&pdev->dev, NULL); 366 + if (IS_ERR(usp->clk)) { 367 + dev_err(&pdev->dev, "Get clock failed.\n"); 368 + return PTR_ERR(usp->clk); 369 + } 370 + 371 + pm_runtime_enable(&pdev->dev); 372 + 373 + ret = devm_snd_soc_register_component(&pdev->dev, &sirf_usp_component, 374 + &sirf_usp_pcm_dai, 1); 375 + if (ret) { 376 + dev_err(&pdev->dev, "Register Audio SoC dai failed.\n"); 377 + return ret; 378 + } 379 + return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 380 + } 381 + 382 + static int sirf_usp_pcm_remove(struct platform_device *pdev) 383 + { 384 + pm_runtime_disable(&pdev->dev); 385 + return 0; 386 + } 387 + 388 + static const struct of_device_id sirf_usp_pcm_of_match[] = { 389 + { .compatible = "sirf,prima2-usp-pcm", }, 390 + {} 391 + }; 392 + MODULE_DEVICE_TABLE(of, sirf_usp_pcm_of_match); 393 + 394 + static const struct dev_pm_ops sirf_usp_pcm_pm_ops = { 395 + SET_RUNTIME_PM_OPS(sirf_usp_pcm_runtime_suspend, 396 + sirf_usp_pcm_runtime_resume, NULL) 397 + SET_SYSTEM_SLEEP_PM_OPS(sirf_usp_pcm_suspend, sirf_usp_pcm_resume) 398 + }; 399 + 400 + static struct platform_driver sirf_usp_pcm_driver = { 401 + .driver = { 402 + .name = "sirf-usp-pcm", 403 + .owner = THIS_MODULE, 404 + .of_match_table = sirf_usp_pcm_of_match, 405 + .pm = &sirf_usp_pcm_pm_ops, 406 + }, 407 + .probe = sirf_usp_pcm_probe, 408 + .remove = sirf_usp_pcm_remove, 409 + }; 410 + 411 + module_platform_driver(sirf_usp_pcm_driver); 412 + 413 + MODULE_DESCRIPTION("SiRF SoC USP PCM bus driver"); 414 + MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); 415 + MODULE_LICENSE("GPL v2");
+293
sound/soc/sirf/sirf-usp.h
··· 1 + /* 2 + * arch/arm/mach-prima2/include/mach/sirfsoc_usp.h 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + 9 + #ifndef _SIRF_USP_H 10 + #define _SIRF_USP_H 11 + 12 + /* USP Registers */ 13 + #define USP_MODE1 0x00 14 + #define USP_MODE2 0x04 15 + #define USP_TX_FRAME_CTRL 0x08 16 + #define USP_RX_FRAME_CTRL 0x0C 17 + #define USP_TX_RX_ENABLE 0x10 18 + #define USP_INT_ENABLE 0x14 19 + #define USP_INT_STATUS 0x18 20 + #define USP_PIN_IO_DATA 0x1C 21 + #define USP_RISC_DSP_MODE 0x20 22 + #define USP_AYSNC_PARAM_REG 0x24 23 + #define USP_IRDA_X_MODE_DIV 0x28 24 + #define USP_SM_CFG 0x2C 25 + #define USP_TX_DMA_IO_CTRL 0x100 26 + #define USP_TX_DMA_IO_LEN 0x104 27 + #define USP_TX_FIFO_CTRL 0x108 28 + #define USP_TX_FIFO_LEVEL_CHK 0x10C 29 + #define USP_TX_FIFO_OP 0x110 30 + #define USP_TX_FIFO_STATUS 0x114 31 + #define USP_TX_FIFO_DATA 0x118 32 + #define USP_RX_DMA_IO_CTRL 0x120 33 + #define USP_RX_DMA_IO_LEN 0x124 34 + #define USP_RX_FIFO_CTRL 0x128 35 + #define USP_RX_FIFO_LEVEL_CHK 0x12C 36 + #define USP_RX_FIFO_OP 0x130 37 + #define USP_RX_FIFO_STATUS 0x134 38 + #define USP_RX_FIFO_DATA 0x138 39 + 40 + /* USP MODE register-1 */ 41 + #define USP_SYNC_MODE 0x00000001 42 + #define USP_CLOCK_MODE_SLAVE 0x00000002 43 + #define USP_LOOP_BACK_EN 0x00000004 44 + #define USP_HPSIR_EN 0x00000008 45 + #define USP_ENDIAN_CTRL_LSBF 0x00000010 46 + #define USP_EN 0x00000020 47 + #define USP_RXD_ACT_EDGE_FALLING 0x00000040 48 + #define USP_TXD_ACT_EDGE_FALLING 0x00000080 49 + #define USP_RFS_ACT_LEVEL_LOGIC1 0x00000100 50 + #define USP_TFS_ACT_LEVEL_LOGIC1 0x00000200 51 + #define USP_SCLK_IDLE_MODE_TOGGLE 0x00000400 52 + #define USP_SCLK_IDLE_LEVEL_LOGIC1 0x00000800 53 + #define USP_SCLK_PIN_MODE_IO 0x00001000 54 + #define USP_RFS_PIN_MODE_IO 0x00002000 55 + #define USP_TFS_PIN_MODE_IO 0x00004000 56 + #define USP_RXD_PIN_MODE_IO 0x00008000 57 + #define USP_TXD_PIN_MODE_IO 0x00010000 58 + #define USP_SCLK_IO_MODE_INPUT 0x00020000 59 + #define USP_RFS_IO_MODE_INPUT 0x00040000 60 + #define USP_TFS_IO_MODE_INPUT 0x00080000 61 + #define USP_RXD_IO_MODE_INPUT 0x00100000 62 + #define USP_TXD_IO_MODE_INPUT 0x00200000 63 + #define USP_IRDA_WIDTH_DIV_MASK 0x3FC00000 64 + #define USP_IRDA_WIDTH_DIV_OFFSET 0 65 + #define USP_IRDA_IDLE_LEVEL_HIGH 0x40000000 66 + #define USP_TX_UFLOW_REPEAT_ZERO 0x80000000 67 + #define USP_TX_ENDIAN_MODE 0x00000020 68 + #define USP_RX_ENDIAN_MODE 0x00000020 69 + 70 + /* USP Mode Register-2 */ 71 + #define USP_RXD_DELAY_LEN_MASK 0x000000FF 72 + #define USP_RXD_DELAY_LEN_OFFSET 0 73 + 74 + #define USP_TXD_DELAY_LEN_MASK 0x0000FF00 75 + #define USP_TXD_DELAY_LEN_OFFSET 8 76 + 77 + #define USP_ENA_CTRL_MODE 0x00010000 78 + #define USP_FRAME_CTRL_MODE 0x00020000 79 + #define USP_TFS_SOURCE_MODE 0x00040000 80 + #define USP_TFS_MS_MODE 0x00080000 81 + #define USP_CLK_DIVISOR_MASK 0x7FE00000 82 + #define USP_CLK_DIVISOR_OFFSET 21 83 + 84 + #define USP_TFS_CLK_SLAVE_MODE (1<<20) 85 + #define USP_RFS_CLK_SLAVE_MODE (1<<19) 86 + 87 + #define USP_IRDA_DATA_WIDTH 0x80000000 88 + 89 + /* USP Transmit Frame Control Register */ 90 + 91 + #define USP_TXC_DATA_LEN_MASK 0x000000FF 92 + #define USP_TXC_DATA_LEN_OFFSET 0 93 + 94 + #define USP_TXC_SYNC_LEN_MASK 0x0000FF00 95 + #define USP_TXC_SYNC_LEN_OFFSET 8 96 + 97 + #define USP_TXC_FRAME_LEN_MASK 0x00FF0000 98 + #define USP_TXC_FRAME_LEN_OFFSET 16 99 + 100 + #define USP_TXC_SHIFTER_LEN_MASK 0x1F000000 101 + #define USP_TXC_SHIFTER_LEN_OFFSET 24 102 + 103 + #define USP_TXC_SLAVE_CLK_SAMPLE 0x20000000 104 + 105 + #define USP_TXC_CLK_DIVISOR_MASK 0xC0000000 106 + #define USP_TXC_CLK_DIVISOR_OFFSET 30 107 + 108 + /* USP Receive Frame Control Register */ 109 + 110 + #define USP_RXC_DATA_LEN_MASK 0x000000FF 111 + #define USP_RXC_DATA_LEN_OFFSET 0 112 + 113 + #define USP_RXC_FRAME_LEN_MASK 0x0000FF00 114 + #define USP_RXC_FRAME_LEN_OFFSET 8 115 + 116 + #define USP_RXC_SHIFTER_LEN_MASK 0x001F0000 117 + #define USP_RXC_SHIFTER_LEN_OFFSET 16 118 + 119 + #define USP_START_EDGE_MODE 0x00800000 120 + #define USP_I2S_SYNC_CHG 0x00200000 121 + 122 + #define USP_RXC_CLK_DIVISOR_MASK 0x0F000000 123 + #define USP_RXC_CLK_DIVISOR_OFFSET 24 124 + #define USP_SINGLE_SYNC_MODE 0x00400000 125 + 126 + /* Tx - RX Enable Register */ 127 + 128 + #define USP_RX_ENA 0x00000001 129 + #define USP_TX_ENA 0x00000002 130 + 131 + /* USP Interrupt Enable and status Register */ 132 + #define USP_RX_DONE_INT 0x00000001 133 + #define USP_TX_DONE_INT 0x00000002 134 + #define USP_RX_OFLOW_INT 0x00000004 135 + #define USP_TX_UFLOW_INT 0x00000008 136 + #define USP_RX_IO_DMA_INT 0x00000010 137 + #define USP_TX_IO_DMA_INT 0x00000020 138 + #define USP_RXFIFO_FULL_INT 0x00000040 139 + #define USP_TXFIFO_EMPTY_INT 0x00000080 140 + #define USP_RXFIFO_THD_INT 0x00000100 141 + #define USP_TXFIFO_THD_INT 0x00000200 142 + #define USP_UART_FRM_ERR_INT 0x00000400 143 + #define USP_RX_TIMEOUT_INT 0x00000800 144 + #define USP_TX_ALLOUT_INT 0x00001000 145 + #define USP_RXD_BREAK_INT 0x00008000 146 + 147 + /* All possible TX interruots */ 148 + #define USP_TX_INTERRUPT (USP_TX_DONE_INT|USP_TX_UFLOW_INT|\ 149 + USP_TX_IO_DMA_INT|\ 150 + USP_TXFIFO_EMPTY_INT|\ 151 + USP_TXFIFO_THD_INT) 152 + /* All possible RX interruots */ 153 + #define USP_RX_INTERRUPT (USP_RX_DONE_INT|USP_RX_OFLOW_INT|\ 154 + USP_RX_IO_DMA_INT|\ 155 + USP_RXFIFO_FULL_INT|\ 156 + USP_RXFIFO_THD_INT|\ 157 + USP_RXFIFO_THD_INT|USP_RX_TIMEOUT_INT) 158 + 159 + #define USP_INT_ALL 0x1FFF 160 + 161 + /* USP Pin I/O Data Register */ 162 + 163 + #define USP_RFS_PIN_VALUE_MASK 0x00000001 164 + #define USP_TFS_PIN_VALUE_MASK 0x00000002 165 + #define USP_RXD_PIN_VALUE_MASK 0x00000004 166 + #define USP_TXD_PIN_VALUE_MASK 0x00000008 167 + #define USP_SCLK_PIN_VALUE_MASK 0x00000010 168 + 169 + /* USP RISC/DSP Mode Register */ 170 + #define USP_RISC_DSP_SEL 0x00000001 171 + 172 + /* USP ASYNC PARAMETER Register*/ 173 + 174 + #define USP_ASYNC_TIMEOUT_MASK 0x0000FFFF 175 + #define USP_ASYNC_TIMEOUT_OFFSET 0 176 + #define USP_ASYNC_TIMEOUT(x) (((x)&USP_ASYNC_TIMEOUT_MASK) \ 177 + <<USP_ASYNC_TIMEOUT_OFFSET) 178 + 179 + #define USP_ASYNC_DIV2_MASK 0x003F0000 180 + #define USP_ASYNC_DIV2_OFFSET 16 181 + 182 + /* USP TX DMA I/O MODE Register */ 183 + #define USP_TX_MODE_IO 0x00000001 184 + 185 + /* USP TX DMA I/O Length Register */ 186 + #define USP_TX_DATA_LEN_MASK 0xFFFFFFFF 187 + #define USP_TX_DATA_LEN_OFFSET 0 188 + 189 + /* USP TX FIFO Control Register */ 190 + #define USP_TX_FIFO_WIDTH_MASK 0x00000003 191 + #define USP_TX_FIFO_WIDTH_OFFSET 0 192 + 193 + #define USP_TX_FIFO_THD_MASK 0x000001FC 194 + #define USP_TX_FIFO_THD_OFFSET 2 195 + 196 + /* USP TX FIFO Level Check Register */ 197 + #define USP_TX_FIFO_LEVEL_CHECK_MASK 0x1F 198 + #define USP_TX_FIFO_SC_OFFSET 0 199 + #define USP_TX_FIFO_LC_OFFSET 10 200 + #define USP_TX_FIFO_HC_OFFSET 20 201 + 202 + #define TX_FIFO_SC(x) (((x) & USP_TX_FIFO_LEVEL_CHECK_MASK) \ 203 + << USP_TX_FIFO_SC_OFFSET) 204 + #define TX_FIFO_LC(x) (((x) & USP_TX_FIFO_LEVEL_CHECK_MASK) \ 205 + << USP_TX_FIFO_LC_OFFSET) 206 + #define TX_FIFO_HC(x) (((x) & USP_TX_FIFO_LEVEL_CHECK_MASK) \ 207 + << USP_TX_FIFO_HC_OFFSET) 208 + 209 + /* USP TX FIFO Operation Register */ 210 + #define USP_TX_FIFO_RESET 0x00000001 211 + #define USP_TX_FIFO_START 0x00000002 212 + 213 + /* USP TX FIFO Status Register */ 214 + #define USP_TX_FIFO_LEVEL_MASK 0x0000007F 215 + #define USP_TX_FIFO_LEVEL_OFFSET 0 216 + 217 + #define USP_TX_FIFO_FULL 0x00000080 218 + #define USP_TX_FIFO_EMPTY 0x00000100 219 + 220 + /* USP TX FIFO Data Register */ 221 + #define USP_TX_FIFO_DATA_MASK 0xFFFFFFFF 222 + #define USP_TX_FIFO_DATA_OFFSET 0 223 + 224 + /* USP RX DMA I/O MODE Register */ 225 + #define USP_RX_MODE_IO 0x00000001 226 + #define USP_RX_DMA_FLUSH 0x00000004 227 + 228 + /* USP RX DMA I/O Length Register */ 229 + #define USP_RX_DATA_LEN_MASK 0xFFFFFFFF 230 + #define USP_RX_DATA_LEN_OFFSET 0 231 + 232 + /* USP RX FIFO Control Register */ 233 + #define USP_RX_FIFO_WIDTH_MASK 0x00000003 234 + #define USP_RX_FIFO_WIDTH_OFFSET 0 235 + 236 + #define USP_RX_FIFO_THD_MASK 0x000001FC 237 + #define USP_RX_FIFO_THD_OFFSET 2 238 + 239 + /* USP RX FIFO Level Check Register */ 240 + 241 + #define USP_RX_FIFO_LEVEL_CHECK_MASK 0x1F 242 + #define USP_RX_FIFO_SC_OFFSET 0 243 + #define USP_RX_FIFO_LC_OFFSET 10 244 + #define USP_RX_FIFO_HC_OFFSET 20 245 + 246 + #define RX_FIFO_SC(x) (((x) & USP_RX_FIFO_LEVEL_CHECK_MASK) \ 247 + << USP_RX_FIFO_SC_OFFSET) 248 + #define RX_FIFO_LC(x) (((x) & USP_RX_FIFO_LEVEL_CHECK_MASK) \ 249 + << USP_RX_FIFO_LC_OFFSET) 250 + #define RX_FIFO_HC(x) (((x) & USP_RX_FIFO_LEVEL_CHECK_MASK) \ 251 + << USP_RX_FIFO_HC_OFFSET) 252 + 253 + /* USP RX FIFO Operation Register */ 254 + #define USP_RX_FIFO_RESET 0x00000001 255 + #define USP_RX_FIFO_START 0x00000002 256 + 257 + /* USP RX FIFO Status Register */ 258 + 259 + #define USP_RX_FIFO_LEVEL_MASK 0x0000007F 260 + #define USP_RX_FIFO_LEVEL_OFFSET 0 261 + 262 + #define USP_RX_FIFO_FULL 0x00000080 263 + #define USP_RX_FIFO_EMPTY 0x00000100 264 + 265 + /* USP RX FIFO Data Register */ 266 + 267 + #define USP_RX_FIFO_DATA_MASK 0xFFFFFFFF 268 + #define USP_RX_FIFO_DATA_OFFSET 0 269 + 270 + /* 271 + * When rx thd irq occur, sender just disable tx empty irq, 272 + * Remaining data in tx fifo wil also be sent out. 273 + */ 274 + #define USP_FIFO_SIZE 128 275 + #define USP_TX_FIFO_THRESHOLD (USP_FIFO_SIZE/2) 276 + #define USP_RX_FIFO_THRESHOLD (USP_FIFO_SIZE/2) 277 + 278 + /* FIFO_WIDTH for the USP_TX_FIFO_CTRL and USP_RX_FIFO_CTRL registers */ 279 + #define USP_FIFO_WIDTH_BYTE 0x00 280 + #define USP_FIFO_WIDTH_WORD 0x01 281 + #define USP_FIFO_WIDTH_DWORD 0x02 282 + 283 + #define USP_ASYNC_DIV2 16 284 + 285 + #define USP_PLUGOUT_RETRY_CNT 2 286 + 287 + #define USP_TX_RX_FIFO_WIDTH_DWORD 2 288 + 289 + #define SIRF_USP_DIV_MCLK 0 290 + 291 + #define SIRF_USP_I2S_TFS_SYNC 0 292 + #define SIRF_USP_I2S_RFS_SYNC 1 293 + #endif