From 42965b3b7a620ce20de4dfddf1c366b7ff2c5eb1 Mon Sep 17 00:00:00 2001 From: encrypt Date: Tue, 5 Jan 2016 22:35:24 +0100 Subject: [PATCH] pwm controlled led --- usbio-led.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/usbio-led.c b/usbio-led.c index 7e382f1..17b6c4b 100644 --- a/usbio-led.c +++ b/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;