linux/sound/usb/helper.c
<<
>>
Prefs
   1/*
   2 *   This program is free software; you can redistribute it and/or modify
   3 *   it under the terms of the GNU General Public License as published by
   4 *   the Free Software Foundation; either version 2 of the License, or
   5 *   (at your option) any later version.
   6 *
   7 *   This program is distributed in the hope that it will be useful,
   8 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 *   GNU General Public License for more details.
  11 *
  12 *   You should have received a copy of the GNU General Public License
  13 *   along with this program; if not, write to the Free Software
  14 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  15 *
  16 */
  17
  18#include <linux/init.h>
  19#include <linux/slab.h>
  20#include <linux/usb.h>
  21
  22#include "usbaudio.h"
  23#include "helper.h"
  24
  25/*
  26 * combine bytes and get an integer value
  27 */
  28unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
  29{
  30        switch (size) {
  31        case 1:  return *bytes;
  32        case 2:  return combine_word(bytes);
  33        case 3:  return combine_triple(bytes);
  34        case 4:  return combine_quad(bytes);
  35        default: return 0;
  36        }
  37}
  38
  39/*
  40 * parse descriptor buffer and return the pointer starting the given
  41 * descriptor type.
  42 */
  43void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
  44{
  45        u8 *p, *end, *next;
  46
  47        p = descstart;
  48        end = p + desclen;
  49        for (; p < end;) {
  50                if (p[0] < 2)
  51                        return NULL;
  52                next = p + p[0];
  53                if (next > end)
  54                        return NULL;
  55                if (p[1] == dtype && (!after || (void *)p > after)) {
  56                        return p;
  57                }
  58                p = next;
  59        }
  60        return NULL;
  61}
  62
  63/*
  64 * find a class-specified interface descriptor with the given subtype.
  65 */
  66void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
  67{
  68        unsigned char *p = after;
  69
  70        while ((p = snd_usb_find_desc(buffer, buflen, p,
  71                                      USB_DT_CS_INTERFACE)) != NULL) {
  72                if (p[0] >= 3 && p[2] == dsubtype)
  73                        return p;
  74        }
  75        return NULL;
  76}
  77
  78/*
  79 * Wrapper for usb_control_msg().
  80 * Allocates a temp buffer to prevent dmaing from/to the stack.
  81 */
  82int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
  83                    __u8 requesttype, __u16 value, __u16 index, void *data,
  84                    __u16 size)
  85{
  86        int err;
  87        void *buf = NULL;
  88
  89        if (size > 0) {
  90                buf = kmemdup(data, size, GFP_KERNEL);
  91                if (!buf)
  92                        return -ENOMEM;
  93        }
  94        err = usb_control_msg(dev, pipe, request, requesttype,
  95                              value, index, buf, size, 1000);
  96        if (size > 0) {
  97                memcpy(data, buf, size);
  98                kfree(buf);
  99        }
 100        return err;
 101}
 102
 103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
 104                                         struct usb_host_interface *alts)
 105{
 106        switch (snd_usb_get_speed(chip->dev)) {
 107        case USB_SPEED_HIGH:
 108        case USB_SPEED_SUPER:
 109                if (get_endpoint(alts, 0)->bInterval >= 1 &&
 110                    get_endpoint(alts, 0)->bInterval <= 4)
 111                        return get_endpoint(alts, 0)->bInterval - 1;
 112                break;
 113        default:
 114                break;
 115        }
 116        return 0;
 117}
 118
 119
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.