Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * bebob_focusrite.c - a part of driver for BeBoB based devices
0004  *
0005  * Copyright (c) 2013-2014 Takashi Sakamoto
0006  */
0007 
0008 #include "./bebob.h"
0009 
0010 #define ANA_IN  "Analog In"
0011 #define DIG_IN  "Digital In"
0012 #define ANA_OUT "Analog Out"
0013 #define DIG_OUT "Digital Out"
0014 #define STM_IN  "Stream In"
0015 
0016 #define SAFFIRE_ADDRESS_BASE            0x000100000000ULL
0017 
0018 #define SAFFIRE_OFFSET_CLOCK_SOURCE     0x00f8
0019 #define SAFFIREPRO_OFFSET_CLOCK_SOURCE      0x0174
0020 
0021 /* whether sync to external device or not */
0022 #define SAFFIRE_OFFSET_CLOCK_SYNC_EXT       0x013c
0023 #define SAFFIRE_LE_OFFSET_CLOCK_SYNC_EXT    0x0432
0024 #define SAFFIREPRO_OFFSET_CLOCK_SYNC_EXT    0x0164
0025 
0026 #define SAFFIRE_CLOCK_SOURCE_INTERNAL       0
0027 #define SAFFIRE_CLOCK_SOURCE_SPDIF      1
0028 
0029 /* clock sources as returned from register of Saffire Pro 10 and 26 */
0030 #define SAFFIREPRO_CLOCK_SOURCE_SELECT_MASK 0x000000ff
0031 #define SAFFIREPRO_CLOCK_SOURCE_DETECT_MASK 0x0000ff00
0032 #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL    0
0033 #define SAFFIREPRO_CLOCK_SOURCE_SKIP        1 /* never used on hardware */
0034 #define SAFFIREPRO_CLOCK_SOURCE_SPDIF       2
0035 #define SAFFIREPRO_CLOCK_SOURCE_ADAT1       3 /* not used on s.pro. 10 */
0036 #define SAFFIREPRO_CLOCK_SOURCE_ADAT2       4 /* not used on s.pro. 10 */
0037 #define SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK   5
0038 #define SAFFIREPRO_CLOCK_SOURCE_COUNT       6
0039 
0040 /* S/PDIF, ADAT1, ADAT2 is enabled or not. three quadlets */
0041 #define SAFFIREPRO_ENABLE_DIG_IFACES        0x01a4
0042 
0043 /* saffirepro has its own parameter for sampling frequency */
0044 #define SAFFIREPRO_RATE_NOREBOOT        0x01cc
0045 /* index is the value for this register */
0046 static const unsigned int rates[] = {
0047     [0] = 0,
0048     [1] = 44100,
0049     [2] = 48000,
0050     [3] = 88200,
0051     [4] = 96000,
0052     [5] = 176400,
0053     [6] = 192000
0054 };
0055 
0056 /* saffire(no label)/saffire LE has metering */
0057 #define SAFFIRE_OFFSET_METER            0x0100
0058 #define SAFFIRE_LE_OFFSET_METER         0x0168
0059 
0060 static inline int
0061 saffire_read_block(struct snd_bebob *bebob, u64 offset,
0062            u32 *buf, unsigned int size)
0063 {
0064     unsigned int i;
0065     int err;
0066     __be32 *tmp = (__be32 *)buf;
0067 
0068     err =  snd_fw_transaction(bebob->unit, TCODE_READ_BLOCK_REQUEST,
0069                   SAFFIRE_ADDRESS_BASE + offset,
0070                   tmp, size, 0);
0071     if (err < 0)
0072         goto end;
0073 
0074     for (i = 0; i < size / sizeof(u32); i++)
0075         buf[i] = be32_to_cpu(tmp[i]);
0076 end:
0077     return err;
0078 }
0079 
0080 static inline int
0081 saffire_read_quad(struct snd_bebob *bebob, u64 offset, u32 *value)
0082 {
0083     int err;
0084     __be32 tmp;
0085 
0086     err = snd_fw_transaction(bebob->unit, TCODE_READ_QUADLET_REQUEST,
0087                  SAFFIRE_ADDRESS_BASE + offset,
0088                  &tmp, sizeof(__be32), 0);
0089     if (err < 0)
0090         goto end;
0091 
0092     *value = be32_to_cpu(tmp);
0093 end:
0094     return err;
0095 }
0096 
0097 static inline int
0098 saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value)
0099 {
0100     __be32 data = cpu_to_be32(value);
0101 
0102     return snd_fw_transaction(bebob->unit, TCODE_WRITE_QUADLET_REQUEST,
0103                   SAFFIRE_ADDRESS_BASE + offset,
0104                   &data, sizeof(__be32), 0);
0105 }
0106 
0107 static const enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = {
0108     SND_BEBOB_CLOCK_TYPE_INTERNAL,
0109     SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* S/PDIF */
0110     SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* Word Clock */
0111 };
0112 static const enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = {
0113     SND_BEBOB_CLOCK_TYPE_INTERNAL,
0114     SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* S/PDIF */
0115     SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* ADAT1 */
0116     SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* ADAT2 */
0117     SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* Word Clock */
0118 };
0119 /* Value maps between registers and labels for SaffirePro 10/26. */
0120 static const signed char saffirepro_clk_maps[][SAFFIREPRO_CLOCK_SOURCE_COUNT] = {
0121     /* SaffirePro 10 */
0122     [0] = {
0123         [SAFFIREPRO_CLOCK_SOURCE_INTERNAL]  =  0,
0124         [SAFFIREPRO_CLOCK_SOURCE_SKIP]      = -1, /* not supported */
0125         [SAFFIREPRO_CLOCK_SOURCE_SPDIF]     =  1,
0126         [SAFFIREPRO_CLOCK_SOURCE_ADAT1]     = -1, /* not supported */
0127         [SAFFIREPRO_CLOCK_SOURCE_ADAT2]     = -1, /* not supported */
0128         [SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK] =  2,
0129     },
0130     /* SaffirePro 26 */
0131     [1] = {
0132         [SAFFIREPRO_CLOCK_SOURCE_INTERNAL]  =  0,
0133         [SAFFIREPRO_CLOCK_SOURCE_SKIP]      = -1, /* not supported */
0134         [SAFFIREPRO_CLOCK_SOURCE_SPDIF]     =  1,
0135         [SAFFIREPRO_CLOCK_SOURCE_ADAT1]     =  2,
0136         [SAFFIREPRO_CLOCK_SOURCE_ADAT2]     =  3,
0137         [SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK] =  4,
0138     }
0139 };
0140 
0141 static int
0142 saffirepro_both_clk_freq_get(struct snd_bebob *bebob, unsigned int *rate)
0143 {
0144     u32 id;
0145     int err;
0146 
0147     err = saffire_read_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, &id);
0148     if (err < 0)
0149         goto end;
0150     if (id >= ARRAY_SIZE(rates))
0151         err = -EIO;
0152     else
0153         *rate = rates[id];
0154 end:
0155     return err;
0156 }
0157 static int
0158 saffirepro_both_clk_freq_set(struct snd_bebob *bebob, unsigned int rate)
0159 {
0160     u32 id;
0161 
0162     for (id = 0; id < ARRAY_SIZE(rates); id++) {
0163         if (rates[id] == rate)
0164             break;
0165     }
0166     if (id == ARRAY_SIZE(rates))
0167         return -EINVAL;
0168 
0169     return saffire_write_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, id);
0170 }
0171 
0172 /*
0173  * query hardware for current clock source, return our internally
0174  * used clock index in *id, depending on hardware.
0175  */
0176 static int
0177 saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
0178 {
0179     int err;
0180     u32 value;       /* clock source read from hw register */
0181     const signed char *map;
0182 
0183     err = saffire_read_quad(bebob, SAFFIREPRO_OFFSET_CLOCK_SOURCE, &value);
0184     if (err < 0)
0185         goto end;
0186 
0187     /* depending on hardware, use a different mapping */
0188     if (bebob->spec->clock->types == saffirepro_10_clk_src_types)
0189         map = saffirepro_clk_maps[0];
0190     else
0191         map = saffirepro_clk_maps[1];
0192 
0193     /* In a case that this driver cannot handle the value of register. */
0194     value &= SAFFIREPRO_CLOCK_SOURCE_SELECT_MASK;
0195     if (value >= SAFFIREPRO_CLOCK_SOURCE_COUNT || map[value] < 0) {
0196         err = -EIO;
0197         goto end;
0198     }
0199 
0200     *id = (unsigned int)map[value];
0201 end:
0202     return err;
0203 }
0204 
0205 const struct snd_bebob_spec saffire_le_spec;
0206 static const enum snd_bebob_clock_type saffire_both_clk_src_types[] = {
0207     SND_BEBOB_CLOCK_TYPE_INTERNAL,
0208     SND_BEBOB_CLOCK_TYPE_EXTERNAL,
0209 };
0210 static int
0211 saffire_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
0212 {
0213     int err;
0214     u32 value;
0215 
0216     err = saffire_read_quad(bebob, SAFFIRE_OFFSET_CLOCK_SOURCE, &value);
0217     if (err >= 0)
0218         *id = 0xff & value;
0219 
0220     return err;
0221 };
0222 static const char *const saffire_le_meter_labels[] = {
0223     ANA_IN, ANA_IN, DIG_IN,
0224     ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT,
0225     STM_IN, STM_IN
0226 };
0227 static const char *const saffire_meter_labels[] = {
0228     ANA_IN, ANA_IN,
0229     STM_IN, STM_IN, STM_IN, STM_IN, STM_IN,
0230 };
0231 static int
0232 saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
0233 {
0234     const struct snd_bebob_meter_spec *spec = bebob->spec->meter;
0235     unsigned int channels;
0236     u64 offset;
0237     int err;
0238 
0239     if (spec->labels == saffire_le_meter_labels)
0240         offset = SAFFIRE_LE_OFFSET_METER;
0241     else
0242         offset = SAFFIRE_OFFSET_METER;
0243 
0244     channels = spec->num * 2;
0245     if (size < channels * sizeof(u32))
0246         return -EIO;
0247 
0248     err = saffire_read_block(bebob, offset, buf, size);
0249     if (err >= 0 && spec->labels == saffire_le_meter_labels) {
0250         swap(buf[1], buf[3]);
0251         swap(buf[2], buf[3]);
0252         swap(buf[3], buf[4]);
0253 
0254         swap(buf[7], buf[10]);
0255         swap(buf[8], buf[10]);
0256         swap(buf[9], buf[11]);
0257         swap(buf[11], buf[12]);
0258 
0259         swap(buf[15], buf[16]);
0260     }
0261 
0262     return err;
0263 }
0264 
0265 static const struct snd_bebob_rate_spec saffirepro_both_rate_spec = {
0266     .get    = &saffirepro_both_clk_freq_get,
0267     .set    = &saffirepro_both_clk_freq_set,
0268 };
0269 /* Saffire Pro 26 I/O  */
0270 static const struct snd_bebob_clock_spec saffirepro_26_clk_spec = {
0271     .num    = ARRAY_SIZE(saffirepro_26_clk_src_types),
0272     .types  = saffirepro_26_clk_src_types,
0273     .get    = &saffirepro_both_clk_src_get,
0274 };
0275 const struct snd_bebob_spec saffirepro_26_spec = {
0276     .clock  = &saffirepro_26_clk_spec,
0277     .rate   = &saffirepro_both_rate_spec,
0278     .meter  = NULL
0279 };
0280 /* Saffire Pro 10 I/O */
0281 static const struct snd_bebob_clock_spec saffirepro_10_clk_spec = {
0282     .num    = ARRAY_SIZE(saffirepro_10_clk_src_types),
0283     .types  = saffirepro_10_clk_src_types,
0284     .get    = &saffirepro_both_clk_src_get,
0285 };
0286 const struct snd_bebob_spec saffirepro_10_spec = {
0287     .clock  = &saffirepro_10_clk_spec,
0288     .rate   = &saffirepro_both_rate_spec,
0289     .meter  = NULL
0290 };
0291 
0292 static const struct snd_bebob_rate_spec saffire_both_rate_spec = {
0293     .get    = &snd_bebob_stream_get_rate,
0294     .set    = &snd_bebob_stream_set_rate,
0295 };
0296 static const struct snd_bebob_clock_spec saffire_both_clk_spec = {
0297     .num    = ARRAY_SIZE(saffire_both_clk_src_types),
0298     .types  = saffire_both_clk_src_types,
0299     .get    = &saffire_both_clk_src_get,
0300 };
0301 /* Saffire LE */
0302 static const struct snd_bebob_meter_spec saffire_le_meter_spec = {
0303     .num    = ARRAY_SIZE(saffire_le_meter_labels),
0304     .labels = saffire_le_meter_labels,
0305     .get    = &saffire_meter_get,
0306 };
0307 const struct snd_bebob_spec saffire_le_spec = {
0308     .clock  = &saffire_both_clk_spec,
0309     .rate   = &saffire_both_rate_spec,
0310     .meter  = &saffire_le_meter_spec
0311 };
0312 /* Saffire */
0313 static const struct snd_bebob_meter_spec saffire_meter_spec = {
0314     .num    = ARRAY_SIZE(saffire_meter_labels),
0315     .labels = saffire_meter_labels,
0316     .get    = &saffire_meter_get,
0317 };
0318 const struct snd_bebob_spec saffire_spec = {
0319     .clock  = &saffire_both_clk_spec,
0320     .rate   = &saffire_both_rate_spec,
0321     .meter  = &saffire_meter_spec
0322 };