Alsa-devel
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
January 2017
- 145 participants
- 276 discussions
30 Jan '17
Add mixer quirk for Tascam US-16x08 usb interface.
Even that this an usb compliant device,
the input channels and DSP functions (EQ/Compressor)
arn't accessible by default.
Signed-off by: Detlef Urban <onkel(a)paraair.de>
---
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 2d2d122..5394264 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -10,6 +10,9 @@ snd-usb-audio-objs := card.o \
mixer.o \
mixer_quirks.o \
mixer_scarlett.o \
+ mixer_us16x08.o \
+ mixer_us16x08_eq.o \
+ mixer_us16x08_comp.o \
pcm.o \
proc.o \
quirks.o \
@@ -25,4 +28,3 @@ obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/
-obj-$(CONFIG_SND_USB_LINE6) += line6/
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 04991b0..4fa0053 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -43,6 +43,7 @@
#include "mixer.h"
#include "mixer_quirks.h"
#include "mixer_scarlett.h"
+#include "mixer_us16x08.h"
#include "helper.h"
extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
@@ -1729,6 +1730,10 @@ int snd_usb_mixer_apply_create_quirk(struct
usb_mixer_interface *mixer)
return err;
switch (mixer->chip->usb_id) {
+ /* Tascam US-16x08 */
+ case USB_ID(0x0644, 0x8047):
+ err = snd_us16x08_controls_create(mixer);
+ break;
case USB_ID(0x041e, 0x3020):
case USB_ID(0x041e, 0x3040):
case USB_ID(0x041e, 0x3042):
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
new file mode 100644
index 0000000..177ec5f
--- /dev/null
+++ b/sound/usb/mixer_us16x08.c
@@ -0,0 +1,815 @@
+/*
+ * Tascam US-16x08 ALSA driver
+ *
+ * Copyright (c) 2016 by Detlef Urban (onkel(a)paraair.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/audio-v2.h>
+#include "linux/kthread.h"
+
+#include <sound/core.h>
+#include <sound/control.h>
+
+#include "usbaudio.h"
+#include "mixer.h"
+#include "helper.h"
+
+#include "mixer_us16x08.h"
+
+#define FADER_INFOPUTGET_NOLOG
+
+static char route_msg[] = {
+ 0x61,
+ 0x02,
+ 0x03, /* input from master (0x02) or input from computer bus (0x03) */
+ 0x62,
+ 0x02,
+ 0x01, /* input index (0x01/0x02 eq. left/right) or bus (0x01-0x08) */
+ 0x41,
+ 0x01,
+ 0x61,
+ 0x02,
+ 0x01,
+ 0x62,
+ 0x02,
+ 0x01, /* output index (0x01-0x08) */
+ 0x42,
+ 0x01,
+ 0x43,
+ 0x01,
+ 0x00,
+ 0x00
+};
+
+static char mix_init_msg1[] = {
+ 0x71, 0x01, 0x00, 0x00
+};
+static char mix_init_msg2[] = {
+ 0x62, 0x02, 0x00, 0x61, 0x02, 0x04, 0xb1, 0x01, 0x00, 0x00
+};
+
+static int comp_channel = 1;
+
+static char mix_msg_in[] = {
+ CTLMSGHEAD_IN, /* the default message head */
+ 0x81, /* 0x06: Controller ID */
+ 0x02, /* 0x07: */
+ 0x00, /* 0x08: Value of common mixer */
+ 0x00,
+ 0x00
+};
+static char mix_msg_out[] = {
+ CTLMSGHEAD_OUT, /* the default message head */
+ 0x81, /* 0x06: Controller ID */
+ 0x02, /* 0x07: */
+ 0x00, /* 0x08: Value of common mixer */
+ 0x00,
+ 0x00
+};
+
+static char bypass_msg_out[] = {
+ 0x45,
+ 0x02,
+ 0x01, // on/off flag
+ 0x00,
+ 0x00
+};
+
+static char bus_msg_out[] = {
+ 0x44,
+ 0x02,
+ 0x01, // on/off flag
+ 0x00,
+ 0x00
+};
+
+int snd_us16x08_recv_urb(struct snd_usb_audio *chip,
+ unsigned char *buf, int size)
+{
+
+ mutex_lock(&chip->mutex);
+ snd_usb_ctl_msg(chip->dev,
+ usb_rcvctrlpipe(chip->dev, 0),
+ SND_US16X08_URB_METER_REQUEST,
+ SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size);
+ mutex_unlock(&chip->mutex);
+ return 0;
+}
+
+int snd_us16x08_recv_urb_0xa1(struct snd_usb_audio *chip,
+ char *buffer, int size)
+{
+
+ unsigned char buf[64] = {0,};
+ int err = snd_usb_ctl_msg(chip->dev,
+ usb_rcvctrlpipe(chip->dev, 0),
+ 2,
+ 0xa1, 0x0100, 0x100, buf, 14);
+ dev_err(&chip->dev->dev,
+ "us16x08: snd_us16x08_recv_urb: error: %d\n", err);
+
+ return 0;
+}
+
+/* wrapper function to send prepared URB buffer to usb device. Return -1
+ * if something went wrong (FIXME: have to have more helpful error
numbers) */
+int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size)
+{
+ int count = -1;
+
+ if (chip) {
+ count = snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0),
+ SND_US16X08_URB_REQUEST,
+ SND_US16X08_URB_REQUESTTYPE,
+ 0, 0, buf, size);
+ }
+
+ return(count == size) ? 0 : -1;
+}
+
+struct meter_resp {
+ uint8_t a0;
+ uint8_t a1;
+ uint8_t a2;
+ uint8_t b0;
+ uint8_t b1;
+ uint8_t b2;
+ uint8_t c0;
+ uint8_t c1;
+ uint8_t c2;
+ uint8_t c3;
+};
+struct meter_resp *resp = NULL;
+unsigned char meter_urb_buf[64] = {0,};
+
+int snd_us16x08_route_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
+ uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
+ uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
+ return 0;
+}
+
+static int snd_us16x08_route_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_us16x08_fader *store =
+ (struct snd_us16x08_fader *) elem->private_data;
+ int index = ucontrol->id.index;
+
+ /* we have only eight output channels, so ignore all others */
+ ucontrol->value.integer.value[0] = store->value[index];
+
+ return 0;
+}
+
+static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_fader *store =
+ (struct snd_us16x08_fader *) elem->private_data;
+ int index = ucontrol->id.index;
+ char buf[sizeof(route_msg)];
+ int val, val_org, err = 0;
+
+ /* prepare the message buffer from static one */
+ memcpy(buf, route_msg, sizeof(route_msg));
+
+ /* get the new value */
+ val = ucontrol->value.integer.value[0];
+ if (val < 2) { /* input comes from a master channel */
+ val_org = val;
+ buf[2] = 0x02;
+ } else { /* input comes from a computer channel */
+ buf[2] = 0x03;
+ val_org = val - 2;
+ }
+
+ buf[5] = (unsigned char) (val_org & 0x0f) + 1;
+ buf[13] = index + 1;
+
+ err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
+
+ if (err == 0)
+ store->value[index] = val;
+
+ return err == 0 ? 1 : 0;
+}
+
+static int snd_us16x08_master_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_us16x08_fader *store =
+ (struct snd_us16x08_fader *) elem->private_data;
+ int index = ucontrol->id.index;
+
+ ucontrol->value.integer.value[0] = store->value[index];
+
+ return 0;
+}
+
+int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
+ uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
+ uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
+ return 0;
+}
+
+static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_fader *store =
+ (struct snd_us16x08_fader *) elem->private_data;
+ char buf[sizeof(mix_msg_out)];
+ int val, err = 0;
+ int index = ucontrol->id.index;
+
+
+ /* prepare the message buffer from static one */
+ memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
+
+ val = ucontrol->value.integer.value[0];
+ dev_dbg(&chip->dev->dev,
+ "snd_us16x08_master_put index:%d, val, %d", index, val);
+
+ buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
+ buf[6] = elem->head.id;
+
+ buf[5] = index + 1;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
+
+ if (err == 0)
+ store->value[index] = val;
+
+ return err == 0 ? 1 : 0;
+}
+
+static int snd_us16x08_bypass_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_us16x08_bypass_store *store =
+ (struct snd_us16x08_bypass_store *) elem->private_data;
+
+ ucontrol->value.integer.value[0] = store->value;
+
+ return 0;
+}
+
+static int snd_us16x08_bypass_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_bypass_store *store =
+ (struct snd_us16x08_bypass_store *) elem->private_data;
+
+ // prepare message buffer
+ char buf[sizeof(bypass_msg_out)];
+ int val, err = 0;
+
+ /* prepare the message buffer from static one */
+ memcpy(buf, bypass_msg_out, sizeof(bypass_msg_out));
+
+ val = ucontrol->value.integer.value[0];
+ dev_dbg(&chip->dev->dev, "snd_us16x08_bypass_put val: %d", val);
+
+ buf[2] = val;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(bypass_msg_out));
+
+ if (err == 0)
+ store->value = val;
+
+ return err == 0 ? 1 : 0;
+}
+
+static int snd_us16x08_bussout_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_bypass_store *store =
+ (struct snd_us16x08_bypass_store *) elem->private_data;
+
+ // prepare message buffer
+ char buf[sizeof(bus_msg_out)];
+ int val, err = 0;
+
+ /* prepare the message buffer from static one */
+ memcpy(buf, bus_msg_out, sizeof(bus_msg_out));
+
+ val = ucontrol->value.integer.value[0];
+ dev_dbg(&chip->dev->dev, "snd_us16x08_bus_out_put val: %d", val);
+
+ buf[2] = val;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(bus_msg_out));
+
+ if (err == 0)
+ store->value = val;
+
+ return err == 0 ? 1 : 0;
+}
+
+/*
+gets a current mixer value from common store
+ */
+static int snd_us16x08_mix_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_us16x08_fader *store =
+ (struct snd_us16x08_fader *) elem->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ int index = ucontrol->id.index;
+
+ ucontrol->value.integer.value[0] = store->value[index];
+ dev_dbg(&chip->dev->dev,
+ "snd_us16x08_mix_get: index:%d, val:%d\n",
+ index, store->value[index]);
+
+ return 0;
+}
+
+static int snd_us16x08_mix_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_fader *store =
+ (struct snd_us16x08_fader *) elem->private_data;
+ char buf[sizeof(mix_msg_in)];
+ int val, err;
+ int index = ucontrol->id.index;
+
+
+ memcpy(buf, mix_msg_in, sizeof(mix_msg_in));
+
+ val = ucontrol->value.integer.value[0];
+
+ buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
+ buf[6] = elem->head.id;
+ buf[5] = index + 1;
+
+ err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
+
+ if (err == 0)
+ store->value[index] = val;
+
+ return err == 0 ? 1 : 0;
+}
+
+int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
+ uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
+ uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
+ return 0;
+}
+
+static int snd_us16x08_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->value.integer.max = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.step = 1;
+ return 0;
+}
+
+
+static struct snd_kcontrol_new snd_us16x08_mix_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_mix_get,
+ .put = snd_us16x08_mix_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133),
+};
+static struct snd_kcontrol_new snd_us16x08_pan_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_mix_get,
+ .put = snd_us16x08_mix_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 254),
+};
+static struct snd_kcontrol_new snd_us16x08_mute_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 16,
+ .info = snd_us16x08_switch_info,
+ .get = snd_us16x08_mix_get,
+ .put = snd_us16x08_mix_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1),
+};
+static struct snd_kcontrol_new snd_us16x08_phase_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 16,
+ .info = snd_us16x08_switch_info,
+ .get = snd_us16x08_mix_get,
+ .put = snd_us16x08_mix_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1),
+};
+static struct snd_kcontrol_new snd_us16x08_master_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 2,
+ .info = snd_us16x08_master_info,
+ .get = snd_us16x08_master_get,
+ .put = snd_us16x08_master_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133),
+};
+static struct snd_kcontrol_new snd_us16x08_route_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 8,
+ .info = snd_us16x08_route_info,
+ .get = snd_us16x08_route_get,
+ .put = snd_us16x08_route_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9),
+};
+static struct snd_kcontrol_new snd_us16x08_bypass_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 1,
+ .info = snd_us16x08_switch_info,
+ .get = snd_us16x08_bypass_get,
+ .put = snd_us16x08_bypass_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1),
+};
+static struct snd_kcontrol_new snd_us16x08_bussout_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 1,
+ .info = snd_us16x08_switch_info,
+ .get = snd_us16x08_bypass_get,
+ .put = snd_us16x08_bussout_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1),
+};
+
+static struct snd_kcontrol_new snd_us16x08_master_mute_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .count = 1,
+ .info = snd_us16x08_switch_info,
+ .get = snd_us16x08_master_get,
+ .put = snd_us16x08_master_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1),
+};
+
+struct snd_us16x08_fader *snd_us16x08_create_mix_store(int default_val)
+{
+ int i;
+ struct snd_us16x08_fader *tmp =
+ kmalloc(sizeof(struct snd_us16x08_fader), GFP_KERNEL);
+
+ for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++)
+ tmp->value[i] = default_val;
+ return tmp;
+}
+
+struct snd_us16x08_bypass_store *snd_us16x08_create_single_store(
+ int default_val)
+{
+ struct snd_us16x08_bypass_store *tmp =
+ kmalloc(sizeof(struct snd_us16x08_bypass_store), GFP_KERNEL);
+
+ tmp->value = default_val;
+ return tmp;
+}
+
+void snd_us16x08_free_mix_store(struct snd_kcontrol *kctl)
+{
+ snd_usb_mixer_elem_free(kctl);
+}
+
+/*
+meter level transports
+ */
+static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->value.integer.max = 0x7FFF;
+ uinfo->value.integer.min = 0;
+
+ return 0;
+}
+
+static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 1;
+}
+
+static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i, set;
+ int val;
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_meter_store *store = elem->private_data;
+ struct snd_us16x08_comp_store* comp_store;
+
+ if (elem) {
+ store = (struct snd_us16x08_meter_store *) elem->private_data;
+ chip = elem->head.mixer->chip;
+ }
+
+ switch (kcontrol->private_value) {
+ case 0:
+ snd_us16x08_send_urb(chip, mix_init_msg1, 4);
+ snd_us16x08_recv_urb(chip, meter_urb_buf,
+ sizeof(meter_urb_buf));
+ kcontrol->private_value++;
+ break;
+ case 1:
+ snd_us16x08_recv_urb(chip, meter_urb_buf,
+ sizeof(meter_urb_buf));
+ kcontrol->private_value++;
+ break;
+ case 2:
+ snd_us16x08_recv_urb(chip, meter_urb_buf,
+ sizeof(meter_urb_buf));
+ kcontrol->private_value++;
+ break;
+ case 3:
+ mix_init_msg2[2] = comp_channel++;
+ snd_us16x08_send_urb(chip, mix_init_msg2, 10);
+ snd_us16x08_recv_urb(chip, meter_urb_buf,
+ sizeof(meter_urb_buf));
+ kcontrol->private_value = 0;
+
+ comp_store = get_comp_store();
+ if (comp_channel == 17)
+ comp_channel = 1;
+ while (!comp_store->valSwitch[comp_channel - 1] &&
+ comp_channel < 17)
+ comp_channel++;
+ if (comp_channel == 17)
+ comp_channel = 1;
+ break;
+
+ }
+
+ for (set = 0; set < 6; set++) {
+ resp = (struct meter_resp *) &(meter_urb_buf[4 + set * 10]);
+ val = resp->c2 + (resp->c3 << 8);
+ if (resp->a0 == 0x61 && resp->a1 == 0x02 &&
+ resp->a2 == 0x04 && resp->b0 == 0x62) {
+ if (resp->c0 == 0x72)
+ if (store)
+ store->meter_level[resp->b2 - 1] = val;
+ if (resp->c0 == 0xb2) {
+ if (store)
+ store->comp_level[resp->b2 - 1] = val;
+ }
+ }
+ if (resp->a0 == 0x61 && resp->a1 == 0x02 &&
+ resp->a2 == 0x02 && resp->b0 == 0x62) {
+ if (store)
+ store->master_level[resp->b2 - 1] = val;
+ }
+ }
+
+ for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
+ ucontrol->value.integer.value[i] =
+ store ? store->meter_level[i] : 0;
+ }
+
+ ucontrol->value.integer.value[i++] = store ? store->master_level[0]
: 0;
+ ucontrol->value.integer.value[i++] = store ? store->master_level[1]
: 0;
+
+ for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
+ ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
+ store ? store->comp_level[i] : 0;
+
+ return 1;
+}
+static struct snd_kcontrol_new snd_us16x08_meter_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .info = snd_us16x08_meter_info,
+ .get = snd_us16x08_meter_get,
+ .put = snd_us16x08_meter_put,
+};
+
+struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
+{
+ struct snd_us16x08_meter_store *tmp =
+ kzalloc(sizeof(struct snd_us16x08_meter_store), GFP_KERNEL);
+
+ if (!tmp)
+ return NULL;
+ return tmp;
+
+}
+
+void snd_us16x08_free_meter_store(struct snd_kcontrol *kctl)
+{
+ kfree(kctl->private_data);
+}
+
+int add_new_ctl(struct usb_mixer_interface *mixer,
+ const struct snd_kcontrol_new *ncontrol,
+ int index, int offset, int num, int val_type,
+ int channels, const char *name, const struct snd_us16x08_fader *opt,
+ opt_free freeer, struct usb_mixer_elem_info **elem_ret)
+{
+ struct snd_kcontrol *kctl;
+ struct usb_mixer_elem_info *elem;
+ int err;
+
+ usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name);
+
+ elem = kzalloc(sizeof(*elem), GFP_KERNEL);
+ if (!elem)
+ return -ENOMEM;
+
+ elem->head.mixer = mixer;
+ elem->control = offset;
+ elem->idx_off = num;
+ elem->head.id = index;
+ elem->val_type = val_type;
+ elem->channels = channels;
+ elem->private_data = (void *) opt;
+
+ kctl = snd_ctl_new1(ncontrol, elem);
+ if (!kctl) {
+ kfree(elem);
+ return -ENOMEM;
+ }
+
+ kctl->private_free = freeer;
+
+ strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
+
+ err = snd_usb_mixer_add_control(&elem->head, kctl);
+ if (err < 0)
+ return err;
+
+ if (elem_ret)
+ *elem_ret = elem;
+
+ return 0;
+}
+
+int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
+{
+
+ int err;
+ char name[64];
+ struct usb_mixer_elem_info *elem;
+
+
+ if (mixer->chip->num_interfaces > 0) {
+ struct snd_us16x08_fader *route_store =
+ snd_us16x08_create_mix_store(0);
+
+ route_store->value[0] = 0;
+ route_store->value[1] = 1;
+ route_store->value[2] = 4;
+ route_store->value[3] = 5;
+ route_store->value[4] = 6;
+ route_store->value[5] = 7;
+ route_store->value[6] = 8;
+ route_store->value[7] = 9;
+ snprintf(name, sizeof(name), "Route");
+ err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
+ 0x00, 0x00, 0,
+ USB_MIXER_U8, 1, name, (void *) route_store,
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+
+ snprintf(name, sizeof(name), "Master");
+ err = add_new_ctl(mixer, &snd_us16x08_master_ctl,
+ SND_US16X08_ID_FADER, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) snd_us16x08_create_mix_store(0),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "Bypass");
+ err = add_new_ctl(mixer, &snd_us16x08_bypass_ctl,
+ SND_US16X08_ID_BYPASS, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) snd_us16x08_create_single_store(0),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "Buss out");
+ err = add_new_ctl(mixer, &snd_us16x08_bussout_ctl,
+ SND_US16X08_ID_BUSS_OUT, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) snd_us16x08_create_single_store(0),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "Master Mute");
+ err = add_new_ctl(mixer, &snd_us16x08_master_mute_ctl,
+ SND_US16X08_ID_MUTE, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) snd_us16x08_create_single_store(0),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+
+ snprintf(name, sizeof(name), "Phase");
+ err = add_new_ctl(mixer, &snd_us16x08_phase_ctl,
+ SND_US16X08_ID_PHASE, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) snd_us16x08_create_mix_store(0),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "Fader");
+ err = add_new_ctl(mixer, &snd_us16x08_mix_ctl,
+ SND_US16X08_ID_FADER, 0x00, 0, USB_MIXER_S16, 1, name,
+ (void *) snd_us16x08_create_mix_store(127),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "3 Mute");
+ err = add_new_ctl(mixer, &snd_us16x08_mute_ctl,
+ SND_US16X08_ID_MUTE, 0x00, 0, USB_MIXER_BOOLEAN, 1,
+ name, (void *) snd_us16x08_create_mix_store(0),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "4 Pan");
+ err = add_new_ctl(mixer, &snd_us16x08_pan_ctl,
+ SND_US16X08_ID_PAN, 0x00, 0, USB_MIXER_U16, 1, name,
+ (void *) snd_us16x08_create_mix_store(127),
+ snd_us16x08_free_mix_store, &elem);
+ if (err < 0)
+ return err;
+
+ resp = kmalloc(sizeof(struct meter_resp), GFP_KERNEL);
+ if (!resp)
+ return -ENOMEM;
+
+ snprintf(name, sizeof(name), "Z Meter");
+ err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
+ SND_US16X08_ID_METER, 0x00, 0, USB_MIXER_U16, 1, name,
+ (void *) snd_us16x08_create_meter_store(),
+ snd_us16x08_free_meter_store, &elem);
+ if (err < 0)
+ return err;
+
+ err = snd_us16x08_controls_create_eq(mixer);
+ if (err < 0)
+ return err;
+
+ err = snd_us16x08_controls_create_comp(mixer);
+ if (err < 0)
+ return err;
+
+
+ } else {
+ usb_audio_dbg(mixer->chip,
+ "mixer->chip->num_interfaces == 0\n");
+ }
+
+ return 0;
+}
diff --git a/sound/usb/mixer_us16x08.h b/sound/usb/mixer_us16x08.h
new file mode 100644
index 0000000..6423547
--- /dev/null
+++ b/sound/usb/mixer_us16x08.h
@@ -0,0 +1,136 @@
+#ifndef __USB_MIXER_US16X08_H
+#define __USB_MIXER_US16X08_H
+
+
+#define SND_US16X08_MIN_CHANNELS 0
+#define SND_US16X08_MAX_CHANNELS 16
+
+/* define some bias, cause some alsa-mixers wont work with
+ * negative ranges or if mixer-min != 0 */
+#define SND_US16X08_NO_BIAS 0
+#define SND_US16X08_FADER_BIAS 127
+#define SND_US16X08_EQ_HIGHFREQ_BIAS 0x20
+#define SND_US16X08_COMP_THRESHOLD_BIAS 0x20
+#define SND_US16X08_COMP_ATTACK_BIAS 2
+#define SND_US16X08_COMP_RELEASE_BIAS 1
+
+/* get macro for components of kcontrol private_value */
+#define SND_US16X08_KCBIAS(x) ((x->private_value >> 24) & 0xff)
+#define SND_US16X08_KCSTEP(x) ((x->private_value >> 16) & 0xff)
+#define SND_US16X08_KCMIN(x) ((x->private_value >> 8) & 0xff)
+#define SND_US16X08_KCMAX(x) ((x->private_value >> 0) & 0xff)
+/* set macro for kcontrol private_value */
+#define SND_US16X08_KCSET(bias, step, min, max) \
+ ((bias << 24) | (step << 16) | (min << 8) | max)
+
+/* the URB request/type to control Tascam mixers */
+#define SND_US16X08_URB_REQUEST 0x1D
+#define SND_US16X08_URB_REQUESTTYPE 0x40
+
+/* the URB params to retrieve meter ranges */
+#define SND_US16X08_URB_METER_REQUEST 0x1e
+#define SND_US16X08_URB_METER_REQUESTTYPE 0xc0
+
+/* Common Channel control IDs */
+#define SND_US16X08_ID_BYPASS 0x45
+#define SND_US16X08_ID_BUSS_OUT 0x44
+#define SND_US16X08_ID_PHASE 0x85
+#define SND_US16X08_ID_MUTE 0x83
+#define SND_US16X08_ID_FADER 0x81
+#define SND_US16X08_ID_PAN 0x82
+#define SND_US16X08_ID_METER 0xB1
+
+/* EQ level IDs */
+#define SND_US16X08_ID_EQLOWLEVEL 0x01
+#define SND_US16X08_ID_EQLOWMIDLEVEL 0x02
+#define SND_US16X08_ID_EQHIGHMIDLEVEL 0x03
+#define SND_US16X08_ID_EQHIGHLEVEL 0x04
+
+/* EQ frequence IDs */
+#define SND_US16X08_ID_EQLOWFREQ 0x11
+#define SND_US16X08_ID_EQLOWMIDFREQ 0x12
+#define SND_US16X08_ID_EQHIGHMIDFREQ 0x13
+#define SND_US16X08_ID_EQHIGHFREQ 0x14
+
+/* EQ width IDs */
+#define SND_US16X08_ID_EQLOWMIDWIDTH 0x22
+#define SND_US16X08_ID_EQHIGHMIDWIDTH 0x23
+
+#define SND_US16X08_ID_EQENABLE 0x31
+
+/* Compressor Ids */
+#define SND_US16X08_ID_COMP_THRESHOLD 0x01
+#define SND_US16X08_ID_COMP_RATIO 0x02
+#define SND_US16X08_ID_COMP_ATTACK 0x03
+#define SND_US16X08_ID_COMP_RELEASE 0x04
+#define SND_US16X08_ID_COMP_GAIN 0x05
+#define SND_US16X08_ID_COMP_SWITCH 0x06
+
+struct snd_us16x08_fader {
+ uint8_t value[SND_US16X08_MAX_CHANNELS];
+};
+
+struct snd_us16x08_eq_store {
+ uint8_t valdB[SND_US16X08_MAX_CHANNELS];
+ uint8_t valFreq[SND_US16X08_MAX_CHANNELS];
+ uint8_t valWidth[SND_US16X08_MAX_CHANNELS];
+ uint8_t valSwitch[SND_US16X08_MAX_CHANNELS];
+};
+
+struct snd_us16x08_eq_all_store {
+ struct snd_us16x08_eq_store *low_store;
+ struct snd_us16x08_eq_store *midlow_store;
+ struct snd_us16x08_eq_store *midhigh_store;
+ struct snd_us16x08_eq_store *high_store;
+};
+
+struct snd_us16x08_comp_store {
+ int8_t valThreshold[SND_US16X08_MAX_CHANNELS];
+ uint8_t valAttack[SND_US16X08_MAX_CHANNELS];
+ uint8_t valRelease[SND_US16X08_MAX_CHANNELS];
+ uint8_t valRatio[SND_US16X08_MAX_CHANNELS];
+ uint8_t valGain[SND_US16X08_MAX_CHANNELS];
+ uint8_t valSwitch[SND_US16X08_MAX_CHANNELS];
+};
+
+struct snd_us16x08_meter_store {
+ long meter_level[SND_US16X08_MAX_CHANNELS];
+ long master_level[2]; /* level of meter for master output */
+ long comp_level[16]; /* compressor reduction level of current
channel */
+};
+
+struct snd_us16x08_bypass_store {
+ int value;
+};
+
+typedef void(*opt_free)(struct snd_kcontrol *kctl);
+
+
+/* |- Channel index (5) */
+/* | */
+/* v */
+#define CTLMSGHEAD_IN 0x61, 0x02, 0x04, 0x62, 0x02, 0x01
+#define CTLMSGHEAD_OUT 0x61, 0x02, 0x02, 0x62, 0x02, 0x01
+
+int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+
+int snd_us16x08_controls_create(struct usb_mixer_interface *mixer);
+
+int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size);
+
+int snd_us16x08_cur_channel(void);
+
+int add_new_ctl(struct usb_mixer_interface *mixer,
+ const struct snd_kcontrol_new *ncontrol,
+ int index, int offset, int num, int val_type, int channels,
+ const char *name, const struct snd_us16x08_fader *opt,
+ opt_free freeer, struct usb_mixer_elem_info **elem_ret);
+
+int snd_us16x08_controls_create_eq(struct usb_mixer_interface *mixer);
+int snd_us16x08_controls_create_comp(struct usb_mixer_interface *mixer);
+
+struct snd_us16x08_comp_store *get_comp_store(void);
+
+#endif /* __USB_MIXER_US16X08_H */
+
diff --git a/sound/usb/mixer_us16x08_comp.c b/sound/usb/mixer_us16x08_comp.c
new file mode 100644
index 0000000..2bc0146
--- /dev/null
+++ b/sound/usb/mixer_us16x08_comp.c
@@ -0,0 +1,316 @@
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/audio-v2.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+
+#include "usbaudio.h"
+#include "mixer.h"
+#include "helper.h"
+#include "power.h"
+
+#include "mixer_us16x08.h"
+
+#define COMP_INFOPUTGET_NOLOG
+
+static char comp_msg[] = {
+ CTLMSGHEAD_IN, /* default message head, equal to all mixers */
+ 0x91,
+ 0x02,
+ 0xf0, /* 0x08: Threshold db (8) (e0 ... 00) (+-0dB -- -32dB) x-32 */
+ 0x92,
+ 0x02,
+ 0x0a, /* 0x0b: Ratio (0a,0b,0d,0f,11,14,19,1e,23,28,32,3c,50,a0,ff) */
+ 0x93,
+ 0x02,
+ 0x02, /* 0x0e: Attack (0x02 ... 0xc0) (2ms ... 200ms) */
+ 0x94,
+ 0x02,
+ 0x01, /* 0x11: Release (0x01 ... 0x64) (10ms ... 1000ms) x*10 */
+ 0x95,
+ 0x02,
+ 0x03, /* 0x14: gain (0 ... 20) (0dB .. 20dB) */
+ 0x96,
+ 0x02,
+ 0x01,
+ 0x97,
+ 0x02,
+ 0x01, /* 0x1a: main Comp switch (0 ... 1) (off ... on)) */
+ 0x00,
+ 0x00
+};
+
+static char ratio_map[] = {
+ 0x0a, 0x0b, 0x0d, 0x0f, 0x11, 0x14, 0x19, 0x1e,
+ 0x23, 0x28, 0x32, 0x3c, 0x50, 0xa0, 0xff
+};
+
+struct snd_us16x08_comp_store *comp_store;
+
+int snd_us16x08_compswitch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->value.integer.max = 1;
+ uinfo->value.integer.min = 0;
+ return 0;
+}
+
+static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int val = 0;
+ int bias = (kcontrol->private_value >> 24) & 0xff;
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_comp_store *store =
+ ((struct snd_us16x08_comp_store *) elem->private_data);
+ int index = ucontrol->id.index;
+
+
+ switch (elem->head.id) {
+ case SND_US16X08_ID_COMP_THRESHOLD:
+ val = store->valThreshold[index];
+ dev_info(&chip->dev->dev,
+ "snd_us16x08_comp_get name:Threshold index: %d val:%d",
+ index, val);
+ break;
+ case SND_US16X08_ID_COMP_RATIO:
+ val = store->valRatio[index];
+ dev_info(&chip->dev->dev,
+ "snd_us16x08_comp_get name:Ratio index: %d val:%d",
+ index, val);
+ break;
+ case SND_US16X08_ID_COMP_ATTACK:
+ val = store->valAttack[index] - bias;
+ dev_info(&chip->dev->dev,
+ "snd_us16x08_comp_get name:Attack index: %d val:%d",
+ index, val);
+ break;
+ case SND_US16X08_ID_COMP_RELEASE:
+ val = store->valRelease[index] - bias;
+ dev_info(&chip->dev->dev,
+ "snd_us16x08_comp_get name:Release index: %d val:%d",
+ index, val);
+ break;
+ case SND_US16X08_ID_COMP_GAIN:
+ val = store->valGain[index];
+ dev_info(&chip->dev->dev,
+ "snd_us16x08_comp_get name:Gain index: %d val:%d",
+ index, val);
+ break;
+ case SND_US16X08_ID_COMP_SWITCH:
+ val = store->valSwitch[index];
+ dev_info(&chip->dev->dev,
+ "snd_us16x08_comp_get name:Switch index: %d val:%d",
+ index, val);
+ break;
+ }
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_comp_store *store =
+ ((struct snd_us16x08_comp_store *) elem->private_data);
+ int index = ucontrol->id.index;
+
+ char buf[sizeof(comp_msg)];
+ int val, err = 0;
+ int bias = SND_US16X08_KCBIAS(kcontrol);
+
+ memcpy(buf, comp_msg, sizeof(comp_msg));
+
+ val = ucontrol->value.integer.value[0];
+
+ switch (elem->head.id) {
+ case SND_US16X08_ID_COMP_THRESHOLD:
+ store->valThreshold[index] = val;
+ break;
+ case SND_US16X08_ID_COMP_RATIO:
+ store->valRatio[index] = val;
+ break;
+ case SND_US16X08_ID_COMP_ATTACK:
+ store->valAttack[index] = val + bias;
+ break;
+ case SND_US16X08_ID_COMP_RELEASE:
+ store->valRelease[index] = val + bias;
+ break;
+ case SND_US16X08_ID_COMP_GAIN:
+ store->valGain[index] = val;
+ break;
+ case SND_US16X08_ID_COMP_SWITCH:
+ store->valSwitch[index] = val;
+ break;
+ }
+
+ buf[8] = store->valThreshold[index] - SND_US16X08_COMP_THRESHOLD_BIAS;
+ buf[11] = ratio_map[store->valRatio[index]];
+ buf[14] = store->valAttack[index];
+ buf[17] = store->valRelease[index];
+ buf[20] = store->valGain[index];
+ buf[26] = store->valSwitch[index];
+
+ buf[5] = index + 1;
+
+ err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
+
+ return 1;
+}
+
+static struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_compswitch_info,
+ .get = snd_us16x08_comp_get,
+ .put = snd_us16x08_comp_put,
+ .private_value = ((SND_US16X08_NO_BIAS << 24) | /*bias*/
+ (1 << 16) | /*step*/
+ (0 << 8) | /*min*/
+ (1)), /*max*/
+};
+
+static struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_comp_get,
+ .put = snd_us16x08_comp_put,
+ .private_value = ((SND_US16X08_COMP_THRESHOLD_BIAS << 24) | /*bias*/
+ (1 << 16) | /*step*/
+ (0 << 8) | /*min*/
+ (0x20)), /*max*/
+};
+static struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_comp_get,
+ .put = snd_us16x08_comp_put,
+ .private_value = ((SND_US16X08_NO_BIAS << 24) | /*bias*/
+ (1 << 16) | /*step*/
+ (0 << 8) | /*min*/
+ (sizeof(ratio_map) - 1)), /*max*/
+};
+static struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_comp_get,
+ .put = snd_us16x08_comp_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14),
+};
+static struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_comp_get,
+ .put = snd_us16x08_comp_put,
+ .private_value =
+ SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
+};
+static struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_comp_get,
+ .put = snd_us16x08_comp_put,
+ .private_value =
+ SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
+};
+
+struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
+{
+ int i = 0;
+ struct snd_us16x08_comp_store *tmp =
+ kmalloc(sizeof(struct snd_us16x08_comp_store), GFP_KERNEL);
+
+ for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
+ tmp->valThreshold[i] = 0x20; /* 0dB */
+ tmp->valRatio[i] = 0x00; /* 1:1 */
+ tmp->valGain[i] = 0x00; /* 0dB */
+ tmp->valSwitch[i] = 0x00; /* on */
+ tmp->valAttack[i] = 0x02; /* 2ms */
+ tmp->valRelease[i] = 0x01; /* 10ms */
+ }
+ return tmp;
+}
+
+int snd_us16x08_controls_create_comp(struct usb_mixer_interface *mixer)
+{
+
+ int err;
+ char name[64];
+ struct usb_mixer_elem_info *elem;
+
+ comp_store = snd_us16x08_create_comp_store();
+
+ snprintf(name, sizeof(name), "A Comp");
+ err = add_new_ctl(mixer, &snd_us16x08_compswitch_ctl,
+ SND_US16X08_ID_COMP_SWITCH, 0x00, 0, USB_MIXER_U8, 1,
+ name, (void *) comp_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "B Thresh");
+ err = add_new_ctl(mixer, &snd_us16x08_comp_threshold_ctl,
+ SND_US16X08_ID_COMP_THRESHOLD, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) comp_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "C Ratio");
+ err = add_new_ctl(mixer, &snd_us16x08_comp_ratio_ctl,
+ SND_US16X08_ID_COMP_RATIO, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) comp_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "D Attack");
+ err = add_new_ctl(mixer, &snd_us16x08_comp_attack_ctl,
+ SND_US16X08_ID_COMP_ATTACK, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) comp_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "E Release");
+ err = add_new_ctl(mixer, &snd_us16x08_comp_release_ctl,
+ SND_US16X08_ID_COMP_RELEASE, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) comp_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "F Gain");
+ err = add_new_ctl(mixer, &snd_us16x08_comp_gain_ctl,
+ SND_US16X08_ID_COMP_GAIN, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) comp_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ return err;
+}
+
+struct snd_us16x08_comp_store* get_comp_store(void)
+{
+ return comp_store;
+}
\ No newline at end of file
diff --git a/sound/usb/mixer_us16x08_eq.c b/sound/usb/mixer_us16x08_eq.c
new file mode 100644
index 0000000..dea2dfb
--- /dev/null
+++ b/sound/usb/mixer_us16x08_eq.c
@@ -0,0 +1,407 @@
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/audio-v2.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+
+
+#include "usbaudio.h"
+#include "mixer.h"
+
+#include "mixer_us16x08.h"
+
+
+#define EQ_INFOPUTGET_NOLOG
+
+static char eqs_msq[] = {
+ CTLMSGHEAD_IN, /* default message head, equal to all mixers */
+ 0x51, /* 0x06: Controller ID */
+ 0x02,
+ 0x04, /* 0x08: EQ set num (0x01..0x04) (LOW, LOWMID, HIGHMID, HIGH)) */
+ 0x52,
+ 0x02,
+ 0x0c, /* 0x0b: value dB (0 ... 12) (-12db .. +12db) x-6 */
+ 0x53,
+ 0x02,
+ 0x0f, /* 0x0e: value freq (32-47) (1.7kHz..18kHz) */
+ 0x54,
+ 0x02,
+ 0x02, /* 0x11: band width (0-6) (Q16-Q0.25) 2^x/4 (EQ xxMID only) */
+ 0x55,
+ 0x02,
+ 0x01, /* 0x14: main EQ switch (0 ... 1) (off ... on)) */
+ 0x00,
+ 0x00
+};
+
+int snd_us16x08_eqswitch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->count = 1;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->value.integer.max = 1;
+ uinfo->value.integer.min = 0;
+ return 0;
+}
+
+static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int val = 0;
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_us16x08_eq_all_store *store =
+ ((struct snd_us16x08_eq_all_store *) elem->private_data);
+ int index = ucontrol->id.index;
+
+ val = store->low_store->valSwitch[index];
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_eq_all_store *store =
+ ((struct snd_us16x08_eq_all_store *) elem->private_data);
+ int index = ucontrol->id.index;
+
+ char buf[sizeof(eqs_msq)];
+ int val, err = 0;
+
+ val = ucontrol->value.integer.value[0];
+
+ memcpy(buf, eqs_msq, sizeof(eqs_msq));
+
+ store->low_store->valSwitch[index] = val;
+ store->midlow_store->valSwitch[index] = val;
+ store->midhigh_store->valSwitch[index] = val;
+ store->high_store->valSwitch[index] = val;
+
+ buf[5] = index + 1;
+
+ buf[20] = store->low_store->valSwitch[index];
+ buf[17] = store->low_store->valWidth[index];
+ buf[14] = store->low_store->valFreq[index];
+ buf[11] = store->low_store->valdB[index];
+ buf[8] = 0x01;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+
+ udelay(15000);
+ buf[20] = store->midlow_store->valSwitch[index];
+ buf[17] = store->midlow_store->valWidth[index];
+ buf[14] = store->midlow_store->valFreq[index];
+ buf[11] = store->midlow_store->valdB[index];
+ buf[8] = 0x02;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+
+ udelay(15000);
+ buf[20] = store->midhigh_store->valSwitch[index];
+ buf[17] = store->midhigh_store->valWidth[index];
+ buf[14] = store->midhigh_store->valFreq[index];
+ buf[11] = store->midhigh_store->valdB[index];
+ buf[8] = 0x03;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+
+ udelay(15000);
+ buf[20] = store->high_store->valSwitch[index];
+ buf[17] = store->high_store->valWidth[index];
+ buf[14] = store->high_store->valFreq[index];
+ buf[11] = store->high_store->valdB[index];
+ buf[8] = 0x04;
+ err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+
+ return 1;
+}
+
+static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int val = 0;
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_us16x08_eq_store *store =
+ ((struct snd_us16x08_eq_store *) elem->private_data);
+ int index = ucontrol->id.index;
+
+
+ switch (elem->head.id & 0xf0) {
+ case 0x00:
+ val = store->valdB[index];
+ break;
+ case 0x10:
+ val = store->valFreq[index] -
+ ((kcontrol->private_value >> 24) & 0xff);
+ break;
+ case 0x20:
+ val = store->valWidth[index];
+ break;
+ }
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kcontrol->private_data;
+ struct snd_usb_audio *chip = elem->head.mixer->chip;
+ struct snd_us16x08_eq_store *store =
+ ((struct snd_us16x08_eq_store *) elem->private_data);
+ int index = ucontrol->id.index;
+
+ char buf[sizeof(eqs_msq)];
+ int val, err = 0;
+
+ memcpy(buf, eqs_msq, sizeof(eqs_msq));
+
+ val = ucontrol->value.integer.value[0] +
+ ((kcontrol->private_value >> 24) & 0xff);
+
+ switch (elem->head.id & 0xf0) {
+ case 0x00: /* level dB */
+ store->valdB[index] = val;
+ break;
+ case 0x10:
+ store->valFreq[index] = val;
+ break;
+ case 0x20:
+ store->valWidth[index] = val;
+ break;
+ }
+
+ buf[20] = store->valSwitch[index];
+ buf[17] = store->valWidth[index];
+ buf[14] = store->valFreq[index];
+ buf[11] = store->valdB[index];
+
+ buf[5] = index + 1;
+
+ buf[8] = (elem->head.id & 0x0F);
+ err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+
+ return 1;
+}
+
+static struct snd_kcontrol_new snd_us16x08_eqlevel_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_eq_get,
+ .put = snd_us16x08_eq_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eqLowFreq_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_eq_get,
+ .put = snd_us16x08_eq_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eqMidFreq_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_eq_get,
+ .put = snd_us16x08_eq_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eqMidWidth_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_eq_get,
+ .put = snd_us16x08_eq_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eqHighFreq_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_mix_info,
+ .get = snd_us16x08_eq_get,
+ .put = snd_us16x08_eq_put,
+ .private_value =
+ SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eqswitch_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "",
+ .count = 16,
+ .info = snd_us16x08_eqswitch_info,
+ .get = snd_us16x08_eqswitch_get,
+ .put = snd_us16x08_eqswitch_put,
+ .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1),
+};
+
+struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(int index)
+{
+ int i = 0;
+ struct snd_us16x08_eq_store *tmp =
+ kmalloc(sizeof(struct snd_us16x08_eq_store), GFP_KERNEL);
+
+ for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
+ switch (index) {
+ case 0x01: /* EQ Low */
+ tmp->valdB[i] = 0x0c;
+ tmp->valFreq[i] = 0x05;
+ tmp->valWidth[i] = 0xff;
+ tmp->valSwitch[i] = 0x01; /* on */
+ break;
+ case 0x02: /* EQ Mid low */
+ tmp->valdB[i] = 0x0c;
+ tmp->valFreq[i] = 0x0e;
+ tmp->valWidth[i] = 0x02;
+ tmp->valSwitch[i] = 0x01; /* on */
+ break;
+ case 0x03: /* EQ Mid High */
+ tmp->valdB[i] = 0x0c;
+ tmp->valFreq[i] = 0x1b;
+ tmp->valWidth[i] = 0x02;
+ tmp->valSwitch[i] = 0x01; /* on */
+ break;
+ case 0x04: /* EQ Mid Low */
+ tmp->valdB[i] = 0x0c;
+ tmp->valFreq[i] = 0x2f;
+ tmp->valWidth[i] = 0xff;
+ tmp->valSwitch[i] = 0x01; /* on */
+ break;
+ }
+ }
+ return tmp;
+}
+
+void snd_us16x08_free_eq_store(struct snd_kcontrol *kctl)
+{
+ snd_usb_mixer_elem_free(kctl);
+}
+
+int snd_us16x08_controls_create_eq(struct usb_mixer_interface *mixer)
+{
+
+ int err;
+ char name[64];
+ struct usb_mixer_elem_info *elem;
+
+ struct snd_us16x08_eq_store *eq_low_store =
+ snd_us16x08_create_eq_store(0x01);
+ struct snd_us16x08_eq_store *eq_midlow_store =
+ snd_us16x08_create_eq_store(0x02);
+ struct snd_us16x08_eq_store *eq_midhigh_store =
+ snd_us16x08_create_eq_store(0x03);
+ struct snd_us16x08_eq_store *eq_high_store =
+ snd_us16x08_create_eq_store(0x04);
+ struct snd_us16x08_eq_all_store *eq_all_store =
+ kmalloc(sizeof(struct snd_us16x08_eq_all_store), GFP_KERNEL);
+
+ eq_all_store->low_store = eq_low_store;
+ eq_all_store->midlow_store = eq_midlow_store;
+ eq_all_store->midhigh_store = eq_midhigh_store;
+ eq_all_store->high_store = eq_high_store;
+
+
+ snprintf(name, sizeof(name), "5 Low");
+ err = add_new_ctl(mixer, &snd_us16x08_eqlevel_ctl,
+ SND_US16X08_ID_EQLOWLEVEL, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_low_store, snd_us16x08_free_eq_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "51 LowFreq");
+ err = add_new_ctl(mixer, &snd_us16x08_eqLowFreq_ctl,
+ SND_US16X08_ID_EQLOWFREQ, 0x00, 0,
+ USB_MIXER_U8, 1, name, (void *) eq_low_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+
+
+ snprintf(name, sizeof(name), "6 MLow");
+ err = add_new_ctl(mixer, &snd_us16x08_eqlevel_ctl,
+ SND_US16X08_ID_EQLOWMIDLEVEL, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_midlow_store, snd_us16x08_free_eq_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "61 MLowFreq");
+ err = add_new_ctl(mixer, &snd_us16x08_eqMidFreq_ctl,
+ SND_US16X08_ID_EQLOWMIDFREQ, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_midlow_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "62 MLowWidth");
+ err = add_new_ctl(mixer, &snd_us16x08_eqMidWidth_ctl,
+ SND_US16X08_ID_EQLOWMIDWIDTH, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_midlow_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "7 MHigh");
+ err = add_new_ctl(mixer, &snd_us16x08_eqlevel_ctl,
+ SND_US16X08_ID_EQHIGHMIDLEVEL, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_midhigh_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "71 MHiFreq");
+ err = add_new_ctl(mixer, &snd_us16x08_eqMidFreq_ctl,
+ SND_US16X08_ID_EQHIGHMIDFREQ, 0x00, 0,
+ USB_MIXER_U8, 1, name, (void *) eq_midhigh_store, NULL,
+ &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "72 MHiWidth");
+ err = add_new_ctl(mixer, &snd_us16x08_eqMidWidth_ctl,
+ SND_US16X08_ID_EQHIGHMIDWIDTH, 0x00, 0,
+ USB_MIXER_U8, 1, name, (void *) eq_midhigh_store, NULL,
+ &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "8 High");
+ err = add_new_ctl(mixer, &snd_us16x08_eqlevel_ctl,
+ SND_US16X08_ID_EQHIGHLEVEL, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_high_store, snd_us16x08_free_eq_store, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "81 HighFreq");
+ err = add_new_ctl(mixer, &snd_us16x08_eqHighFreq_ctl,
+ SND_US16X08_ID_EQHIGHFREQ, 0x00, 0, USB_MIXER_U8, 1, name,
+ (void *) eq_high_store, NULL, &elem);
+ if (err < 0)
+ return err;
+
+ snprintf(name, sizeof(name), "9 EQ");
+ err = add_new_ctl(mixer, &snd_us16x08_eqswitch_ctl,
+ SND_US16X08_ID_EQENABLE, 0x00, 0, USB_MIXER_BOOLEAN, 1, name,
+ (void *) eq_all_store, NULL,
+ &elem);
+ if (err < 0)
+ return err;
+
+
+ return 0;
+}
2
3
Re: [alsa-devel] [linux-sunxi] Re: [PATCH v3 05/10] arm: dts: sun8i: split Allwinner H3 .dtsi
by Icenowy Zheng 30 Jan '17
by Icenowy Zheng 30 Jan '17
30 Jan '17
2017年1月30日 09:42于 André Przywara <andre.przywara(a)arm.com>写道:
>
> On 29/01/17 02:33, Icenowy Zheng wrote:
> > From: Andre Przywara <andre.przywara(a)arm.com>
>
> (Adding DT folks to CC:)
>
> see below ...
>
> > The new Allwinner H5 SoC is pin-compatible to the H3 SoC, but with the
> > Cortex-A7 cores replaced by Cortex-A53 cores and the MMC controller
> > updated. So we should really share almost the whole .dtsi.
> > In preparation for that move the peripheral parts of the existing
> > sun8i-h3.dtsi into a new sun8i-h3-h5.dtsi.
> > The actual sun8i-h3.dtsi then includes that and defines the H3 specific
> > parts on top of it.
> > On the way get rid of skeleton.dtsi, as recommended in that very file.
> >
> > Signed-off-by: Andre Przywara <andre.przywara(a)arm.com>
> > [Icenowy: also split out mmc, as well as pio and ccu's compatible]
> > Signed-off-by: Icenowy Zheng <icenowy(a)aosc.xyz>
> > ---
> > Changes in v3:
> > - Use label-based syntax to reference nodes in H3 DTSI file.
> > Changes in v2:
> > - Rebase on current linux-next (because of the add of audio codec)
> >
> > arch/arm/boot/dts/sun8i-h3.dtsi | 571 +++----------------------------------
> > arch/arm/boot/dts/sunxi-h3-h5.dtsi | 557 ++++++++++++++++++++++++++++++++++++
> > 2 files changed, 598 insertions(+), 530 deletions(-)
> > create mode 100644 arch/arm/boot/dts/sunxi-h3-h5.dtsi
> >
> > diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
> > index 08fd0860bb6b..f3a3033789b9 100644
> > --- a/arch/arm/boot/dts/sun8i-h3.dtsi
> > +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
> > @@ -40,12 +40,7 @@
> > * OTHER DEALINGS IN THE SOFTWARE.
> > */
> >
> > -#include "skeleton.dtsi"
> > -
> > -#include <dt-bindings/clock/sun8i-h3-ccu.h>
> > -#include <dt-bindings/interrupt-controller/arm-gic.h>
> > -#include <dt-bindings/pinctrl/sun4i-a10.h>
> > -#include <dt-bindings/reset/sun8i-h3-ccu.h>
> > +#include "sunxi-h3-h5.dtsi"
> >
> > / {
> > interrupt-parent = <&gic>;
> > @@ -87,489 +82,7 @@
> > <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> > };
> >
> > - clocks {
> > - #address-cells = <1>;
> > - #size-cells = <1>;
> > - ranges;
> > -
> > - osc24M: osc24M_clk {
> > - #clock-cells = <0>;
> > - compatible = "fixed-clock";
> > - clock-frequency = <24000000>;
> > - clock-output-names = "osc24M";
> > - };
> > -
> > - osc32k: osc32k_clk {
> > - #clock-cells = <0>;
> > - compatible = "fixed-clock";
> > - clock-frequency = <32768>;
> > - clock-output-names = "osc32k";
> > - };
> > -
> > - apb0: apb0_clk {
> > - compatible = "fixed-factor-clock";
> > - #clock-cells = <0>;
> > - clock-div = <1>;
> > - clock-mult = <1>;
> > - clocks = <&osc24M>;
> > - clock-output-names = "apb0";
> > - };
> > -
> > - apb0_gates: clk@01f01428 {
> > - compatible = "allwinner,sun8i-h3-apb0-gates-clk",
> > - "allwinner,sun4i-a10-gates-clk";
> > - reg = <0x01f01428 0x4>;
> > - #clock-cells = <1>;
> > - clocks = <&apb0>;
> > - clock-indices = <0>, <1>;
> > - clock-output-names = "apb0_pio", "apb0_ir";
> > - };
> > -
> > - ir_clk: ir_clk@01f01454 {
> > - compatible = "allwinner,sun4i-a10-mod0-clk";
> > - reg = <0x01f01454 0x4>;
> > - #clock-cells = <0>;
> > - clocks = <&osc32k>, <&osc24M>;
> > - clock-output-names = "ir";
> > - };
> > - };
> > -
> > soc {
> > - compatible = "simple-bus";
> > - #address-cells = <1>;
> > - #size-cells = <1>;
> > - ranges;
> > -
> > - dma: dma-controller@01c02000 {
> > - compatible = "allwinner,sun8i-h3-dma";
> > - reg = <0x01c02000 0x1000>;
> > - interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_DMA>;
> > - resets = <&ccu RST_BUS_DMA>;
> > - #dma-cells = <1>;
> > - };
> > -
> > - mmc0: mmc@01c0f000 {
> > - compatible = "allwinner,sun7i-a20-mmc";
> > - reg = <0x01c0f000 0x1000>;
> > - clocks = <&ccu CLK_BUS_MMC0>,
> > - <&ccu CLK_MMC0>,
> > - <&ccu CLK_MMC0_OUTPUT>,
> > - <&ccu CLK_MMC0_SAMPLE>;
> > - clock-names = "ahb",
> > - "mmc",
> > - "output",
> > - "sample";
> > - resets = <&ccu RST_BUS_MMC0>;
> > - reset-names = "ahb";
> > - interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - mmc1: mmc@01c10000 {
> > - compatible = "allwinner,sun7i-a20-mmc";
> > - reg = <0x01c10000 0x1000>;
> > - clocks = <&ccu CLK_BUS_MMC1>,
> > - <&ccu CLK_MMC1>,
> > - <&ccu CLK_MMC1_OUTPUT>,
> > - <&ccu CLK_MMC1_SAMPLE>;
> > - clock-names = "ahb",
> > - "mmc",
> > - "output",
> > - "sample";
> > - resets = <&ccu RST_BUS_MMC1>;
> > - reset-names = "ahb";
> > - interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - mmc2: mmc@01c11000 {
> > - compatible = "allwinner,sun7i-a20-mmc";
> > - reg = <0x01c11000 0x1000>;
> > - clocks = <&ccu CLK_BUS_MMC2>,
> > - <&ccu CLK_MMC2>,
> > - <&ccu CLK_MMC2_OUTPUT>,
> > - <&ccu CLK_MMC2_SAMPLE>;
> > - clock-names = "ahb",
> > - "mmc",
> > - "output",
> > - "sample";
> > - resets = <&ccu RST_BUS_MMC2>;
> > - reset-names = "ahb";
> > - interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - usbphy: phy@01c19400 {
> > - compatible = "allwinner,sun8i-h3-usb-phy";
> > - reg = <0x01c19400 0x2c>,
> > - <0x01c1a800 0x4>,
> > - <0x01c1b800 0x4>,
> > - <0x01c1c800 0x4>,
> > - <0x01c1d800 0x4>;
> > - reg-names = "phy_ctrl",
> > - "pmu0",
> > - "pmu1",
> > - "pmu2",
> > - "pmu3";
> > - clocks = <&ccu CLK_USB_PHY0>,
> > - <&ccu CLK_USB_PHY1>,
> > - <&ccu CLK_USB_PHY2>,
> > - <&ccu CLK_USB_PHY3>;
> > - clock-names = "usb0_phy",
> > - "usb1_phy",
> > - "usb2_phy",
> > - "usb3_phy";
> > - resets = <&ccu RST_USB_PHY0>,
> > - <&ccu RST_USB_PHY1>,
> > - <&ccu RST_USB_PHY2>,
> > - <&ccu RST_USB_PHY3>;
> > - reset-names = "usb0_reset",
> > - "usb1_reset",
> > - "usb2_reset",
> > - "usb3_reset";
> > - status = "disabled";
> > - #phy-cells = <1>;
> > - };
> > -
> > - ehci1: usb@01c1b000 {
> > - compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
> > - reg = <0x01c1b000 0x100>;
> > - interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>;
> > - resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>;
> > - phys = <&usbphy 1>;
> > - phy-names = "usb";
> > - status = "disabled";
> > - };
> > -
> > - ohci1: usb@01c1b400 {
> > - compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
> > - reg = <0x01c1b400 0x100>;
> > - interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>,
> > - <&ccu CLK_USB_OHCI1>;
> > - resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>;
> > - phys = <&usbphy 1>;
> > - phy-names = "usb";
> > - status = "disabled";
> > - };
> > -
> > - ehci2: usb@01c1c000 {
> > - compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
> > - reg = <0x01c1c000 0x100>;
> > - interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>;
> > - resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
> > - phys = <&usbphy 2>;
> > - phy-names = "usb";
> > - status = "disabled";
> > - };
> > -
> > - ohci2: usb@01c1c400 {
> > - compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
> > - reg = <0x01c1c400 0x100>;
> > - interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>,
> > - <&ccu CLK_USB_OHCI2>;
> > - resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
> > - phys = <&usbphy 2>;
> > - phy-names = "usb";
> > - status = "disabled";
> > - };
> > -
> > - ehci3: usb@01c1d000 {
> > - compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
> > - reg = <0x01c1d000 0x100>;
> > - interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>;
> > - resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>;
> > - phys = <&usbphy 3>;
> > - phy-names = "usb";
> > - status = "disabled";
> > - };
> > -
> > - ohci3: usb@01c1d400 {
> > - compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
> > - reg = <0x01c1d400 0x100>;
> > - interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>,
> > - <&ccu CLK_USB_OHCI3>;
> > - resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>;
> > - phys = <&usbphy 3>;
> > - phy-names = "usb";
> > - status = "disabled";
> > - };
> > -
> > - ccu: clock@01c20000 {
> > - compatible = "allwinner,sun8i-h3-ccu";
> > - reg = <0x01c20000 0x400>;
> > - clocks = <&osc24M>, <&osc32k>;
> > - clock-names = "hosc", "losc";
> > - #clock-cells = <1>;
> > - #reset-cells = <1>;
> > - };
> > -
> > - pio: pinctrl@01c20800 {
> > - compatible = "allwinner,sun8i-h3-pinctrl";
> > - reg = <0x01c20800 0x400>;
> > - interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> > - <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
> > - clock-names = "apb", "hosc", "losc";
> > - gpio-controller;
> > - #gpio-cells = <3>;
> > - interrupt-controller;
> > - #interrupt-cells = <3>;
> > -
> > - i2c0_pins: i2c0 {
> > - pins = "PA11", "PA12";
> > - function = "i2c0";
> > - };
> > -
> > - i2c1_pins: i2c1 {
> > - pins = "PA18", "PA19";
> > - function = "i2c1";
> > - };
> > -
> > - i2c2_pins: i2c2 {
> > - pins = "PE12", "PE13";
> > - function = "i2c2";
> > - };
> > -
> > - mmc0_pins_a: mmc0@0 {
> > - pins = "PF0", "PF1", "PF2", "PF3",
> > - "PF4", "PF5";
> > - function = "mmc0";
> > - drive-strength = <30>;
> > - bias-pull-up;
> > - };
> > -
> > - mmc0_cd_pin: mmc0_cd_pin@0 {
> > - pins = "PF6";
> > - function = "gpio_in";
> > - bias-pull-up;
> > - };
> > -
> > - mmc1_pins_a: mmc1@0 {
> > - pins = "PG0", "PG1", "PG2", "PG3",
> > - "PG4", "PG5";
> > - function = "mmc1";
> > - drive-strength = <30>;
> > - bias-pull-up;
> > - };
> > -
> > - mmc2_8bit_pins: mmc2_8bit {
> > - pins = "PC5", "PC6", "PC8",
> > - "PC9", "PC10", "PC11",
> > - "PC12", "PC13", "PC14",
> > - "PC15", "PC16";
> > - function = "mmc2";
> > - drive-strength = <30>;
> > - bias-pull-up;
> > - };
> > -
> > - spi0_pins: spi0 {
> > - pins = "PC0", "PC1", "PC2", "PC3";
> > - function = "spi0";
> > - };
> > -
> > - spi1_pins: spi1 {
> > - pins = "PA15", "PA16", "PA14", "PA13";
> > - function = "spi1";
> > - };
> > -
> > - uart0_pins_a: uart0@0 {
> > - pins = "PA4", "PA5";
> > - function = "uart0";
> > - };
> > -
> > - uart1_pins: uart1 {
> > - pins = "PG6", "PG7";
> > - function = "uart1";
> > - };
> > -
> > - uart1_rts_cts_pins: uart1_rts_cts {
> > - pins = "PG8", "PG9";
> > - function = "uart1";
> > - };
> > -
> > - uart2_pins: uart2 {
> > - pins = "PA0", "PA1";
> > - function = "uart2";
> > - };
> > -
> > - uart3_pins: uart3 {
> > - pins = "PA13", "PA14";
> > - function = "uart3";
> > - };
> > - };
> > -
> > - timer@01c20c00 {
> > - compatible = "allwinner,sun4i-a10-timer";
> > - reg = <0x01c20c00 0xa0>;
> > - interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> > - <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&osc24M>;
> > - };
> > -
> > - spi0: spi@01c68000 {
> > - compatible = "allwinner,sun8i-h3-spi";
> > - reg = <0x01c68000 0x1000>;
> > - interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
> > - clock-names = "ahb", "mod";
> > - dmas = <&dma 23>, <&dma 23>;
> > - dma-names = "rx", "tx";
> > - pinctrl-names = "default";
> > - pinctrl-0 = <&spi0_pins>;
> > - resets = <&ccu RST_BUS_SPI0>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - spi1: spi@01c69000 {
> > - compatible = "allwinner,sun8i-h3-spi";
> > - reg = <0x01c69000 0x1000>;
> > - interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
> > - clock-names = "ahb", "mod";
> > - dmas = <&dma 24>, <&dma 24>;
> > - dma-names = "rx", "tx";
> > - pinctrl-names = "default";
> > - pinctrl-0 = <&spi1_pins>;
> > - resets = <&ccu RST_BUS_SPI1>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - wdt0: watchdog@01c20ca0 {
> > - compatible = "allwinner,sun6i-a31-wdt";
> > - reg = <0x01c20ca0 0x20>;
> > - interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
> > - };
> > -
> > - pwm: pwm@01c21400 {
> > - compatible = "allwinner,sun8i-h3-pwm";
> > - reg = <0x01c21400 0x8>;
> > - clocks = <&osc24M>;
> > - #pwm-cells = <3>;
> > - status = "disabled";
> > - };
> > -
> > - codec: codec@01c22c00 {
> > - #sound-dai-cells = <0>;
> > - compatible = "allwinner,sun8i-h3-codec";
> > - reg = <0x01c22c00 0x400>;
> > - interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
> > - clock-names = "apb", "codec";
> > - resets = <&ccu RST_BUS_CODEC>;
> > - dmas = <&dma 15>, <&dma 15>;
> > - dma-names = "rx", "tx";
> > - allwinner,codec-analog-controls = <&codec_analog>;
> > - status = "disabled";
> > - };
> > -
> > - uart0: serial@01c28000 {
> > - compatible = "snps,dw-apb-uart";
> > - reg = <0x01c28000 0x400>;
> > - interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> > - reg-shift = <2>;
> > - reg-io-width = <4>;
> > - clocks = <&ccu CLK_BUS_UART0>;
> > - resets = <&ccu RST_BUS_UART0>;
> > - dmas = <&dma 6>, <&dma 6>;
> > - dma-names = "rx", "tx";
> > - status = "disabled";
> > - };
> > -
> > - uart1: serial@01c28400 {
> > - compatible = "snps,dw-apb-uart";
> > - reg = <0x01c28400 0x400>;
> > - interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> > - reg-shift = <2>;
> > - reg-io-width = <4>;
> > - clocks = <&ccu CLK_BUS_UART1>;
> > - resets = <&ccu RST_BUS_UART1>;
> > - dmas = <&dma 7>, <&dma 7>;
> > - dma-names = "rx", "tx";
> > - status = "disabled";
> > - };
> > -
> > - uart2: serial@01c28800 {
> > - compatible = "snps,dw-apb-uart";
> > - reg = <0x01c28800 0x400>;
> > - interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
> > - reg-shift = <2>;
> > - reg-io-width = <4>;
> > - clocks = <&ccu CLK_BUS_UART2>;
> > - resets = <&ccu RST_BUS_UART2>;
> > - dmas = <&dma 8>, <&dma 8>;
> > - dma-names = "rx", "tx";
> > - status = "disabled";
> > - };
> > -
> > - uart3: serial@01c28c00 {
> > - compatible = "snps,dw-apb-uart";
> > - reg = <0x01c28c00 0x400>;
> > - interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
> > - reg-shift = <2>;
> > - reg-io-width = <4>;
> > - clocks = <&ccu CLK_BUS_UART3>;
> > - resets = <&ccu RST_BUS_UART3>;
> > - dmas = <&dma 9>, <&dma 9>;
> > - dma-names = "rx", "tx";
> > - status = "disabled";
> > - };
> > -
> > - i2c0: i2c@01c2ac00 {
> > - compatible = "allwinner,sun6i-a31-i2c";
> > - reg = <0x01c2ac00 0x400>;
> > - interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_I2C0>;
> > - resets = <&ccu RST_BUS_I2C0>;
> > - pinctrl-names = "default";
> > - pinctrl-0 = <&i2c0_pins>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - i2c1: i2c@01c2b000 {
> > - compatible = "allwinner,sun6i-a31-i2c";
> > - reg = <0x01c2b000 0x400>;
> > - interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_I2C1>;
> > - resets = <&ccu RST_BUS_I2C1>;
> > - pinctrl-names = "default";
> > - pinctrl-0 = <&i2c1_pins>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > - i2c2: i2c@01c2b400 {
> > - compatible = "allwinner,sun6i-a31-i2c";
> > - reg = <0x01c2b000 0x400>;
> > - interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&ccu CLK_BUS_I2C2>;
> > - resets = <&ccu RST_BUS_I2C2>;
> > - pinctrl-names = "default";
> > - pinctrl-0 = <&i2c2_pins>;
> > - status = "disabled";
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - };
> > -
> > gic: interrupt-controller@01c81000 {
> > compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
> > reg = <0x01c81000 0x1000>,
> > @@ -580,51 +93,49 @@
> > #interrupt-cells = <3>;
> > interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> > };
> > + };
> > +};
> >
> > - rtc: rtc@01f00000 {
> > - compatible = "allwinner,sun6i-a31-rtc";
> > - reg = <0x01f00000 0x54>;
> > - interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
> > - <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
> > - };
> > -
> > - apb0_reset: reset@01f014b0 {
> > - reg = <0x01f014b0 0x4>;
> > - compatible = "allwinner,sun6i-a31-clock-reset";
> > - #reset-cells = <1>;
> > - };
> > +&ccu {
> > + compatible = "allwinner,sun8i-h3-ccu";
> > +};
>
> I believe this kind of sharing nodes is a bit frowned upon in connection
> with sharing .dtsi's. If the compatible name differs, I think it
> deserves to be a separate node spelt out in each SoC's .dtsi.
> This also makes the DT more readable, since a reader doesn't have to
> refer to two files to see what's in that node.
For such a device tree, see sun8i-a23-a33.c .
>
> >
> > - codec_analog: codec-analog@01f015c0 {
> > - compatible = "allwinner,sun8i-h3-codec-analog";
> > - reg = <0x01f015c0 0x4>;
> > - };
> > +&mmc0 {
> > + compatible = "allwinner,sun7i-a20-mmc";
> > + clocks = <&ccu CLK_BUS_MMC0>,
> > + <&ccu CLK_MMC0>,
> > + <&ccu CLK_MMC0_OUTPUT>,
> > + <&ccu CLK_MMC0_SAMPLE>;
> > + clock-names = "ahb",
> > + "mmc",
> > + "output",
> > + "sample";
>
> This applies even more here, since the MMC controllers also have
> different clock requirements.
>
> So why can't we just leave the CCU, MMC and possibly the pinctrl nodes
> completely out of the shared h3-h5.dtsi and introduce them from scratch
> in the SoC specific .dtsi?
>
> I think we still have enough identical nodes to justify this kind of
> .dtsi sharing.
>
> Cheers,
> Andre.
>
> > +};
> >
> > - ir: ir@01f02000 {
> > - compatible = "allwinner,sun5i-a13-ir";
> > - clocks = <&apb0_gates 1>, <&ir_clk>;
> > - clock-names = "apb", "ir";
> > - resets = <&apb0_reset 1>;
> > - interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
> > - reg = <0x01f02000 0x40>;
> > - status = "disabled";
> > - };
> > +&mmc1 {
> > + compatible = "allwinner,sun7i-a20-mmc";
> > + clocks = <&ccu CLK_BUS_MMC1>,
> > + <&ccu CLK_MMC1>,
> > + <&ccu CLK_MMC1_OUTPUT>,
> > + <&ccu CLK_MMC1_SAMPLE>;
> > + clock-names = "ahb",
> > + "mmc",
> > + "output",
> > + "sample";
> > +};
> >
> > - r_pio: pinctrl@01f02c00 {
> > - compatible = "allwinner,sun8i-h3-r-pinctrl";
> > - reg = <0x01f02c00 0x400>;
> > - interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> > - clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
> > - clock-names = "apb", "hosc", "losc";
> > - resets = <&apb0_reset 0>;
> > - gpio-controller;
> > - #gpio-cells = <3>;
> > - interrupt-controller;
> > - #interrupt-cells = <3>;
> > +&mmc2 {
> > + compatible = "allwinner,sun7i-a20-mmc";
> > + clocks = <&ccu CLK_BUS_MMC2>,
> > + <&ccu CLK_MMC2>,
> > + <&ccu CLK_MMC2_OUTPUT>,
> > + <&ccu CLK_MMC2_SAMPLE>;
> > + clock-names = "ahb",
> > + "mmc",
> > + "output",
> > + "sample";
> > +};
> >
> > - ir_pins_a: ir@0 {
> > - pins = "PL11";
> > - function = "s_cir_rx";
> > - };
> > - };
> > - };
> > +&pio {
> > + compatible = "allwinner,sun8i-h3-pinctrl";
> > };
> > diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
> > new file mode 100644
> > index 000000000000..4a57c65e8869
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
> > @@ -0,0 +1,557 @@
> > +/*
> > + * Copyright (C) 2015 Jens Kuske <jenskuske(a)gmail.com>
> > + *
> > + * This file is dual-licensed: you can use it either under the terms
> > + * of the GPL or the X11 license, at your option. Note that this dual
> > + * licensing only applies to this file, and not this project as a
> > + * whole.
> > + *
> > + * a) This file is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of the
> > + * License, or (at your option) any later version.
> > + *
> > + * This file is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * Or, alternatively,
> > + *
> > + * b) Permission is hereby granted, free of charge, to any person
> > + * obtaining a copy of this software and associated documentation
> > + * files (the "Software"), to deal in the Software without
> > + * restriction, including without limitation the rights to use,
> > + * copy, modify, merge, publish, distribute, sublicense, and/or
> > + * sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following
> > + * conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be
> > + * included in all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> > + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> > + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> > + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> > + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > + * OTHER DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +#include <dt-bindings/clock/sunxi-h3-h5-ccu.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/pinctrl/sun4i-a10.h>
> > +#include <dt-bindings/reset/sunxi-h3-h5-ccu.h>
> > +
> > +/ {
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > +
> > + clocks {
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + ranges;
> > +
> > + osc24M: osc24M_clk {
> > + #clock-cells = <0>;
> > + compatible = "fixed-clock";
> > + clock-frequency = <24000000>;
> > + clock-output-names = "osc24M";
> > + };
> > +
> > + osc32k: osc32k_clk {
> > + #clock-cells = <0>;
> > + compatible = "fixed-clock";
> > + clock-frequency = <32768>;
> > + clock-output-names = "osc32k";
> > + };
> > +
> > + apb0: apb0_clk {
> > + compatible = "fixed-factor-clock";
> > + #clock-cells = <0>;
> > + clock-div = <1>;
> > + clock-mult = <1>;
> > + clocks = <&osc24M>;
> > + clock-output-names = "apb0";
> > + };
> > +
> > + apb0_gates: clk@01f01428 {
> > + compatible = "allwinner,sun8i-h3-apb0-gates-clk",
> > + "allwinner,sun4i-a10-gates-clk";
> > + reg = <0x01f01428 0x4>;
> > + #clock-cells = <1>;
> > + clocks = <&apb0>;
> > + clock-indices = <0>, <1>;
> > + clock-output-names = "apb0_pio", "apb0_ir";
> > + };
> > +
> > + ir_clk: ir_clk@01f01454 {
> > + compatible = "allwinner,sun4i-a10-mod0-clk";
> > + reg = <0x01f01454 0x4>;
> > + #clock-cells = <0>;
> > + clocks = <&osc32k>, <&osc24M>;
> > + clock-output-names = "ir";
> > + };
> > + };
> > +
> > + soc {
> > + compatible = "simple-bus";
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + ranges;
> > +
> > + dma: dma-controller@01c02000 {
> > + compatible = "allwinner,sun8i-h3-dma";
> > + reg = <0x01c02000 0x1000>;
> > + interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_DMA>;
> > + resets = <&ccu RST_BUS_DMA>;
> > + #dma-cells = <1>;
> > + };
> > +
> > + mmc0: mmc@01c0f000 {
> > + /* compatible and clocks are in per SoC .dtsi file */
> > + reg = <0x01c0f000 0x1000>;
> > + resets = <&ccu RST_BUS_MMC0>;
> > + reset-names = "ahb";
> > + interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + mmc1: mmc@01c10000 {
> > + /* compatible and clocks are in per SoC .dtsi file */
> > + reg = <0x01c10000 0x1000>;
> > + resets = <&ccu RST_BUS_MMC1>;
> > + reset-names = "ahb";
> > + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + mmc2: mmc@01c11000 {
> > + /* compatible and clocks are in per SoC .dtsi file */
> > + reg = <0x01c11000 0x1000>;
> > + resets = <&ccu RST_BUS_MMC2>;
> > + reset-names = "ahb";
> > + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + usbphy: phy@01c19400 {
> > + compatible = "allwinner,sun8i-h3-usb-phy";
> > + reg = <0x01c19400 0x2c>,
> > + <0x01c1a800 0x4>,
> > + <0x01c1b800 0x4>,
> > + <0x01c1c800 0x4>,
> > + <0x01c1d800 0x4>;
> > + reg-names = "phy_ctrl",
> > + "pmu0",
> > + "pmu1",
> > + "pmu2",
> > + "pmu3";
> > + clocks = <&ccu CLK_USB_PHY0>,
> > + <&ccu CLK_USB_PHY1>,
> > + <&ccu CLK_USB_PHY2>,
> > + <&ccu CLK_USB_PHY3>;
> > + clock-names = "usb0_phy",
> > + "usb1_phy",
> > + "usb2_phy",
> > + "usb3_phy";
> > + resets = <&ccu RST_USB_PHY0>,
> > + <&ccu RST_USB_PHY1>,
> > + <&ccu RST_USB_PHY2>,
> > + <&ccu RST_USB_PHY3>;
> > + reset-names = "usb0_reset",
> > + "usb1_reset",
> > + "usb2_reset",
> > + "usb3_reset";
> > + status = "disabled";
> > + #phy-cells = <1>;
> > + };
> > +
> > + ehci1: usb@01c1b000 {
> > + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
> > + reg = <0x01c1b000 0x100>;
> > + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>;
> > + resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>;
> > + phys = <&usbphy 1>;
> > + phy-names = "usb";
> > + status = "disabled";
> > + };
> > +
> > + ohci1: usb@01c1b400 {
> > + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
> > + reg = <0x01c1b400 0x100>;
> > + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>,
> > + <&ccu CLK_USB_OHCI1>;
> > + resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>;
> > + phys = <&usbphy 1>;
> > + phy-names = "usb";
> > + status = "disabled";
> > + };
> > +
> > + ehci2: usb@01c1c000 {
> > + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
> > + reg = <0x01c1c000 0x100>;
> > + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>;
> > + resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
> > + phys = <&usbphy 2>;
> > + phy-names = "usb";
> > + status = "disabled";
> > + };
> > +
> > + ohci2: usb@01c1c400 {
> > + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
> > + reg = <0x01c1c400 0x100>;
> > + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>,
> > + <&ccu CLK_USB_OHCI2>;
> > + resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
> > + phys = <&usbphy 2>;
> > + phy-names = "usb";
> > + status = "disabled";
> > + };
> > +
> > + ehci3: usb@01c1d000 {
> > + compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
> > + reg = <0x01c1d000 0x100>;
> > + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>;
> > + resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>;
> > + phys = <&usbphy 3>;
> > + phy-names = "usb";
> > + status = "disabled";
> > + };
> > +
> > + ohci3: usb@01c1d400 {
> > + compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
> > + reg = <0x01c1d400 0x100>;
> > + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>,
> > + <&ccu CLK_USB_OHCI3>;
> > + resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>;
> > + phys = <&usbphy 3>;
> > + phy-names = "usb";
> > + status = "disabled";
> > + };
> > +
> > + ccu: clock@01c20000 {
> > + /* compatible is in per SoC .dtsi file */
> > + reg = <0x01c20000 0x400>;
> > + clocks = <&osc24M>, <&osc32k>;
> > + clock-names = "hosc", "losc";
> > + #clock-cells = <1>;
> > + #reset-cells = <1>;
> > + };
> > +
> > + pio: pinctrl@01c20800 {
> > + /* compatible is in per SoC .dtsi file */
> > + reg = <0x01c20800 0x400>;
> > + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
> > + clock-names = "apb", "hosc", "losc";
> > + gpio-controller;
> > + #gpio-cells = <3>;
> > + interrupt-controller;
> > + #interrupt-cells = <3>;
> > +
> > + i2c0_pins: i2c0 {
> > + pins = "PA11", "PA12";
> > + function = "i2c0";
> > + };
> > +
> > + i2c1_pins: i2c1 {
> > + pins = "PA18", "PA19";
> > + function = "i2c1";
> > + };
> > +
> > + i2c2_pins: i2c2 {
> > + pins = "PE12", "PE13";
> > + function = "i2c2";
> > + };
> > +
> > + mmc0_pins_a: mmc0@0 {
> > + pins = "PF0", "PF1", "PF2", "PF3",
> > + "PF4", "PF5";
> > + function = "mmc0";
> > + drive-strength = <30>;
> > + bias-pull-up;
> > + };
> > +
> > + mmc0_cd_pin: mmc0_cd_pin@0 {
> > + pins = "PF6";
> > + function = "gpio_in";
> > + bias-pull-up;
> > + };
> > +
> > + mmc1_pins_a: mmc1@0 {
> > + pins = "PG0", "PG1", "PG2", "PG3",
> > + "PG4", "PG5";
> > + function = "mmc1";
> > + drive-strength = <30>;
> > + bias-pull-up;
> > + };
> > +
> > + mmc2_8bit_pins: mmc2_8bit {
> > + pins = "PC5", "PC6", "PC8",
> > + "PC9", "PC10", "PC11",
> > + "PC12", "PC13", "PC14",
> > + "PC15", "PC16";
> > + function = "mmc2";
> > + drive-strength = <30>;
> > + bias-pull-up;
> > + };
> > +
> > + spi0_pins: spi0 {
> > + pins = "PC0", "PC1", "PC2", "PC3";
> > + function = "spi0";
> > + };
> > +
> > + spi1_pins: spi1 {
> > + pins = "PA15", "PA16", "PA14", "PA13";
> > + function = "spi1";
> > + };
> > +
> > + uart0_pins_a: uart0@0 {
> > + pins = "PA4", "PA5";
> > + function = "uart0";
> > + };
> > +
> > + uart1_pins: uart1 {
> > + pins = "PG6", "PG7";
> > + function = "uart1";
> > + };
> > +
> > + uart1_rts_cts_pins: uart1_rts_cts {
> > + pins = "PG8", "PG9";
> > + function = "uart1";
> > + };
> > +
> > + uart2_pins: uart2 {
> > + pins = "PA0", "PA1";
> > + function = "uart2";
> > + };
> > +
> > + uart3_pins: uart3 {
> > + pins = "PA13", "PA14";
> > + function = "uart3";
> > + };
> > + };
> > +
> > + timer@01c20c00 {
> > + compatible = "allwinner,sun4i-a10-timer";
> > + reg = <0x01c20c00 0xa0>;
> > + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&osc24M>;
> > + };
> > +
> > + spi0: spi@01c68000 {
> > + compatible = "allwinner,sun8i-h3-spi";
> > + reg = <0x01c68000 0x1000>;
> > + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
> > + clock-names = "ahb", "mod";
> > + dmas = <&dma 23>, <&dma 23>;
> > + dma-names = "rx", "tx";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&spi0_pins>;
> > + resets = <&ccu RST_BUS_SPI0>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + spi1: spi@01c69000 {
> > + compatible = "allwinner,sun8i-h3-spi";
> > + reg = <0x01c69000 0x1000>;
> > + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
> > + clock-names = "ahb", "mod";
> > + dmas = <&dma 24>, <&dma 24>;
> > + dma-names = "rx", "tx";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&spi1_pins>;
> > + resets = <&ccu RST_BUS_SPI1>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + wdt0: watchdog@01c20ca0 {
> > + compatible = "allwinner,sun6i-a31-wdt";
> > + reg = <0x01c20ca0 0x20>;
> > + interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
> > + };
> > +
> > + pwm: pwm@01c21400 {
> > + compatible = "allwinner,sun8i-h3-pwm";
> > + reg = <0x01c21400 0x8>;
> > + clocks = <&osc24M>;
> > + #pwm-cells = <3>;
> > + status = "disabled";
> > + };
> > +
> > + codec: codec@01c22c00 {
> > + #sound-dai-cells = <0>;
> > + compatible = "allwinner,sun8i-h3-codec";
> > + reg = <0x01c22c00 0x400>;
> > + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
> > + clock-names = "apb", "codec";
> > + resets = <&ccu RST_BUS_CODEC>;
> > + dmas = <&dma 15>, <&dma 15>;
> > + dma-names = "rx", "tx";
> > + allwinner,codec-analog-controls = <&codec_analog>;
> > + status = "disabled";
> > + };
> > +
> > + uart0: serial@01c28000 {
> > + compatible = "snps,dw-apb-uart";
> > + reg = <0x01c28000 0x400>;
> > + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> > + reg-shift = <2>;
> > + reg-io-width = <4>;
> > + clocks = <&ccu CLK_BUS_UART0>;
> > + resets = <&ccu RST_BUS_UART0>;
> > + dmas = <&dma 6>, <&dma 6>;
> > + dma-names = "rx", "tx";
> > + status = "disabled";
> > + };
> > +
> > + uart1: serial@01c28400 {
> > + compatible = "snps,dw-apb-uart";
> > + reg = <0x01c28400 0x400>;
> > + interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> > + reg-shift = <2>;
> > + reg-io-width = <4>;
> > + clocks = <&ccu CLK_BUS_UART1>;
> > + resets = <&ccu RST_BUS_UART1>;
> > + dmas = <&dma 7>, <&dma 7>;
> > + dma-names = "rx", "tx";
> > + status = "disabled";
> > + };
> > +
> > + uart2: serial@01c28800 {
> > + compatible = "snps,dw-apb-uart";
> > + reg = <0x01c28800 0x400>;
> > + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
> > + reg-shift = <2>;
> > + reg-io-width = <4>;
> > + clocks = <&ccu CLK_BUS_UART2>;
> > + resets = <&ccu RST_BUS_UART2>;
> > + dmas = <&dma 8>, <&dma 8>;
> > + dma-names = "rx", "tx";
> > + status = "disabled";
> > + };
> > +
> > + uart3: serial@01c28c00 {
> > + compatible = "snps,dw-apb-uart";
> > + reg = <0x01c28c00 0x400>;
> > + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
> > + reg-shift = <2>;
> > + reg-io-width = <4>;
> > + clocks = <&ccu CLK_BUS_UART3>;
> > + resets = <&ccu RST_BUS_UART3>;
> > + dmas = <&dma 9>, <&dma 9>;
> > + dma-names = "rx", "tx";
> > + status = "disabled";
> > + };
> > +
> > + i2c0: i2c@01c2ac00 {
> > + compatible = "allwinner,sun6i-a31-i2c";
> > + reg = <0x01c2ac00 0x400>;
> > + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_I2C0>;
> > + resets = <&ccu RST_BUS_I2C0>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c0_pins>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + i2c1: i2c@01c2b000 {
> > + compatible = "allwinner,sun6i-a31-i2c";
> > + reg = <0x01c2b000 0x400>;
> > + interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_I2C1>;
> > + resets = <&ccu RST_BUS_I2C1>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c1_pins>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + i2c2: i2c@01c2b400 {
> > + compatible = "allwinner,sun6i-a31-i2c";
> > + reg = <0x01c2b000 0x400>;
> > + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_I2C2>;
> > + resets = <&ccu RST_BUS_I2C2>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c2_pins>;
> > + status = "disabled";
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + };
> > +
> > + rtc: rtc@01f00000 {
> > + compatible = "allwinner,sun6i-a31-rtc";
> > + reg = <0x01f00000 0x54>;
> > + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
> > + };
> > +
> > + apb0_reset: reset@01f014b0 {
> > + reg = <0x01f014b0 0x4>;
> > + compatible = "allwinner,sun6i-a31-clock-reset";
> > + #reset-cells = <1>;
> > + };
> > +
> > + codec_analog: codec-analog@01f015c0 {
> > + compatible = "allwinner,sun8i-h3-codec-analog";
> > + reg = <0x01f015c0 0x4>;
> > + };
> > +
> > + ir: ir@01f02000 {
> > + compatible = "allwinner,sun5i-a13-ir";
> > + clocks = <&apb0_gates 1>, <&ir_clk>;
> > + clock-names = "apb", "ir";
> > + resets = <&apb0_reset 1>;
> > + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
> > + reg = <0x01f02000 0x40>;
> > + status = "disabled";
> > + };
> > +
> > + r_pio: pinctrl@01f02c00 {
> > + compatible = "allwinner,sun8i-h3-r-pinctrl";
> > + reg = <0x01f02c00 0x400>;
> > + interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
> > + clock-names = "apb", "hosc", "losc";
> > + resets = <&apb0_reset 0>;
> > + gpio-controller;
> > + #gpio-cells = <3>;
> > + interrupt-controller;
> > + #interrupt-cells = <3>;
> > +
> > + ir_pins_a: ir@0 {
> > + pins = "PL11";
> > + function = "s_cir_rx";
> > + };
> > + };
> > + };
> > +};
> >
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe(a)googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
1
0
[alsa-devel] [PATCH 00/19][RFC v2] ALSA: firewire-motu: new driver for MOTU FireWire series
by Takashi Sakamoto 30 Jan '17
by Takashi Sakamoto 30 Jan '17
30 Jan '17
Hi,
This patchset updates a part of my previous RFC, just for MOTU FireWire series.
[RFC][PATCH 00/37] ALSA: firewire: support AMDTP variants
http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/094789.html
This patchset adds support for a part of MOTU FireWire series with their
functionality of packet streaming. Below models are newly supported:
- 828
- 828mk2
- 828mk3 (FireWire/Hybrid)
However, this module cannot handle 828 correctly to generate sound. The reason
is not clear yet. On the other hand, 828mk2 and 828mk3 can be handled most
properly via ALSA PCM/MIDI/HwDep interfaces.
Currently, I have a plan to post this patchset to merge into Linux 4.12.
Corresponding merge window will be estimated to open this April. If you're
willing to test this module, please report the result till then.
For testers, I prepared for backport modules in my repository. Please follow
instructions in README.
https://github.com/takaswie/snd-firewire-improve/tree/topic/motu
As user land tools, I added some stuffs to libhinawa and hinawa-utils. Please
refer to 'topic/motu' branch of these repositories. You can use
'hinawa-motu-common-cui' to configure some streaming-related features of the
above units:
* https://github.com/takaswie/libhinawa/tree/topic/motu
* https://github.com/takaswie/hinawa-utils/tree/topic/motu
Takashi Sakamoto (19):
firewire-motu: add skeleton for Mark of the unicorn (MOTU) FireWire
series
firewire-motu: postpone sound card registration
firewire-motu: add a structure for model-dependent parameters.
firewire-motu: add an abstraction layer for three types of protocols
firewire-lib: record cycle count for the first packet
firewire-lib: add support for source packet header field in CIP header
firewire-lib: enable CIP_DBC_IS_END_EVENT for both directions of
stream
firewire-motu: add MOTU specific protocol layer
firewire-motu: handle transactions specific for MOTU FireWire models
firewire-motu: add stream management functionality
firewire-motu: add proc node to show current statuc of clock and
packet formats
firewire-motu: add PCM functionality
firewire-motu: add MIDI functionality
firewire-motu: add hwdep interface
firewire-motu: enable to read transaction cache via hwdep interface
firewire-motu: add support for MOTU 828 as a model with protocol
version 1
firewire-motu: add support for MOTU 828mk2 as a model with protocol
version 2
firewire-lib: add a quirk of packet without valid EOH in CIP format
firewire-motu: add support for MOTU 828mk3 (FireWire/Hybrid) as a
model with protocol version 3
include/uapi/sound/asound.h | 3 +-
include/uapi/sound/firewire.h | 10 +-
sound/firewire/Kconfig | 13 ++
sound/firewire/Makefile | 1 +
sound/firewire/amdtp-stream.c | 36 ++-
sound/firewire/amdtp-stream.h | 9 +-
sound/firewire/motu/Makefile | 5 +
sound/firewire/motu/amdtp-motu.c | 388 ++++++++++++++++++++++++++++++++
sound/firewire/motu/motu-hwdep.c | 198 ++++++++++++++++
sound/firewire/motu/motu-midi.c | 169 ++++++++++++++
sound/firewire/motu/motu-pcm.c | 398 +++++++++++++++++++++++++++++++++
sound/firewire/motu/motu-proc.c | 118 ++++++++++
sound/firewire/motu/motu-protocol-v1.c | 204 +++++++++++++++++
sound/firewire/motu/motu-protocol-v2.c | 237 ++++++++++++++++++++
sound/firewire/motu/motu-protocol-v3.c | 312 ++++++++++++++++++++++++++
sound/firewire/motu/motu-stream.c | 381 +++++++++++++++++++++++++++++++
sound/firewire/motu/motu-transaction.c | 137 ++++++++++++
sound/firewire/motu/motu.c | 273 ++++++++++++++++++++++
sound/firewire/motu/motu.h | 161 +++++++++++++
19 files changed, 3042 insertions(+), 11 deletions(-)
create mode 100644 sound/firewire/motu/Makefile
create mode 100644 sound/firewire/motu/amdtp-motu.c
create mode 100644 sound/firewire/motu/motu-hwdep.c
create mode 100644 sound/firewire/motu/motu-midi.c
create mode 100644 sound/firewire/motu/motu-pcm.c
create mode 100644 sound/firewire/motu/motu-proc.c
create mode 100644 sound/firewire/motu/motu-protocol-v1.c
create mode 100644 sound/firewire/motu/motu-protocol-v2.c
create mode 100644 sound/firewire/motu/motu-protocol-v3.c
create mode 100644 sound/firewire/motu/motu-stream.c
create mode 100644 sound/firewire/motu/motu-transaction.c
create mode 100644 sound/firewire/motu/motu.c
create mode 100644 sound/firewire/motu/motu.h
--
2.9.3
2
27
Re: [alsa-devel] [linux-sunxi] Re: [PATCH v2 4/9] arm: dts: sun8i: split Allwinner H3 .dtsi
by Icenowy Zheng 27 Jan '17
by Icenowy Zheng 27 Jan '17
27 Jan '17
2017年1月27日 23:55于 Maxime Ripard <maxime.ripard(a)free-electrons.com>写道:
>
> On Thu, Jan 26, 2017 at 11:48:54PM +0800, Icenowy Zheng wrote:
> > - mmc0: mmc@01c0f000 {
> > + mmc@01c0f000 {
>
> There's no point in removing the labels, and you can even use the
> label-based syntax to reference them, instead of using the path.
I think keeping a tree structure in sub dtsi file will make it more
pretty and easy to use :-)
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe(a)googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
2
1
Re: [alsa-devel] [linux-sunxi] Re: [PATCH v2 6/9] arm64: dts: allwinner: add Allwinner H5 .dtsi
by Icenowy Zheng 27 Jan '17
by Icenowy Zheng 27 Jan '17
27 Jan '17
2017年1月27日 23:58于 Maxime Ripard <maxime.ripard(a)free-electrons.com>写道:
>
> On Thu, Jan 26, 2017 at 11:48:56PM +0800, Icenowy Zheng wrote:
> > + mmc@01c0f000 {
>
> Please use a label based syntax here too.
>
> > + compatible = "allwinner,sun50i-a64-mmc",
> > + "allwinner,sun5i-a13-mmc";
>
> The compatibility with the A13 has never been true, and the compatible
> should be "allwinner,sun50i-h5-mmc", "allwinner,sun50i-a64-mmc".
>
> > + clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
> > + clock-names = "ahb", "mmc";
> > + };
> > +
> > + mmc@01c10000 {
> > + compatible = "allwinner,sun50i-a64-mmc",
> > + "allwinner,sun5i-a13-mmc";
> > + clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
> > + clock-names = "ahb", "mmc";
> > + };
> > +
> > + mmc@01c11000 {
> > + compatible = "allwinner,sun50i-a64-mmc",
>
> And this is very likely to use the emmc compatible.
>
> > + "allwinner,sun5i-a13-mmc";
> > + clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
> > + clock-names = "ahb", "mmc";
> > + };
> > +
> > + clock@01c20000 {
> > + compatible = "allwinner,sun50i-h5-ccu",
> > + "allwinner,sun8i-h3-ccu";
> > + };
>
> If it doesn't have the same clocks, it's not compatible with the H3.
I'll drop it.
It's from the original patch from Andre.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe(a)googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
1
0
27 Jan '17
The following patches enable DisplayPort Audio on Cherrytrail machines
when applied on top of Takashi's topic/intel-lpe-audio branch (tested
on Zotac PI330)
There are a couple of opens where I could use some help:
- is it necessary to set a valid_bit which is used only for DP audio?
- is the sequence to set the chicken bits and unmute the amplifier ok or
can it be improved by being moved somewhere else in the i915 driver?
- the register offset to be used by the audio driver depends on a
combination of port/pipe/output type. Do we need to get access to the
pipe information and when is it available (initial trials showed the
pipe is still invalid when the audio notification happens)
Feedback welcome!
Pierre-Louis Bossart (5):
drm: i915: add DP support in LPE audio mode
ALSA: x86: intel_hdmi: add definitions and logic for DP audio
ALSA: x86: intel_hdmi: set config bitfields for DP mode
drm: i915: add DisplayPort amp unmute for LPE audio mode
ALSA: x86: hdmi: hack to enable DP audio on CHT
drivers/gpu/drm/i915/i915_drv.h | 3 +-
drivers/gpu/drm/i915/i915_reg.h | 12 +++
drivers/gpu/drm/i915/intel_audio.c | 19 +++-
drivers/gpu/drm/i915/intel_lpe_audio.c | 34 ++++++-
include/drm/intel_lpe_audio.h | 2 +
sound/x86/intel_hdmi_audio.c | 174 ++++++++++++++++++++++++++++-----
sound/x86/intel_hdmi_audio.h | 8 +-
sound/x86/intel_hdmi_lpe_audio.c | 44 ++++++++-
sound/x86/intel_hdmi_lpe_audio.h | 29 ++++++
9 files changed, 288 insertions(+), 37 deletions(-)
--
2.7.4
4
16
Hi,
this is a patch series to pass the pipe over LPE audio notification,
based on Pierre's latest patchset ("[RFC PATCH 0/5] DisplayPort Audio
on Cherrytrail").
Takashi
===
Takashi Iwai (3):
drm/i915: Avoid MST pipe handling for LPE audio
drm/i915: Pass pipe to LPE audio notification
ALSA: x86: Use config base depending on the pipe
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/intel_audio.c | 27 ++++++++++++++-------------
drivers/gpu/drm/i915/intel_lpe_audio.c | 3 ++-
include/drm/intel_lpe_audio.h | 1 +
sound/x86/intel_hdmi_lpe_audio.c | 32 +++++++++++++++++++++-----------
5 files changed, 39 insertions(+), 26 deletions(-)
--
2.11.0
2
5
[alsa-devel] [PATCH v7 0/5] Add platform clock for BayTrail platforms
by Pierre-Louis Bossart 27 Jan '17
by Pierre-Louis Bossart 27 Jan '17
27 Jan '17
These patches specifically enable the audio MCLK required by Baytrail
CR devices. It is the remaining part of a bigger set of patches
(already merged in Mark Brown's tree) that enable sound for Baytrail CR
devices (especially Asus T100TAF) [1]. They include the clock driver
and clock enabling in the pmc_atom code (along with moving of the
non-architectural pmc_atom driver code into drivers/platform/x86 as
suggested by Thomas Gleixner [2]). This move includes a new header in
include/linux/platform_data/x86/. While there is an agreement that the
definitions for PMC clocks are not really platform data this location
is seen as a good-enough compromise with an agreement between Darren
Hart and Andy Shevchenko [3]
[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-August/111704.html
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-October/113936.ht…
[3] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-December/115892.h…
Changes from v6:
- Addressed comments from Stephen Boyd, Andy Shevchenko and Vinod Koul
- Renamed clk-byt-plt to clk-pmc-atom
- Rebase to 4.10-rc3 (broonie/for-next)
- Added helper functions to make error handling more compact
- Removed module-related code since it's not possible/supported
- Removed useless tests on remove
- PMC_CLK_OFFSET move to clk-pcm-atom (more logical)
- Split typo correction and makefile fix in separate patches
- small fixes (spaces, defaults in switches, alphabetical order, use of
clk_writel/readl and no test on write, simpler error handling, use of
while(i--), unsigned loop variables, kernel doc fields, format-patch -M
-C -D, use of PLATFORM_DEVID_NONE)
Changes from v5:
- fix build error reported by kbuild test robot
- split the clk driver code from x86 platform changes
Changes from v4:
- move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86
Changes from v3:
- replace devm_kzalloc with devm_kcalloc
- add x86 architecture maintainers
Changes from v2:
- move clk platform data structures to a separate include file
- store clk_hw pointer for the fixed rate clocks
Changes from v1:
- register the clk device as child of pmc device
- pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
- use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create
Irina Tirdea (3):
clk: x86: Add Atom PMC platform clocks
arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86
platform/x86: Enable Atom PMC platform clocks
Pierre-Louis Bossart (2):
clk: Make x86/ conditional on CONFIG_COMMON_CLK
platform/x86: fix typo in comment
arch/x86/Kconfig | 4 -
arch/x86/platform/atom/Makefile | 1 -
drivers/acpi/acpi_lpss.c | 2 +-
drivers/clk/Makefile | 2 +
drivers/clk/x86/Makefile | 1 +
drivers/clk/x86/clk-pmc-atom.c | 373 +++++++++++++++++++++
drivers/platform/x86/Kconfig | 5 +
drivers/platform/x86/Makefile | 1 +
.../atom => drivers/platform/x86}/pmc_atom.c | 88 ++++-
include/linux/platform_data/x86/clk-pmc-atom.h | 44 +++
.../linux/platform_data/x86}/pmc_atom.h | 2 +-
11 files changed, 508 insertions(+), 15 deletions(-)
create mode 100644 drivers/clk/x86/clk-pmc-atom.c
rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (87%)
create mode 100644 include/linux/platform_data/x86/clk-pmc-atom.h
rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h (98%)
--
2.7.4
5
13
[alsa-devel] [PATCH] sound: pci: cs46xx: constify snd_pcm_ops structures
by Bhumika Goyal 26 Jan '17
by Bhumika Goyal 26 Jan '17
26 Jan '17
Declare snd_pcm_ops structures as const as they are either stored in the
ops field of a snd_pcm_substream structure or passed as an argument to the
function snd_pcm_set_ops. The function argument and the ops field
are of type const, so snd_pcm_ops structures having this property
can be made const too.
File size before: sound/pci/cs46xx/cs46xx_lib.o
text data bss dec hex filename
13669 1712 0 15381 3c15 sound/pci/cs46xx/cs46xx_lib.o
File size after: sound/pci/cs46xx/cs46xx_lib.o
text data bss dec hex filename
14181 1216 0 15397 3c25 sound/pci/cs46xx/cs46xx_lib.o
Signed-off-by: Bhumika Goyal <bhumirks(a)gmail.com>
---
sound/pci/cs46xx/cs46xx_lib.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index fde3cd4..5d012f5 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -72,18 +72,18 @@
static void amp_voyetra(struct snd_cs46xx *chip, int change);
#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
#endif
-static struct snd_pcm_ops snd_cs46xx_playback_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
-static struct snd_pcm_ops snd_cs46xx_capture_ops;
-static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
+static const struct snd_pcm_ops snd_cs46xx_capture_ops;
+static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
unsigned short reg,
@@ -1665,7 +1665,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
.open = snd_cs46xx_playback_open_rear,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1677,7 +1677,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
.ack = snd_cs46xx_playback_transfer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
.open = snd_cs46xx_playback_open_clfe,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1688,7 +1688,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
.open = snd_cs46xx_playback_open_clfe,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1700,7 +1700,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
.ack = snd_cs46xx_playback_transfer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
.open = snd_cs46xx_playback_open_iec958,
.close = snd_cs46xx_playback_close_iec958,
.ioctl = snd_pcm_lib_ioctl,
@@ -1711,7 +1711,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
.open = snd_cs46xx_playback_open_iec958,
.close = snd_cs46xx_playback_close_iec958,
.ioctl = snd_pcm_lib_ioctl,
@@ -1725,7 +1725,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
#endif
-static struct snd_pcm_ops snd_cs46xx_playback_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_ops = {
.open = snd_cs46xx_playback_open,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1736,7 +1736,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
.open = snd_cs46xx_playback_open,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1748,7 +1748,7 @@ static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
.ack = snd_cs46xx_playback_transfer,
};
-static struct snd_pcm_ops snd_cs46xx_capture_ops = {
+static const struct snd_pcm_ops snd_cs46xx_capture_ops = {
.open = snd_cs46xx_capture_open,
.close = snd_cs46xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1759,7 +1759,7 @@ static struct snd_pcm_ops snd_cs46xx_capture_ops = {
.pointer = snd_cs46xx_capture_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
+static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
.open = snd_cs46xx_capture_open,
.close = snd_cs46xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
--
2.7.4
3
2
[alsa-devel] [PATCH v2] sound: pci: cs46xx: constify snd_pcm_ops structures
by Bhumika Goyal 26 Jan '17
by Bhumika Goyal 26 Jan '17
26 Jan '17
Declare snd_pcm_ops structures as const as they are either stored in the
ops field of a snd_pcm_substream structure or passed as an argument to
the function snd_pcm_set_ops. The function argument and the ops field
are of type const, so snd_pcm_ops structures having this property
can be made const too.
File size before: sound/pci/cs46xx/cs46xx_lib.o
text data bss dec hex filename
26047 5304 16 31367 7a87 sound/pci/cs46xx/cs46xx_lib.o
File size after: sound/pci/cs46xx/cs46xx_lib.o
text data bss dec hex filename
27335 4036 16 31387 7a9b sound/pci/cs46xx/cs46xx_lib.o
Signed-off-by: Bhumika Goyal <bhumirks(a)gmail.com>
---
Changes in v2:
* test build the patch with CONFIG_SND_CS46XX_NEW_DSP=y
sound/pci/cs46xx/cs46xx_lib.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index fde3cd4..9a8b41f 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -72,18 +72,18 @@
static void amp_voyetra(struct snd_cs46xx *chip, int change);
#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
#endif
-static struct snd_pcm_ops snd_cs46xx_playback_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
-static struct snd_pcm_ops snd_cs46xx_capture_ops;
-static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_ops;
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
+static const struct snd_pcm_ops snd_cs46xx_capture_ops;
+static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
unsigned short reg,
@@ -1654,7 +1654,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
.open = snd_cs46xx_playback_open_rear,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1665,7 +1665,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
.open = snd_cs46xx_playback_open_rear,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1677,7 +1677,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.ack = snd_cs46xx_playback_transfer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
.open = snd_cs46xx_playback_open_clfe,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1688,7 +1688,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
.open = snd_cs46xx_playback_open_clfe,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1700,7 +1700,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.ack = snd_cs46xx_playback_transfer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
.open = snd_cs46xx_playback_open_iec958,
.close = snd_cs46xx_playback_close_iec958,
.ioctl = snd_pcm_lib_ioctl,
@@ -1711,7 +1711,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
.open = snd_cs46xx_playback_open_iec958,
.close = snd_cs46xx_playback_close_iec958,
.ioctl = snd_pcm_lib_ioctl,
@@ -1725,7 +1725,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
#endif
-static struct snd_pcm_ops snd_cs46xx_playback_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_ops = {
.open = snd_cs46xx_playback_open,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1736,7 +1736,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.pointer = snd_cs46xx_playback_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
+static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
.open = snd_cs46xx_playback_open,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1748,7 +1748,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.ack = snd_cs46xx_playback_transfer,
};
-static struct snd_pcm_ops snd_cs46xx_capture_ops = {
+static const struct snd_pcm_ops snd_cs46xx_capture_ops = {
.open = snd_cs46xx_capture_open,
.close = snd_cs46xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1759,7 +1759,7 @@ static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
.pointer = snd_cs46xx_capture_direct_pointer,
};
-static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
+static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
.open = snd_cs46xx_capture_open,
.close = snd_cs46xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
--
1.9.1
2
1