pwm controlled led
This commit is contained in:
parent
8ff56e1c18
commit
42965b3b7a
1 changed files with 60 additions and 6 deletions
66
usbio-led.c
66
usbio-led.c
|
@ -9,20 +9,69 @@
|
|||
#define USBIO_VENDOR_ID 0x04d8
|
||||
#define USBIO_PRODUCT_ID 0x003f
|
||||
|
||||
enum {
|
||||
ANSELD = 0x5e,
|
||||
TRISD = 0x95,
|
||||
CCPTMRS = 0x59,
|
||||
PR2 = 0xbb,
|
||||
CCP1CON = 0xbd,
|
||||
CCPR1L = 0xbe,
|
||||
T2CON = 0xba,
|
||||
PSTR1CON = 0xb9
|
||||
};
|
||||
|
||||
struct usbio_led {
|
||||
struct usb_device *udev;
|
||||
struct led_classdev ldev;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
int usbio_set_register(struct usb_device *usb_dev, u8 reg, u8 value)
|
||||
{
|
||||
u8 data[14];
|
||||
int actual_len = 14;
|
||||
memset(data, 0, 14);
|
||||
data[10] = reg;
|
||||
data[11] = value;
|
||||
data[0] = 0x99;
|
||||
return usb_interrupt_msg(usb_dev,
|
||||
usb_sndintpipe(usb_dev, 1),
|
||||
data, sizeof(data), &actual_len, USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
|
||||
int usbio_set_register_bit(struct usb_device *usb_dev, u8 reg, u8 reg_bit, u8 value)
|
||||
{
|
||||
u8 data[14];
|
||||
int actual_len = 14;
|
||||
memset(data, 0, 14);
|
||||
data[10] = reg;
|
||||
data[11] = reg_bit;
|
||||
data[12] = value;
|
||||
data[0] = 0x9b;
|
||||
return usb_interrupt_msg(usb_dev,
|
||||
usb_sndintpipe(usb_dev, 1),
|
||||
data, sizeof(data), &actual_len, USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
static int usbio_pwm_init(struct usb_device *usb_dev)
|
||||
{
|
||||
usbio_set_register_bit(usb_dev, ANSELD, 5, 0);
|
||||
usbio_set_register_bit(usb_dev, TRISD, 5, 1);
|
||||
usbio_set_register_bit(usb_dev, PSTR1CON, 1, 1);
|
||||
usbio_set_register_bit(usb_dev, TRISD, 5, 0);
|
||||
usbio_set_register(usb_dev, CCPTMRS, 0x00);
|
||||
usbio_set_register(usb_dev, PR2, 199);
|
||||
usbio_set_register(usb_dev, CCP1CON, 0b00001100);
|
||||
usbio_set_register(usb_dev, CCPR1L, 0x00);
|
||||
usbio_set_register(usb_dev, T2CON, 0b00000110);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbio_led_set(struct led_classdev *ldev, enum led_brightness brightness) {
|
||||
u8 data[] = { 0x80 };
|
||||
struct usbio_led *led = container_of(ldev, struct usbio_led, ldev);
|
||||
int actual_len = 1;
|
||||
mutex_lock(&led->lock);
|
||||
usb_interrupt_msg(led->udev,
|
||||
usb_sndintpipe(led->udev, 1),
|
||||
data, sizeof(data), &actual_len, USB_CTRL_SET_TIMEOUT);
|
||||
usbio_set_register(led->udev, CCPR1L, brightness);
|
||||
mutex_unlock(&led->lock);
|
||||
}
|
||||
|
||||
|
@ -40,8 +89,13 @@ static int usbio_led_probe(struct usb_interface *interface, const struct usb_dev
|
|||
usb_set_intfdata(interface, led);
|
||||
dev_info(&interface->dev, "USBIO LED attached\n");
|
||||
mutex_init(&led->lock);
|
||||
|
||||
mutex_lock(&led->lock);
|
||||
usbio_pwm_init(led->udev);
|
||||
mutex_unlock(&led->lock);
|
||||
|
||||
led->ldev.name = "usbio_led";
|
||||
led->ldev.max_brightness = 1;
|
||||
led->ldev.max_brightness = 255;
|
||||
led->ldev.brightness = LED_OFF;
|
||||
led->ldev.brightness_set = usbio_led_set;
|
||||
|
||||
|
|
Loading…
Reference in a new issue