~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/core/pcm_drm_eld.c

Version: ~ [ linux-5.16-rc3 ] ~ [ linux-5.15.5 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.82 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.162 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.218 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.256 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.291 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.293 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  PCM DRM helpers
  3  *
  4  *   This program is free software; you can redistribute it and/or modify
  5  *   it under the terms of the GNU General Public License version 2 as
  6  *   published by the Free Software Foundation.
  7  */
  8 #include <linux/export.h>
  9 #include <drm/drm_edid.h>
 10 #include <sound/pcm.h>
 11 #include <sound/pcm_drm_eld.h>
 12 
 13 static const unsigned int eld_rates[] = {
 14         32000,
 15         44100,
 16         48000,
 17         88200,
 18         96000,
 19         176400,
 20         192000,
 21 };
 22 
 23 static unsigned int sad_max_channels(const u8 *sad)
 24 {
 25         return 1 + (sad[0] & 7);
 26 }
 27 
 28 static int eld_limit_rates(struct snd_pcm_hw_params *params,
 29                            struct snd_pcm_hw_rule *rule)
 30 {
 31         struct snd_interval *r = hw_param_interval(params, rule->var);
 32         struct snd_interval *c;
 33         unsigned int rate_mask = 7, i;
 34         const u8 *sad, *eld = rule->private;
 35 
 36         sad = drm_eld_sad(eld);
 37         if (sad) {
 38                 c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 39 
 40                 for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) {
 41                         unsigned max_channels = sad_max_channels(sad);
 42 
 43                         /*
 44                          * Exclude SADs which do not include the
 45                          * requested number of channels.
 46                          */
 47                         if (c->min <= max_channels)
 48                                 rate_mask |= sad[1];
 49                 }
 50         }
 51 
 52         return snd_interval_list(r, ARRAY_SIZE(eld_rates), eld_rates,
 53                                  rate_mask);
 54 }
 55 
 56 static int eld_limit_channels(struct snd_pcm_hw_params *params,
 57                               struct snd_pcm_hw_rule *rule)
 58 {
 59         struct snd_interval *c = hw_param_interval(params, rule->var);
 60         struct snd_interval *r;
 61         struct snd_interval t = { .min = 1, .max = 2, .integer = 1, };
 62         unsigned int i;
 63         const u8 *sad, *eld = rule->private;
 64 
 65         sad = drm_eld_sad(eld);
 66         if (sad) {
 67                 unsigned int rate_mask = 0;
 68 
 69                 /* Convert the rate interval to a mask */
 70                 r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 71                 for (i = 0; i < ARRAY_SIZE(eld_rates); i++)
 72                         if (r->min <= eld_rates[i] && r->max >= eld_rates[i])
 73                                 rate_mask |= BIT(i);
 74 
 75                 for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3)
 76                         if (rate_mask & sad[1])
 77                                 t.max = max(t.max, sad_max_channels(sad));
 78         }
 79 
 80         return snd_interval_refine(c, &t);
 81 }
 82 
 83 int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime *runtime, void *eld)
 84 {
 85         int ret;
 86 
 87         ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 88                                   eld_limit_rates, eld,
 89                                   SNDRV_PCM_HW_PARAM_CHANNELS, -1);
 90         if (ret < 0)
 91                 return ret;
 92 
 93         ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 94                                   eld_limit_channels, eld,
 95                                   SNDRV_PCM_HW_PARAM_RATE, -1);
 96 
 97         return ret;
 98 }
 99 EXPORT_SYMBOL_GPL(snd_pcm_hw_constraint_eld);
100 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp