Commit 337b2f0e authored by Geoffrey D. Bennett's avatar Geoffrey D. Bennett Committed by Takashi Iwai
Browse files

ALSA: scarlett2: Add skeleton hwdep/ioctl interface



Add skeleton hwdep/ioctl interface, beginning with
SCARLETT2_IOCTL_PVERSION and SCARLETT2_IOCTL_REBOOT.

Signed-off-by: default avatarGeoffrey D. Bennett <g@b4.vu>
Link: https://lore.kernel.org/r/24ffcd47a8a02ebad3c8b2438104af8f0169164e.1703001053.git.g@b4.vu


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 34101a0f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8279,6 +8279,7 @@ S: Maintained
W:	https://github.com/geoffreybennett/scarlett-gen2
B:	https://github.com/geoffreybennett/scarlett-gen2/issues
T:	git https://github.com/geoffreybennett/scarlett-gen2.git
F:	include/uapi/sound/scarlett2.h
F:	sound/usb/mixer_scarlett2.c
FORCEDETH GIGABIT ETHERNET DRIVER
+34 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *   Focusrite Scarlett 2 Protocol Driver for ALSA
 *   (including Scarlett 2nd Gen, 3rd Gen, Clarett USB, and Clarett+
 *   series products)
 *
 *   Copyright (c) 2023 by Geoffrey D. Bennett <g at b4.vu>
 */
#ifndef __UAPI_SOUND_SCARLETT2_H
#define __UAPI_SOUND_SCARLETT2_H

#include <linux/types.h>
#include <linux/ioctl.h>

#define SCARLETT2_HWDEP_MAJOR 1
#define SCARLETT2_HWDEP_MINOR 0
#define SCARLETT2_HWDEP_SUBMINOR 0

#define SCARLETT2_HWDEP_VERSION \
	((SCARLETT2_HWDEP_MAJOR << 16) | \
	 (SCARLETT2_HWDEP_MINOR << 8) | \
	  SCARLETT2_HWDEP_SUBMINOR)

#define SCARLETT2_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF)
#define SCARLETT2_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF)
#define SCARLETT2_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF)

/* Get protocol version */
#define SCARLETT2_IOCTL_PVERSION _IOR('S', 0x60, int)

/* Reboot */
#define SCARLETT2_IOCTL_REBOOT _IO('S', 0x61)

#endif /* __UAPI_SOUND_SCARLETT2_H */
+66 −1
Original line number Diff line number Diff line
@@ -146,6 +146,9 @@

#include <sound/control.h>
#include <sound/tlv.h>
#include <sound/hwdep.h>

#include <uapi/sound/scarlett2.h>

#include "usbaudio.h"
#include "mixer.h"
@@ -1439,6 +1442,16 @@ static int scarlett2_usb(
	/* validate the response */

	if (err != resp_buf_size) {

		/* ESHUTDOWN and EPROTO are valid responses to a
		 * reboot request
		 */
		if (cmd == SCARLETT2_USB_REBOOT &&
		    (err == -ESHUTDOWN || err == -EPROTO)) {
			err = 0;
			goto unlock;
		}

		usb_audio_err(
			mixer->chip,
			"%s USB response result cmd %x was %d expected %zu\n",
@@ -4697,6 +4710,49 @@ static int snd_scarlett2_controls_create(
	return 0;
}

/*** hwdep interface ***/

/* Reboot the device. */
static int scarlett2_reboot(struct usb_mixer_interface *mixer)
{
	return scarlett2_usb(mixer, SCARLETT2_USB_REBOOT, NULL, 0, NULL, 0);
}

static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
				 unsigned int cmd, unsigned long arg)
{
	struct usb_mixer_interface *mixer = hw->private_data;

	switch (cmd) {

	case SCARLETT2_IOCTL_PVERSION:
		return put_user(SCARLETT2_HWDEP_VERSION,
				(int __user *)arg) ? -EFAULT : 0;

	case SCARLETT2_IOCTL_REBOOT:
		return scarlett2_reboot(mixer);

	default:
		return -ENOIOCTLCMD;
	}
}

static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer)
{
	struct snd_hwdep *hw;
	int err;

	err = snd_hwdep_new(mixer->chip->card, "Focusrite Control", 0, &hw);
	if (err < 0)
		return err;

	hw->private_data = mixer;
	hw->exclusive = 1;
	hw->ops.ioctl = scarlett2_hwdep_ioctl;

	return 0;
}

int snd_scarlett2_init(struct usb_mixer_interface *mixer)
{
	struct snd_usb_audio *chip = mixer->chip;
@@ -4738,11 +4794,20 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer)
		USB_ID_PRODUCT(chip->usb_id));

	err = snd_scarlett2_controls_create(mixer, entry);
	if (err < 0)
	if (err < 0) {
		usb_audio_err(mixer->chip,
			      "Error initialising %s Mixer Driver: %d",
			      entry->series_name,
			      err);
		return err;
	}

	err = scarlett2_hwdep_init(mixer);
	if (err < 0)
		usb_audio_err(mixer->chip,
			      "Error creating %s hwdep device: %d",
			      entry->series_name,
			      err);

	return err;
}