Ignore:
Timestamp:
Jan 1, 2021, 5:31:48 AM (5 years ago)
Author:
Paul Smedley
Message:

Add source for uniaud32 based on code from linux kernel 5.4.86

Location:
GPL/branches/uniaud32-next
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • GPL/branches/uniaud32-next/alsa-kernel/drivers/dummy.c

    r612 r615  
     1// SPDX-License-Identifier: GPL-2.0-or-later
    12/*
    23 *  Dummy soundcard
    34 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
    4  *
    5  *   This program is free software; you can redistribute it and/or modify
    6  *   it under the terms of the GNU General Public License as published by
    7  *   the Free Software Foundation; either version 2 of the License, or
    8  *   (at your option) any later version.
    9  *
    10  *   This program is distributed in the hope that it will be useful,
    11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  *   GNU General Public License for more details.
    14  *
    15  *   You should have received a copy of the GNU General Public License
    16  *   along with this program; if not, write to the Free Software
    17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    18  *
    195 */
    206
     
    6147static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
    6248static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
    63 static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
     49static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
    6450static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
    6551static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
     
    6753//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
    6854#ifdef CONFIG_HIGH_RES_TIMERS
    69 static int hrtimer = 1;
     55static bool hrtimer = 1;
    7056#endif
    71 static int fake_buffer = 1;
     57static bool fake_buffer = 1;
    7258
    7359module_param_array(index, int, NULL, 0444);
     
    138124        int mixer_volume[MIXER_ADDR_LAST+1][2];
    139125        int capture_source[MIXER_ADDR_LAST+1][2];
     126        int iobox;
     127        struct snd_kcontrol *cd_volume_ctl;
     128        struct snd_kcontrol *cd_switch_ctl;
    140129};
    141130
     
    156145}
    157146
    158 struct dummy_model model_emu10k1 = {
     147static struct dummy_model model_emu10k1 = {
    159148        .name = "emu10k1",
    160149        .playback_constraints = emu10k1_playback_constraints,
     
    162151};
    163152
    164 struct dummy_model model_rme9652 = {
     153static struct dummy_model model_rme9652 = {
    165154        .name = "rme9652",
    166155        .buffer_bytes_max = 26 * 64 * 1024,
     
    172161};
    173162
    174 struct dummy_model model_ice1712 = {
     163static struct dummy_model model_ice1712 = {
    175164        .name = "ice1712",
    176165        .buffer_bytes_max = 256 * 1024,
     
    182171};
    183172
    184 struct dummy_model model_uda1341 = {
     173static struct dummy_model model_uda1341 = {
    185174        .name = "uda1341",
    186175        .buffer_bytes_max = 16380,
     
    192181};
    193182
    194 struct dummy_model model_ac97 = {
     183static struct dummy_model model_ac97 = {
    195184        .name = "ac97",
    196185        .formats = SNDRV_PCM_FMTBIT_S16_LE,
     
    202191};
    203192
    204 struct dummy_model model_ca0106 = {
     193static struct dummy_model model_ca0106 = {
    205194        .name = "ca0106",
    206195        .formats = SNDRV_PCM_FMTBIT_S16_LE,
     
    216205};
    217206
    218 struct dummy_model *dummy_models[] = {
     207static struct dummy_model *dummy_models[] = {
    219208        &model_emu10k1,
    220209        &model_rme9652,
     
    247236static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
    248237{
    249         dpcm->timer.expires = jiffies +
    250                 (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate;
    251         add_timer(&dpcm->timer);
     238        mod_timer(&dpcm->timer, jiffies +
     239                (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate);
    252240}
    253241
     
    305293}
    306294
    307 static void dummy_systimer_callback(unsigned long data)
    308 {
    309         struct dummy_systimer_pcm *dpcm = (struct dummy_systimer_pcm *)data;
     295static void dummy_systimer_callback(struct timer_list *t)
     296{
     297        struct dummy_systimer_pcm *dpcm = from_timer(dpcm, t, timer);
    310298        unsigned long flags;
    311299        int elapsed = 0;
     
    342330                return -ENOMEM;
    343331        substream->runtime->private_data = dpcm;
    344         init_timer(&dpcm->timer);
    345         dpcm->timer.data = (unsigned long) dpcm;
    346         dpcm->timer.function = dummy_systimer_callback;
     332        timer_setup(&dpcm->timer, dummy_systimer_callback, 0);
    347333        spin_lock_init(&dpcm->lock);
    348334        dpcm->substream = substream;
     
    355341}
    356342
    357 static struct dummy_timer_ops dummy_systimer_ops = {
     343static const struct dummy_timer_ops dummy_systimer_ops = {
    358344        .create =       dummy_systimer_create,
    359345        .free =         dummy_systimer_free,
     
    376362        atomic_t running;
    377363        struct hrtimer timer;
    378         struct tasklet_struct tasklet;
    379364        struct snd_pcm_substream *substream;
    380365};
    381 
    382 static void dummy_hrtimer_pcm_elapsed(unsigned long priv)
    383 {
    384         struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv;
    385         if (atomic_read(&dpcm->running))
    386                 snd_pcm_period_elapsed(dpcm->substream);
    387 }
    388366
    389367static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer)
     
    394372        if (!atomic_read(&dpcm->running))
    395373                return HRTIMER_NORESTART;
    396         tasklet_schedule(&dpcm->tasklet);
     374        /*
     375         * In cases of XRUN and draining, this calls .trigger to stop PCM
     376         * substream.
     377         */
     378        snd_pcm_period_elapsed(dpcm->substream);
     379        if (!atomic_read(&dpcm->running))
     380                return HRTIMER_NORESTART;
     381
    397382        hrtimer_forward_now(timer, dpcm->period_time);
    398383        return HRTIMER_RESTART;
     
    404389
    405390        dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer);
    406         hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL);
     391        hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL_SOFT);
    407392        atomic_set(&dpcm->running, 1);
    408393        return 0;
     
    414399
    415400        atomic_set(&dpcm->running, 0);
     401        if (!hrtimer_callback_running(&dpcm->timer))
     402                hrtimer_cancel(&dpcm->timer);
     403        return 0;
     404}
     405
     406static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
     407{
    416408        hrtimer_cancel(&dpcm->timer);
    417         return 0;
    418 }
    419 
    420 static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
    421 {
    422         hrtimer_cancel(&dpcm->timer);
    423         tasklet_kill(&dpcm->tasklet);
    424409}
    425410
     
    466451                return -ENOMEM;
    467452        substream->runtime->private_data = dpcm;
    468         hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
     453        hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
    469454        dpcm->timer.function = dummy_hrtimer_callback;
    470455        dpcm->substream = substream;
    471456        atomic_set(&dpcm->running, 0);
    472         tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed,
    473                      (unsigned long)dpcm);
    474457        return 0;
    475458}
     
    482465}
    483466
    484 static struct dummy_timer_ops dummy_hrtimer_ops = {
     467static const struct dummy_timer_ops dummy_hrtimer_ops = {
    485468        .create =       dummy_hrtimer_create,
    486469        .free =         dummy_hrtimer_free,
     
    520503}
    521504
    522 static struct snd_pcm_hardware dummy_pcm_hardware = {
     505static const struct snd_pcm_hardware dummy_pcm_hardware = {
    523506        .info =                 (SNDRV_PCM_INFO_MMAP |
    524507                                 SNDRV_PCM_INFO_INTERLEAVED |
     
    644627
    645628static int dummy_pcm_copy(struct snd_pcm_substream *substream,
    646                           int channel, snd_pcm_uframes_t pos,
    647                           void __user *dst, snd_pcm_uframes_t count)
     629                          int channel, unsigned long pos,
     630                          void __user *dst, unsigned long bytes)
    648631{
    649632        return 0; /* do nothing */
    650633}
    651634
     635static int dummy_pcm_copy_kernel(struct snd_pcm_substream *substream,
     636                                 int channel, unsigned long pos,
     637                                 void *dst, unsigned long bytes)
     638{
     639        return 0; /* do nothing */
     640}
     641
    652642static int dummy_pcm_silence(struct snd_pcm_substream *substream,
    653                              int channel, snd_pcm_uframes_t pos,
    654                              snd_pcm_uframes_t count)
     643                             int channel, unsigned long pos,
     644                             unsigned long bytes)
    655645{
    656646        return 0; /* do nothing */
     
    683673        .trigger =      dummy_pcm_trigger,
    684674        .pointer =      dummy_pcm_pointer,
    685         .copy =         dummy_pcm_copy,
    686         .silence =      dummy_pcm_silence,
     675        .copy_user =    dummy_pcm_copy,
     676        .copy_kernel =  dummy_pcm_copy_kernel,
     677        .fill_silence = dummy_pcm_silence,
    687678        .page =         dummy_pcm_page,
    688679};
    689680
    690 static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
    691                                         int substreams)
     681static int snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
     682                              int substreams)
    692683{
    693684        struct snd_pcm *pcm;
     
    820811}
    821812
     813static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol,
     814                                struct snd_ctl_elem_info *info)
     815{
     816        static const char *const names[] = { "None", "CD Player" };
     817
     818        return snd_ctl_enum_info(info, 1, 2, names);
     819}
     820
     821static int snd_dummy_iobox_get(struct snd_kcontrol *kcontrol,
     822                               struct snd_ctl_elem_value *value)
     823{
     824        struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
     825
     826        value->value.enumerated.item[0] = dummy->iobox;
     827        return 0;
     828}
     829
     830static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol,
     831                               struct snd_ctl_elem_value *value)
     832{
     833        struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
     834        int changed;
     835
     836        if (value->value.enumerated.item[0] > 1)
     837                return -EINVAL;
     838
     839        changed = value->value.enumerated.item[0] != dummy->iobox;
     840        if (changed) {
     841                dummy->iobox = value->value.enumerated.item[0];
     842
     843                if (dummy->iobox) {
     844                        dummy->cd_volume_ctl->vd[0].access &=
     845                                ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
     846                        dummy->cd_switch_ctl->vd[0].access &=
     847                                ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
     848                } else {
     849                        dummy->cd_volume_ctl->vd[0].access |=
     850                                SNDRV_CTL_ELEM_ACCESS_INACTIVE;
     851                        dummy->cd_switch_ctl->vd[0].access |=
     852                                SNDRV_CTL_ELEM_ACCESS_INACTIVE;
     853                }
     854
     855                snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
     856                               &dummy->cd_volume_ctl->id);
     857                snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
     858                               &dummy->cd_switch_ctl->id);
     859        }
     860
     861        return changed;
     862}
     863
    822864static struct snd_kcontrol_new snd_dummy_controls[] = {
    823865DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
     
    830872DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
    831873DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
    832 DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
    833 };
    834 
    835 static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
     874DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD),
     875{
     876        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     877        .name  = "External I/O Box",
     878        .info  = snd_dummy_iobox_info,
     879        .get   = snd_dummy_iobox_get,
     880        .put   = snd_dummy_iobox_put,
     881},
     882};
     883
     884static int snd_card_dummy_new_mixer(struct snd_dummy *dummy)
    836885{
    837886        struct snd_card *card = dummy->card;
     887        struct snd_kcontrol *kcontrol;
    838888        unsigned int idx;
    839889        int err;
     
    841891        spin_lock_init(&dummy->mixer_lock);
    842892        strcpy(card->mixername, "Dummy Mixer");
     893        dummy->iobox = 1;
    843894
    844895        for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
    845                 err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
     896                kcontrol = snd_ctl_new1(&snd_dummy_controls[idx], dummy);
     897                err = snd_ctl_add(card, kcontrol);
    846898                if (err < 0)
    847899                        return err;
    848         }
    849         return 0;
    850 }
    851 
    852 #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_PROC_FS)
     900                if (!strcmp(kcontrol->id.name, "CD Volume"))
     901                        dummy->cd_volume_ctl = kcontrol;
     902                else if (!strcmp(kcontrol->id.name, "CD Capture Switch"))
     903                        dummy->cd_switch_ctl = kcontrol;
     904
     905        }
     906        return 0;
     907}
     908
     909#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_PROC_FS)
    853910/*
    854911 * proc interface
     
    859916        int i;
    860917
    861         for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
     918        for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
    862919                if (dummy->pcm_hw.formats & (1ULL << i))
    863920                        snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
     
    9561013                        continue;
    9571014                snd_info_get_str(item, ptr, sizeof(item));
    958                 if (strict_strtoull(item, 0, &val))
     1015                if (kstrtoull(item, 0, &val))
    9591016                        continue;
    9601017                if (fields[i].size == sizeof(int))
     
    9651022}
    9661023
    967 static void __devinit dummy_proc_init(struct snd_dummy *chip)
    968 {
    969         struct snd_info_entry *entry;
    970 
    971         if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) {
    972                 snd_info_set_text_ops(entry, chip, dummy_proc_read);
    973                 entry->c.text.write = dummy_proc_write;
    974                 entry->mode |= S_IWUSR;
    975                 entry->private_data = chip;
    976         }
     1024static void dummy_proc_init(struct snd_dummy *chip)
     1025{
     1026        snd_card_rw_proc_new(chip->card, "dummy_pcm", chip,
     1027                             dummy_proc_read, dummy_proc_write);
    9771028}
    9781029#else
    9791030#define dummy_proc_init(x)
    980 #endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
    981 
    982 static int __devinit snd_dummy_probe(struct platform_device *devptr)
     1031#endif /* CONFIG_SND_DEBUG && CONFIG_SND_PROC_FS */
     1032
     1033static int snd_dummy_probe(struct platform_device *devptr)
    9831034{
    9841035        struct snd_card *card;
     
    9881039        int dev = devptr->id;
    9891040
    990         err = snd_card_create(index[dev], id[dev], THIS_MODULE,
    991                               sizeof(struct snd_dummy), &card);
     1041        err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
     1042                           sizeof(struct snd_dummy), &card);
    9921043        if (err < 0)
    9931044                return err;
     
    10481099        dummy_proc_init(dummy);
    10491100
    1050         snd_card_set_dev(card, &devptr->dev);
    1051 
    10521101        err = snd_card_register(card);
    10531102        if (err == 0) {
     
    10601109}
    10611110
    1062 static int __devexit snd_dummy_remove(struct platform_device *devptr)
     1111static int snd_dummy_remove(struct platform_device *devptr)
    10631112{
    10641113        snd_card_free(platform_get_drvdata(devptr));
    1065         platform_set_drvdata(devptr, NULL);
    1066         return 0;
    1067 }
    1068 
    1069 #ifdef CONFIG_PM
    1070 static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
    1071 {
    1072         struct snd_card *card = platform_get_drvdata(pdev);
    1073         struct snd_dummy *dummy = card->private_data;
     1114        return 0;
     1115}
     1116
     1117#ifdef CONFIG_PM_SLEEP
     1118static int snd_dummy_suspend(struct device *pdev)
     1119{
     1120        struct snd_card *card = dev_get_drvdata(pdev);
    10741121
    10751122        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
    1076         snd_pcm_suspend_all(dummy->pcm);
    10771123        return 0;
    10781124}
    10791125       
    1080 static int snd_dummy_resume(struct platform_device *pdev)
    1081 {
    1082         struct snd_card *card = platform_get_drvdata(pdev);
     1126static int snd_dummy_resume(struct device *pdev)
     1127{
     1128        struct snd_card *card = dev_get_drvdata(pdev);
    10831129
    10841130        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
    10851131        return 0;
    10861132}
     1133
     1134static SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
     1135#define SND_DUMMY_PM_OPS        &snd_dummy_pm
     1136#else
     1137#define SND_DUMMY_PM_OPS        NULL
    10871138#endif
    10881139
     
    10911142static struct platform_driver snd_dummy_driver = {
    10921143        .probe          = snd_dummy_probe,
    1093         .remove         = __devexit_p(snd_dummy_remove),
    1094 #ifdef CONFIG_PM
    1095         .suspend        = snd_dummy_suspend,
    1096         .resume         = snd_dummy_resume,
    1097 #endif
     1144        .remove         = snd_dummy_remove,
    10981145        .driver         = {
    1099                 .name   = SND_DUMMY_DRIVER
     1146                .name   = SND_DUMMY_DRIVER,
     1147                .pm     = SND_DUMMY_PM_OPS,
    11001148        },
    11011149};
Note: See TracChangeset for help on using the changeset viewer.