1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * tegra30_i2s.c - Tegra30 I2S driver 4 * 5 * Author: Stephen Warren <swarren@nvidia.com> 6 * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. 7 * 8 * Based on code copyright/by: 9 * 10 * Copyright (c) 2009-2010, NVIDIA Corporation. 11 * Scott Peterson <speterson@nvidia.com> 12 * 13 * Copyright (C) 2010 Google, Inc. 14 * Iliyan Malchev <malchev@google.com> 15 */ 16 17 #include <linux/clk.h> 18 #include <linux/device.h> 19 #include <linux/io.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/platform_device.h> 23 #include <linux/pm_runtime.h> 24 #include <linux/regmap.h> 25 #include <linux/reset.h> 26 #include <linux/slab.h> 27 #include <sound/core.h> 28 #include <sound/pcm.h> 29 #include <sound/pcm_params.h> 30 #include <sound/soc.h> 31 #include <sound/dmaengine_pcm.h> 32 33 #include "tegra30_ahub.h" 34 #include "tegra30_i2s.h" 35 36 #define DRV_NAME "tegra30-i2s" 37 38 static __maybe_unused int tegra30_i2s_runtime_suspend(struct device *dev) 39 { 40 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 41 42 regcache_cache_only(i2s->regmap, true); 43 44 clk_disable_unprepare(i2s->clk_i2s); 45 46 return 0; 47 } 48 49 static __maybe_unused int tegra30_i2s_runtime_resume(struct device *dev) 50 { 51 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 52 int ret; 53 54 ret = clk_prepare_enable(i2s->clk_i2s); 55 if (ret) { 56 dev_err(dev, "clk_enable failed: %d\n", ret); 57 return ret; 58 } 59 60 regcache_cache_only(i2s->regmap, false); 61 regcache_mark_dirty(i2s->regmap); 62 63 ret = regcache_sync(i2s->regmap); 64 if (ret) 65 goto disable_clocks; 66 67 return 0; 68 69 disable_clocks: 70 clk_disable_unprepare(i2s->clk_i2s); 71 72 return ret; 73 } 74 75 static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, 76 unsigned int fmt) 77 { 78 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 79 unsigned int mask = 0, val = 0; 80 81 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 82 case SND_SOC_DAIFMT_NB_NF: 83 break; 84 default: 85 return -EINVAL; 86 } 87 88 mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE; 89 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 90 case SND_SOC_DAIFMT_BP_FP: 91 val |= TEGRA30_I2S_CTRL_MASTER_ENABLE; 92 break; 93 case SND_SOC_DAIFMT_BC_FC: 94 break; 95 default: 96 return -EINVAL; 97 } 98 99 mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | 100 TEGRA30_I2S_CTRL_LRCK_MASK; 101 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 102 case SND_SOC_DAIFMT_DSP_A: 103 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 104 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 105 break; 106 case SND_SOC_DAIFMT_DSP_B: 107 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 108 val |= TEGRA30_I2S_CTRL_LRCK_R_LOW; 109 break; 110 case SND_SOC_DAIFMT_I2S: 111 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 112 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 113 break; 114 case SND_SOC_DAIFMT_RIGHT_J: 115 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 116 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 117 break; 118 case SND_SOC_DAIFMT_LEFT_J: 119 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 120 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 121 break; 122 default: 123 return -EINVAL; 124 } 125 126 pm_runtime_get_sync(dai->dev); 127 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); 128 pm_runtime_put(dai->dev); 129 130 return 0; 131 } 132 133 static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, 134 struct snd_pcm_hw_params *params, 135 struct snd_soc_dai *dai) 136 { 137 struct device *dev = dai->dev; 138 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 139 unsigned int mask, val, reg; 140 int ret, sample_size, srate, i2sclock, bitcnt; 141 struct tegra30_ahub_cif_conf cif_conf; 142 143 if (params_channels(params) != 2) 144 return -EINVAL; 145 146 mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK; 147 switch (params_format(params)) { 148 case SNDRV_PCM_FORMAT_S16_LE: 149 val = TEGRA30_I2S_CTRL_BIT_SIZE_16; 150 sample_size = 16; 151 break; 152 default: 153 return -EINVAL; 154 } 155 156 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); 157 158 srate = params_rate(params); 159 160 /* Final "* 2" required by Tegra hardware */ 161 i2sclock = srate * params_channels(params) * sample_size * 2; 162 163 bitcnt = (i2sclock / (2 * srate)) - 1; 164 if (bitcnt < 0 || bitcnt > TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) 165 return -EINVAL; 166 167 ret = clk_set_rate(i2s->clk_i2s, i2sclock); 168 if (ret) { 169 dev_err(dev, "Can't set I2S clock rate: %d\n", ret); 170 return ret; 171 } 172 173 val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; 174 175 if (i2sclock % (2 * srate)) 176 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; 177 178 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val); 179 180 cif_conf.threshold = 0; 181 cif_conf.audio_channels = 2; 182 cif_conf.client_channels = 2; 183 cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16; 184 cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16; 185 cif_conf.expand = 0; 186 cif_conf.stereo_conv = 0; 187 cif_conf.replicate = 0; 188 cif_conf.truncate = 0; 189 cif_conf.mono_conv = 0; 190 191 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 192 cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_RX; 193 reg = TEGRA30_I2S_CIF_RX_CTRL; 194 } else { 195 cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_TX; 196 reg = TEGRA30_I2S_CIF_TX_CTRL; 197 } 198 199 i2s->soc_data->set_audio_cif(i2s->regmap, reg, &cif_conf); 200 201 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | 202 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); 203 regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val); 204 205 return 0; 206 } 207 208 static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) 209 { 210 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); 211 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, 212 TEGRA30_I2S_CTRL_XFER_EN_TX, 213 TEGRA30_I2S_CTRL_XFER_EN_TX); 214 } 215 216 static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) 217 { 218 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); 219 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, 220 TEGRA30_I2S_CTRL_XFER_EN_TX, 0); 221 } 222 223 static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) 224 { 225 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); 226 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, 227 TEGRA30_I2S_CTRL_XFER_EN_RX, 228 TEGRA30_I2S_CTRL_XFER_EN_RX); 229 } 230 231 static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) 232 { 233 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, 234 TEGRA30_I2S_CTRL_XFER_EN_RX, 0); 235 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); 236 } 237 238 static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 239 struct snd_soc_dai *dai) 240 { 241 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 242 243 switch (cmd) { 244 case SNDRV_PCM_TRIGGER_START: 245 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 246 case SNDRV_PCM_TRIGGER_RESUME: 247 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 248 tegra30_i2s_start_playback(i2s); 249 else 250 tegra30_i2s_start_capture(i2s); 251 break; 252 case SNDRV_PCM_TRIGGER_STOP: 253 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 254 case SNDRV_PCM_TRIGGER_SUSPEND: 255 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 256 tegra30_i2s_stop_playback(i2s); 257 else 258 tegra30_i2s_stop_capture(i2s); 259 break; 260 default: 261 return -EINVAL; 262 } 263 264 return 0; 265 } 266 267 static int tegra30_i2s_set_tdm(struct snd_soc_dai *dai, 268 unsigned int tx_mask, unsigned int rx_mask, 269 int slots, int slot_width) 270 { 271 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 272 unsigned int mask, val; 273 274 dev_dbg(dai->dev, "%s: txmask=0x%08x rxmask=0x%08x slots=%d width=%d\n", 275 __func__, tx_mask, rx_mask, slots, slot_width); 276 277 mask = TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK | 278 TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_MASK | 279 TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_MASK; 280 281 val = (tx_mask << TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT) | 282 (rx_mask << TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT) | 283 ((slots - 1) << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT); 284 285 pm_runtime_get_sync(dai->dev); 286 regmap_update_bits(i2s->regmap, TEGRA30_I2S_SLOT_CTRL, mask, val); 287 /* set the fsync width to minimum of 1 clock width */ 288 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CH_CTRL, 289 TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK, 0x0); 290 pm_runtime_put(dai->dev); 291 292 return 0; 293 } 294 295 static int tegra30_i2s_probe(struct snd_soc_dai *dai) 296 { 297 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 298 299 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, 300 &i2s->capture_dma_data); 301 302 return 0; 303 } 304 305 static const struct snd_soc_dai_ops tegra30_i2s_dai_ops = { 306 .probe = tegra30_i2s_probe, 307 .set_fmt = tegra30_i2s_set_fmt, 308 .hw_params = tegra30_i2s_hw_params, 309 .trigger = tegra30_i2s_trigger, 310 .set_tdm_slot = tegra30_i2s_set_tdm, 311 }; 312 313 static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { 314 .playback = { 315 .stream_name = "Playback", 316 .channels_min = 2, 317 .channels_max = 2, 318 .rates = SNDRV_PCM_RATE_8000_96000, 319 .formats = SNDRV_PCM_FMTBIT_S16_LE, 320 }, 321 .capture = { 322 .stream_name = "Capture", 323 .channels_min = 2, 324 .channels_max = 2, 325 .rates = SNDRV_PCM_RATE_8000_96000, 326 .formats = SNDRV_PCM_FMTBIT_S16_LE, 327 }, 328 .ops = &tegra30_i2s_dai_ops, 329 .symmetric_rate = 1, 330 }; 331 332 static const struct snd_soc_component_driver tegra30_i2s_component = { 333 .name = DRV_NAME, 334 .legacy_dai_naming = 1, 335 }; 336 337 static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg) 338 { 339 switch (reg) { 340 case TEGRA30_I2S_CTRL: 341 case TEGRA30_I2S_TIMING: 342 case TEGRA30_I2S_OFFSET: 343 case TEGRA30_I2S_CH_CTRL: 344 case TEGRA30_I2S_SLOT_CTRL: 345 case TEGRA30_I2S_CIF_RX_CTRL: 346 case TEGRA30_I2S_CIF_TX_CTRL: 347 case TEGRA30_I2S_FLOWCTL: 348 case TEGRA30_I2S_TX_STEP: 349 case TEGRA30_I2S_FLOW_STATUS: 350 case TEGRA30_I2S_FLOW_TOTAL: 351 case TEGRA30_I2S_FLOW_OVER: 352 case TEGRA30_I2S_FLOW_UNDER: 353 case TEGRA30_I2S_LCOEF_1_4_0: 354 case TEGRA30_I2S_LCOEF_1_4_1: 355 case TEGRA30_I2S_LCOEF_1_4_2: 356 case TEGRA30_I2S_LCOEF_1_4_3: 357 case TEGRA30_I2S_LCOEF_1_4_4: 358 case TEGRA30_I2S_LCOEF_1_4_5: 359 case TEGRA30_I2S_LCOEF_2_4_0: 360 case TEGRA30_I2S_LCOEF_2_4_1: 361 case TEGRA30_I2S_LCOEF_2_4_2: 362 return true; 363 default: 364 return false; 365 } 366 } 367 368 static bool tegra30_i2s_volatile_reg(struct device *dev, unsigned int reg) 369 { 370 switch (reg) { 371 case TEGRA30_I2S_FLOW_STATUS: 372 case TEGRA30_I2S_FLOW_TOTAL: 373 case TEGRA30_I2S_FLOW_OVER: 374 case TEGRA30_I2S_FLOW_UNDER: 375 return true; 376 default: 377 return false; 378 } 379 } 380 381 static const struct regmap_config tegra30_i2s_regmap_config = { 382 .reg_bits = 32, 383 .reg_stride = 4, 384 .val_bits = 32, 385 .max_register = TEGRA30_I2S_LCOEF_2_4_2, 386 .writeable_reg = tegra30_i2s_wr_rd_reg, 387 .readable_reg = tegra30_i2s_wr_rd_reg, 388 .volatile_reg = tegra30_i2s_volatile_reg, 389 .cache_type = REGCACHE_FLAT, 390 }; 391 392 static const struct tegra30_i2s_soc_data tegra30_i2s_config = { 393 .set_audio_cif = tegra30_ahub_set_cif, 394 }; 395 396 static const struct tegra30_i2s_soc_data tegra124_i2s_config = { 397 .set_audio_cif = tegra124_ahub_set_cif, 398 }; 399 400 static const struct of_device_id tegra30_i2s_of_match[] = { 401 { .compatible = "nvidia,tegra124-i2s", .data = &tegra124_i2s_config }, 402 { .compatible = "nvidia,tegra30-i2s", .data = &tegra30_i2s_config }, 403 {}, 404 }; 405 406 static int tegra30_i2s_platform_probe(struct platform_device *pdev) 407 { 408 struct tegra30_i2s *i2s; 409 const struct tegra30_i2s_soc_data *soc_data; 410 u32 cif_ids[2]; 411 void __iomem *regs; 412 int ret; 413 414 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL); 415 if (!i2s) { 416 ret = -ENOMEM; 417 goto err; 418 } 419 dev_set_drvdata(&pdev->dev, i2s); 420 421 soc_data = of_device_get_match_data(&pdev->dev); 422 if (!soc_data) { 423 dev_err(&pdev->dev, "Error: No device match found\n"); 424 ret = -ENODEV; 425 goto err; 426 } 427 i2s->soc_data = soc_data; 428 429 i2s->dai = tegra30_i2s_dai_template; 430 i2s->dai.name = dev_name(&pdev->dev); 431 432 ret = of_property_read_u32_array(pdev->dev.of_node, 433 "nvidia,ahub-cif-ids", cif_ids, 434 ARRAY_SIZE(cif_ids)); 435 if (ret < 0) 436 goto err; 437 438 i2s->playback_i2s_cif = cif_ids[0]; 439 i2s->capture_i2s_cif = cif_ids[1]; 440 441 i2s->clk_i2s = devm_clk_get(&pdev->dev, NULL); 442 if (IS_ERR(i2s->clk_i2s)) { 443 dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); 444 ret = PTR_ERR(i2s->clk_i2s); 445 goto err; 446 } 447 448 regs = devm_platform_ioremap_resource(pdev, 0); 449 if (IS_ERR(regs)) { 450 ret = PTR_ERR(regs); 451 goto err; 452 } 453 454 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 455 &tegra30_i2s_regmap_config); 456 if (IS_ERR(i2s->regmap)) { 457 dev_err(&pdev->dev, "regmap init failed\n"); 458 ret = PTR_ERR(i2s->regmap); 459 goto err; 460 } 461 regcache_cache_only(i2s->regmap, true); 462 463 pm_runtime_enable(&pdev->dev); 464 465 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 466 i2s->playback_dma_data.maxburst = 4; 467 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, 468 i2s->playback_dma_chan, 469 sizeof(i2s->playback_dma_chan), 470 &i2s->playback_dma_data.addr); 471 if (ret) { 472 dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret); 473 goto err_pm_disable; 474 } 475 ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, 476 i2s->playback_fifo_cif); 477 if (ret) { 478 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); 479 goto err_free_tx_fifo; 480 } 481 482 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 483 i2s->capture_dma_data.maxburst = 4; 484 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, 485 i2s->capture_dma_chan, 486 sizeof(i2s->capture_dma_chan), 487 &i2s->capture_dma_data.addr); 488 if (ret) { 489 dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret); 490 goto err_unroute_tx_fifo; 491 } 492 ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, 493 i2s->capture_i2s_cif); 494 if (ret) { 495 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); 496 goto err_free_rx_fifo; 497 } 498 499 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, 500 &i2s->dai, 1); 501 if (ret) { 502 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 503 ret = -ENOMEM; 504 goto err_unroute_rx_fifo; 505 } 506 507 ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev, 508 &i2s->dma_config, i2s->playback_dma_chan, 509 i2s->capture_dma_chan); 510 if (ret) { 511 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); 512 goto err_unregister_component; 513 } 514 515 return 0; 516 517 err_unregister_component: 518 snd_soc_unregister_component(&pdev->dev); 519 err_unroute_rx_fifo: 520 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); 521 err_free_rx_fifo: 522 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); 523 err_unroute_tx_fifo: 524 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); 525 err_free_tx_fifo: 526 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); 527 err_pm_disable: 528 pm_runtime_disable(&pdev->dev); 529 err: 530 return ret; 531 } 532 533 static void tegra30_i2s_platform_remove(struct platform_device *pdev) 534 { 535 struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev); 536 537 tegra_pcm_platform_unregister(&pdev->dev); 538 snd_soc_unregister_component(&pdev->dev); 539 540 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); 541 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); 542 543 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); 544 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); 545 546 pm_runtime_disable(&pdev->dev); 547 } 548 549 static const struct dev_pm_ops tegra30_i2s_pm_ops = { 550 SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, 551 tegra30_i2s_runtime_resume, NULL) 552 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 553 pm_runtime_force_resume) 554 }; 555 556 static struct platform_driver tegra30_i2s_driver = { 557 .driver = { 558 .name = DRV_NAME, 559 .of_match_table = tegra30_i2s_of_match, 560 .pm = &tegra30_i2s_pm_ops, 561 }, 562 .probe = tegra30_i2s_platform_probe, 563 .remove_new = tegra30_i2s_platform_remove, 564 }; 565 module_platform_driver(tegra30_i2s_driver); 566 567 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 568 MODULE_DESCRIPTION("Tegra30 I2S ASoC driver"); 569 MODULE_LICENSE("GPL"); 570 MODULE_ALIAS("platform:" DRV_NAME); 571 MODULE_DEVICE_TABLE(of, tegra30_i2s_of_match); 572
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.