aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/line6/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/line6/pcm.c')
-rw-r--r--drivers/staging/line6/pcm.c96
1 files changed, 51 insertions, 45 deletions
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index 6c1e31335d1..a3136b189ee 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -34,8 +34,8 @@ static struct snd_line6_pcm *dev2pcm(struct device *dev)
/*
"read" request on "impulse_volume" special file.
*/
-static ssize_t pcm_get_impulse_volume(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t impulse_volume_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume);
}
@@ -43,17 +43,17 @@ static ssize_t pcm_get_impulse_volume(struct device *dev,
/*
"write" request on "impulse_volume" special file.
*/
-static ssize_t pcm_set_impulse_volume(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t impulse_volume_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct snd_line6_pcm *line6pcm = dev2pcm(dev);
int value;
- int rv;
+ int ret;
- rv = kstrtoint(buf, 10, &value);
- if (rv < 0)
- return rv;
+ ret = kstrtoint(buf, 10, &value);
+ if (ret < 0)
+ return ret;
line6pcm->impulse_volume = value;
@@ -64,12 +64,13 @@ static ssize_t pcm_set_impulse_volume(struct device *dev,
return count;
}
+static DEVICE_ATTR_RW(impulse_volume);
/*
"read" request on "impulse_period" special file.
*/
-static ssize_t pcm_get_impulse_period(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t impulse_period_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period);
}
@@ -77,18 +78,21 @@ static ssize_t pcm_get_impulse_period(struct device *dev,
/*
"write" request on "impulse_period" special file.
*/
-static ssize_t pcm_set_impulse_period(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t impulse_period_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- dev2pcm(dev)->impulse_period = simple_strtoul(buf, NULL, 10);
+ int value;
+ int ret;
+
+ ret = kstrtoint(buf, 10, &value);
+ if (ret < 0)
+ return ret;
+
+ dev2pcm(dev)->impulse_period = value;
return count;
}
-
-static DEVICE_ATTR(impulse_volume, S_IWUSR | S_IRUGO, pcm_get_impulse_volume,
- pcm_set_impulse_volume);
-static DEVICE_ATTR(impulse_period, S_IWUSR | S_IRUGO, pcm_get_impulse_period,
- pcm_set_impulse_period);
+static DEVICE_ATTR_RW(impulse_period);
#endif
@@ -100,11 +104,15 @@ static bool test_flags(unsigned long flags0, unsigned long flags1,
int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
{
- unsigned long flags_old =
- __sync_fetch_and_or(&line6pcm->flags, channels);
- unsigned long flags_new = flags_old | channels;
- unsigned long flags_final = flags_old;
- int err = 0;
+ unsigned long flags_old, flags_new, flags_final;
+ int err;
+
+ do {
+ flags_old = ACCESS_ONCE(line6pcm->flags);
+ flags_new = flags_old | channels;
+ } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
+
+ flags_final = flags_old;
line6pcm->prev_fbuf = NULL;
@@ -114,10 +122,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
line6pcm->buffer_in =
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
line6pcm->max_packet_size, GFP_KERNEL);
-
if (!line6pcm->buffer_in) {
- dev_err(line6pcm->line6->ifcdev,
- "cannot malloc capture buffer\n");
err = -ENOMEM;
goto pcm_acquire_error;
}
@@ -153,10 +158,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
line6pcm->buffer_out =
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
line6pcm->max_packet_size, GFP_KERNEL);
-
if (!line6pcm->buffer_out) {
- dev_err(line6pcm->line6->ifcdev,
- "cannot malloc playback buffer\n");
err = -ENOMEM;
goto pcm_acquire_error;
}
@@ -196,9 +198,12 @@ pcm_acquire_error:
int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
{
- unsigned long flags_old =
- __sync_fetch_and_and(&line6pcm->flags, ~channels);
- unsigned long flags_new = flags_old & ~channels;
+ unsigned long flags_old, flags_new;
+
+ do {
+ flags_old = ACCESS_ONCE(line6pcm->flags);
+ flags_new = flags_old & ~channels;
+ } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
line6_unlink_audio_in_urbs(line6pcm);
@@ -384,8 +389,11 @@ static int snd_line6_pcm_free(struct snd_device *device)
*/
static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
{
- if (substream->runtime && snd_pcm_running(substream))
+ if (substream->runtime && snd_pcm_running(substream)) {
+ snd_pcm_stream_lock_irq(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+ snd_pcm_stream_unlock_irq(substream);
+ }
}
/*
@@ -428,6 +436,7 @@ int line6_init_pcm(struct usb_line6 *line6,
case LINE6_DEVID_PODXTLIVE:
case LINE6_DEVID_PODXTPRO:
case LINE6_DEVID_PODHD300:
+ case LINE6_DEVID_PODHD400:
ep_read = 0x82;
ep_write = 0x01;
break;
@@ -455,19 +464,18 @@ int line6_init_pcm(struct usb_line6 *line6,
ep_write = 0x01;
break;
- /* this is for interface_number == 1:
- case LINE6_DEVID_TONEPORT_UX2:
- case LINE6_DEVID_PODSTUDIO_UX2:
- ep_read = 0x87;
- ep_write = 0x00;
- break;
- */
+ /* this is for interface_number == 1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_PODSTUDIO_UX2:
+ ep_read = 0x87;
+ ep_write = 0x00;
+ break; */
default:
MISSING_CASE;
}
- line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
+ line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
if (line6pcm == NULL)
return -ENOMEM;
@@ -493,8 +501,6 @@ int line6_init_pcm(struct usb_line6 *line6,
if (err < 0)
return err;
- snd_card_set_dev(line6->card, line6->ifcdev);
-
err = snd_line6_new_pcm(line6pcm);
if (err < 0)
return err;