~ubuntu-branches/ubuntu/precise/alsa-driver/precise

« back to all changes in this revision

Viewing changes to alsa-kernel/soc/codecs/ssm2602.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2011-02-21 18:06:40 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20110221180640-a8p2yxtvgf7xbxub
Tags: 1.0.24+dfsg-0ubuntu1
* New upstream release
* Refreshed patches:
  - distinguish_kernel_makefile_and_source_dirs.patch
  - debian_dfsg_configure.patch
* debian/control: Update Vcs-bzr field to point to new branch location

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include <sound/pcm.h>
39
39
#include <sound/pcm_params.h>
40
40
#include <sound/soc.h>
41
 
#include <sound/soc-dapm.h>
42
41
#include <sound/initval.h>
43
42
 
44
43
#include "ssm2602.h"
45
44
 
46
45
#define SSM2602_VERSION "0.1"
47
46
 
48
 
struct snd_soc_codec_device soc_codec_dev_ssm2602;
49
 
 
50
47
/* codec private data */
51
48
struct ssm2602_priv {
52
49
        unsigned int sysclk;
 
50
        enum snd_soc_control_type control_type;
 
51
        void *control_data;
53
52
        struct snd_pcm_substream *master_substream;
54
53
        struct snd_pcm_substream *slave_substream;
55
54
};
207
206
 
208
207
static int ssm2602_add_widgets(struct snd_soc_codec *codec)
209
208
{
210
 
        snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets,
 
209
        struct snd_soc_dapm_context *dapm = &codec->dapm;
 
210
 
 
211
        snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
211
212
                                  ARRAY_SIZE(ssm2602_dapm_widgets));
212
 
 
213
 
        snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
 
213
        snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn));
214
214
 
215
215
        return 0;
216
216
}
276
276
{
277
277
        u16 srate;
278
278
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
279
 
        struct snd_soc_device *socdev = rtd->socdev;
280
 
        struct snd_soc_codec *codec = socdev->card->codec;
281
 
        struct ssm2602_priv *ssm2602 = codec->private_data;
 
279
        struct snd_soc_codec *codec = rtd->codec;
 
280
        struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
282
281
        struct i2c_client *i2c = codec->control_data;
283
282
        u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
284
283
        int i = get_coeff(ssm2602->sysclk, params_rate(params));
321
320
                           struct snd_soc_dai *dai)
322
321
{
323
322
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
324
 
        struct snd_soc_device *socdev = rtd->socdev;
325
 
        struct snd_soc_codec *codec = socdev->card->codec;
326
 
        struct ssm2602_priv *ssm2602 = codec->private_data;
 
323
        struct snd_soc_codec *codec = rtd->codec;
 
324
        struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
327
325
        struct i2c_client *i2c = codec->control_data;
328
326
        struct snd_pcm_runtime *master_runtime;
329
327
 
360
358
                               struct snd_soc_dai *dai)
361
359
{
362
360
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
363
 
        struct snd_soc_device *socdev = rtd->socdev;
364
 
        struct snd_soc_codec *codec = socdev->card->codec;
 
361
        struct snd_soc_codec *codec = rtd->codec;
365
362
        /* set active */
366
363
        ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
367
364
 
372
369
                             struct snd_soc_dai *dai)
373
370
{
374
371
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
375
 
        struct snd_soc_device *socdev = rtd->socdev;
376
 
        struct snd_soc_codec *codec = socdev->card->codec;
377
 
        struct ssm2602_priv *ssm2602 = codec->private_data;
 
372
        struct snd_soc_codec *codec = rtd->codec;
 
373
        struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
378
374
 
379
375
        /* deactivate */
380
376
        if (!codec->active)
402
398
                int clk_id, unsigned int freq, int dir)
403
399
{
404
400
        struct snd_soc_codec *codec = codec_dai->codec;
405
 
        struct ssm2602_priv *ssm2602 = codec->private_data;
 
401
        struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
406
402
        switch (freq) {
407
403
        case 11289600:
408
404
        case 12000000:
497
493
                break;
498
494
 
499
495
        }
500
 
        codec->bias_level = level;
 
496
        codec->dapm.bias_level = level;
501
497
        return 0;
502
498
}
503
499
 
518
514
        .set_fmt        = ssm2602_set_dai_fmt,
519
515
};
520
516
 
521
 
struct snd_soc_dai ssm2602_dai = {
522
 
        .name = "SSM2602",
 
517
static struct snd_soc_dai_driver ssm2602_dai = {
 
518
        .name = "ssm2602-hifi",
523
519
        .playback = {
524
520
                .stream_name = "Playback",
525
521
                .channels_min = 2,
534
530
                .formats = SSM2602_FORMATS,},
535
531
        .ops = &ssm2602_dai_ops,
536
532
};
537
 
EXPORT_SYMBOL_GPL(ssm2602_dai);
538
533
 
539
 
static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
 
534
static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
540
535
{
541
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
542
 
        struct snd_soc_codec *codec = socdev->card->codec;
543
 
 
544
536
        ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
545
537
        return 0;
546
538
}
547
539
 
548
 
static int ssm2602_resume(struct platform_device *pdev)
 
540
static int ssm2602_resume(struct snd_soc_codec *codec)
549
541
{
550
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
551
 
        struct snd_soc_codec *codec = socdev->card->codec;
552
542
        int i;
553
543
        u8 data[2];
554
544
        u16 *cache = codec->reg_cache;
560
550
                codec->hw_write(codec->control_data, data, 2);
561
551
        }
562
552
        ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
563
 
        ssm2602_set_bias_level(codec, codec->suspend_bias_level);
564
553
        return 0;
565
554
}
566
555
 
567
 
/*
568
 
 * initialise the ssm2602 driver
569
 
 * register the mixer and dsp interfaces with the kernel
570
 
 */
571
 
static int ssm2602_init(struct snd_soc_device *socdev)
 
556
static int ssm2602_probe(struct snd_soc_codec *codec)
572
557
{
573
 
        struct snd_soc_codec *codec = socdev->card->codec;
574
 
        int reg, ret = 0;
575
 
 
576
 
        codec->name = "SSM2602";
577
 
        codec->owner = THIS_MODULE;
578
 
        codec->read = ssm2602_read_reg_cache;
579
 
        codec->write = ssm2602_write;
580
 
        codec->set_bias_level = ssm2602_set_bias_level;
581
 
        codec->dai = &ssm2602_dai;
582
 
        codec->num_dai = 1;
583
 
        codec->reg_cache_size = sizeof(ssm2602_reg);
584
 
        codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
585
 
                                        GFP_KERNEL);
586
 
        if (codec->reg_cache == NULL)
587
 
                return -ENOMEM;
 
558
        struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
 
559
        int ret = 0, reg;
 
560
 
 
561
        pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
 
562
 
 
563
        codec->control_data = ssm2602->control_data;
588
564
 
589
565
        ssm2602_reset(codec);
590
566
 
591
 
        /* register pcms */
592
 
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
593
 
        if (ret < 0) {
594
 
                pr_err("ssm2602: failed to create pcms\n");
595
 
                goto pcm_err;
596
 
        }
597
567
        /*power on device*/
598
568
        ssm2602_write(codec, SSM2602_ACTIVE, 0);
599
569
        /* set the update bits */
615
585
        ssm2602_add_widgets(codec);
616
586
 
617
587
        return ret;
618
 
 
619
 
pcm_err:
620
 
        kfree(codec->reg_cache);
621
 
        return ret;
622
 
}
623
 
 
624
 
static struct snd_soc_device *ssm2602_socdev;
 
588
}
 
589
 
 
590
/* remove everything here */
 
591
static int ssm2602_remove(struct snd_soc_codec *codec)
 
592
{
 
593
        ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
594
        return 0;
 
595
}
 
596
 
 
597
static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
 
598
        .probe =        ssm2602_probe,
 
599
        .remove =       ssm2602_remove,
 
600
        .suspend =      ssm2602_suspend,
 
601
        .resume =       ssm2602_resume,
 
602
        .read = ssm2602_read_reg_cache,
 
603
        .write = ssm2602_write,
 
604
        .set_bias_level = ssm2602_set_bias_level,
 
605
        .reg_cache_size = sizeof(ssm2602_reg),
 
606
        .reg_word_size = sizeof(u16),
 
607
        .reg_cache_default = ssm2602_reg,
 
608
};
625
609
 
626
610
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
627
611
/*
633
617
static int ssm2602_i2c_probe(struct i2c_client *i2c,
634
618
                             const struct i2c_device_id *id)
635
619
{
636
 
        struct snd_soc_device *socdev = ssm2602_socdev;
637
 
        struct snd_soc_codec *codec = socdev->card->codec;
 
620
        struct ssm2602_priv *ssm2602;
638
621
        int ret;
639
622
 
640
 
        i2c_set_clientdata(i2c, codec);
641
 
        codec->control_data = i2c;
642
 
 
643
 
        ret = ssm2602_init(socdev);
 
623
        ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
 
624
        if (ssm2602 == NULL)
 
625
                return -ENOMEM;
 
626
 
 
627
        i2c_set_clientdata(i2c, ssm2602);
 
628
        ssm2602->control_data = i2c;
 
629
        ssm2602->control_type = SND_SOC_I2C;
 
630
 
 
631
        ret = snd_soc_register_codec(&i2c->dev,
 
632
                        &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
644
633
        if (ret < 0)
645
 
                pr_err("failed to initialise SSM2602\n");
646
 
 
 
634
                kfree(ssm2602);
647
635
        return ret;
648
636
}
649
637
 
650
638
static int ssm2602_i2c_remove(struct i2c_client *client)
651
639
{
652
 
        struct snd_soc_codec *codec = i2c_get_clientdata(client);
653
 
        kfree(codec->reg_cache);
 
640
        snd_soc_unregister_codec(&client->dev);
 
641
        kfree(i2c_get_clientdata(client));
654
642
        return 0;
655
643
}
656
644
 
659
647
        { }
660
648
};
661
649
MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
 
650
 
662
651
/* corgi i2c codec control layer */
663
652
static struct i2c_driver ssm2602_i2c_driver = {
664
653
        .driver = {
665
 
                .name = "SSM2602 I2C Codec",
 
654
                .name = "ssm2602-codec",
666
655
                .owner = THIS_MODULE,
667
656
        },
668
657
        .probe = ssm2602_i2c_probe,
669
658
        .remove = ssm2602_i2c_remove,
670
659
        .id_table = ssm2602_i2c_id,
671
660
};
672
 
 
673
 
static int ssm2602_add_i2c_device(struct platform_device *pdev,
674
 
                                  const struct ssm2602_setup_data *setup)
 
661
#endif
 
662
 
 
663
 
 
664
static int __init ssm2602_modinit(void)
675
665
{
676
 
        struct i2c_board_info info;
677
 
        struct i2c_adapter *adapter;
678
 
        struct i2c_client *client;
679
 
        int ret;
680
 
 
 
666
        int ret = 0;
 
667
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
681
668
        ret = i2c_add_driver(&ssm2602_i2c_driver);
682
669
        if (ret != 0) {
683
 
                dev_err(&pdev->dev, "can't add i2c driver\n");
684
 
                return ret;
685
 
        }
686
 
        memset(&info, 0, sizeof(struct i2c_board_info));
687
 
        info.addr = setup->i2c_address;
688
 
        strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
689
 
        adapter = i2c_get_adapter(setup->i2c_bus);
690
 
        if (!adapter) {
691
 
                dev_err(&pdev->dev, "can't get i2c adapter %d\n",
692
 
                setup->i2c_bus);
693
 
                goto err_driver;
694
 
        }
695
 
        client = i2c_new_device(adapter, &info);
696
 
        i2c_put_adapter(adapter);
697
 
        if (!client) {
698
 
                dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
699
 
                (unsigned int)info.addr);
700
 
                goto err_driver;
701
 
        }
702
 
        return 0;
703
 
err_driver:
704
 
        i2c_del_driver(&ssm2602_i2c_driver);
705
 
        return -ENODEV;
706
 
}
707
 
#endif
708
 
 
709
 
static int ssm2602_probe(struct platform_device *pdev)
710
 
{
711
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
712
 
        struct ssm2602_setup_data *setup;
713
 
        struct snd_soc_codec *codec;
714
 
        struct ssm2602_priv *ssm2602;
715
 
        int ret = 0;
716
 
 
717
 
        pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
718
 
 
719
 
        setup = socdev->codec_data;
720
 
        codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
721
 
        if (codec == NULL)
722
 
                return -ENOMEM;
723
 
 
724
 
        ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
725
 
        if (ssm2602 == NULL) {
726
 
                kfree(codec);
727
 
                return -ENOMEM;
728
 
        }
729
 
 
730
 
        codec->private_data = ssm2602;
731
 
        socdev->card->codec = codec;
732
 
        mutex_init(&codec->mutex);
733
 
        INIT_LIST_HEAD(&codec->dapm_widgets);
734
 
        INIT_LIST_HEAD(&codec->dapm_paths);
735
 
 
736
 
        ssm2602_socdev = socdev;
737
 
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
738
 
        if (setup->i2c_address) {
739
 
                codec->hw_write = (hw_write_t)i2c_master_send;
740
 
                ret = ssm2602_add_i2c_device(pdev, setup);
741
 
        }
742
 
#else
743
 
        /* other interfaces */
 
670
                printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n",
 
671
                       ret);
 
672
        }
744
673
#endif
745
674
        return ret;
746
675
}
747
 
 
748
 
/* remove everything here */
749
 
static int ssm2602_remove(struct platform_device *pdev)
750
 
{
751
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
752
 
        struct snd_soc_codec *codec = socdev->card->codec;
753
 
 
754
 
        if (codec->control_data)
755
 
                ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
756
 
 
757
 
        snd_soc_free_pcms(socdev);
758
 
        snd_soc_dapm_free(socdev);
759
 
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
760
 
        i2c_unregister_device(codec->control_data);
761
 
        i2c_del_driver(&ssm2602_i2c_driver);
762
 
#endif
763
 
        kfree(codec->private_data);
764
 
        kfree(codec);
765
 
 
766
 
        return 0;
767
 
}
768
 
 
769
 
struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
770
 
        .probe =        ssm2602_probe,
771
 
        .remove =       ssm2602_remove,
772
 
        .suspend =      ssm2602_suspend,
773
 
        .resume =       ssm2602_resume,
774
 
};
775
 
EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
776
 
 
777
 
static int __init ssm2602_modinit(void)
778
 
{
779
 
        return snd_soc_register_dai(&ssm2602_dai);
780
 
}
781
676
module_init(ssm2602_modinit);
782
677
 
783
678
static void __exit ssm2602_exit(void)
784
679
{
785
 
        snd_soc_unregister_dai(&ssm2602_dai);
 
680
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
681
        i2c_del_driver(&ssm2602_i2c_driver);
 
682
#endif
786
683
}
787
684
module_exit(ssm2602_exit);
788
685