mirror of
https://github.com/grymoire/i2c_puppet-Linux.git
synced 2024-12-26 13:38:21 +01:00
Pre-release fixes
This commit is contained in:
parent
04604f3a1c
commit
2578c4d01c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
build
|
build
|
||||||
*.txt.user
|
*.txt.user
|
||||||
|
__pycache__
|
||||||
|
2
3rdparty/pico-sdk
vendored
2
3rdparty/pico-sdk
vendored
@ -1 +1 @@
|
|||||||
Subproject commit bfcbefafc5d2a210551a4d9d80b4303d4ae0adf7
|
Subproject commit 2062372d203b372849d573f252cf7c6dc2800c0a
|
15
README.md
15
README.md
@ -1,7 +1,22 @@
|
|||||||
# I2C Puppet
|
# I2C Puppet
|
||||||
|
|
||||||
|
## Checkout
|
||||||
|
|
||||||
git clone https://github.com/solderparty/i2c_puppet
|
git clone https://github.com/solderparty/i2c_puppet
|
||||||
cd i2c_puppet
|
cd i2c_puppet
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
cd 3rdparty/pico-sdk
|
cd 3rdparty/pico-sdk
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DPICO_BOARD=bbq20kbd_breakout -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
make
|
||||||
|
|
||||||
|
## Add rules
|
||||||
|
|
||||||
|
sudo cp tools/99-i2c_puppet.rules /lib/udev/rules.d/
|
||||||
|
sudo udevadm control --reload
|
||||||
|
sudo udevadm trigger
|
||||||
|
24
app/debug.c
24
app/debug.c
@ -19,10 +19,7 @@ static void key_cb(char key, enum key_state state)
|
|||||||
{
|
{
|
||||||
printf("key: 0x%02X/%d/%c, state: %d\r\n", key, key, key, state);
|
printf("key: 0x%02X/%d/%c, state: %d\r\n", key, key, key, state);
|
||||||
}
|
}
|
||||||
static struct key_callback key_callback =
|
static struct key_callback key_callback = { .func = key_cb };
|
||||||
{
|
|
||||||
.func = key_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void key_lock_cb(bool caps_changed, bool num_changed)
|
static void key_lock_cb(bool caps_changed, bool num_changed)
|
||||||
{
|
{
|
||||||
@ -30,28 +27,19 @@ static void key_lock_cb(bool caps_changed, bool num_changed)
|
|||||||
caps_changed, keyboard_get_capslock(),
|
caps_changed, keyboard_get_capslock(),
|
||||||
num_changed, keyboard_get_numlock());
|
num_changed, keyboard_get_numlock());
|
||||||
}
|
}
|
||||||
static struct key_lock_callback key_lock_callback =
|
static struct key_lock_callback key_lock_callback ={ .func = key_lock_cb };
|
||||||
{
|
|
||||||
.func = key_lock_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void touch_cb(int8_t x, int8_t y)
|
static void touch_cb(int8_t x, int8_t y)
|
||||||
{
|
{
|
||||||
// printf("%s: x: %d, y: %d !\r\n", __func__, x, y);
|
printf("%s: x: %d, y: %d !\r\n", __func__, x, y);
|
||||||
}
|
}
|
||||||
static struct touch_callback touch_callback =
|
static struct touch_callback touch_callback = { .func = touch_cb };
|
||||||
{
|
|
||||||
.func = touch_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void gpioexp_cb(uint8_t gpio, uint8_t gpio_idx)
|
static void gpioexp_cb(uint8_t gpio, uint8_t gpio_idx)
|
||||||
{
|
{
|
||||||
printf("gpioexp, pin: %d, idx: %d\r\n", gpio, gpio_idx);
|
printf("gpioexp, pin: %d, idx: %d\r\n", gpio, gpio_idx);
|
||||||
}
|
}
|
||||||
static struct gpioexp_callback gpioexp_callback =
|
static struct gpioexp_callback gpioexp_callback = { .func = gpioexp_cb };
|
||||||
{
|
|
||||||
.func = gpioexp_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
// copied from pico_stdio_usb in the SDK
|
// copied from pico_stdio_usb in the SDK
|
||||||
static void usb_out_chars(const char *buf, int length)
|
static void usb_out_chars(const char *buf, int length)
|
||||||
@ -105,7 +93,7 @@ void debug_init(void)
|
|||||||
{
|
{
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|
||||||
// stdio_set_driver_enabled(&stdio_usb, true);
|
stdio_set_driver_enabled(&stdio_usb, true);
|
||||||
|
|
||||||
printf("I2C Puppet SW v%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR);
|
printf("I2C Puppet SW v%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR);
|
||||||
|
|
||||||
|
@ -222,12 +222,6 @@ uint8_t gpioexp_get_value(void)
|
|||||||
#define GET_VALUE(bit) \
|
#define GET_VALUE(bit) \
|
||||||
value |= (gpio_get(PIN_GPIOEXP ## bit) << bit);
|
value |= (gpio_get(PIN_GPIOEXP ## bit) << bit);
|
||||||
|
|
||||||
// if (reg_is_bit_set(REG_ID_DIR, (1 << bit)) == DIR_INPUT) { \
|
|
||||||
// value |= (port_pin_get_input_level(PIN_GPIOEXP ## bit) << bit); \
|
|
||||||
// } else { \
|
|
||||||
// value |= (port_pin_get_output_level(PIN_GPIOEXP ## bit) << bit); \
|
|
||||||
// }
|
|
||||||
|
|
||||||
#ifdef PIN_GPIOEXP0
|
#ifdef PIN_GPIOEXP0
|
||||||
GET_VALUE(0)
|
GET_VALUE(0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,10 +22,7 @@ static void key_cb(char key, enum key_state state)
|
|||||||
busy_wait_ms(reg_get_value(REG_ID_IND));
|
busy_wait_ms(reg_get_value(REG_ID_IND));
|
||||||
gpio_put(PIN_INT, 1);
|
gpio_put(PIN_INT, 1);
|
||||||
}
|
}
|
||||||
static struct key_callback key_callback =
|
static struct key_callback key_callback = { .func = key_cb };
|
||||||
{
|
|
||||||
.func = key_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void key_lock_cb(bool caps_changed, bool num_changed)
|
static void key_lock_cb(bool caps_changed, bool num_changed)
|
||||||
{
|
{
|
||||||
@ -47,10 +44,7 @@ static void key_lock_cb(bool caps_changed, bool num_changed)
|
|||||||
gpio_put(PIN_INT, 1);
|
gpio_put(PIN_INT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static struct key_lock_callback key_lock_callback =
|
static struct key_lock_callback key_lock_callback = { .func = key_lock_cb };
|
||||||
{
|
|
||||||
.func = key_lock_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void touch_cb(int8_t x, int8_t y)
|
static void touch_cb(int8_t x, int8_t y)
|
||||||
{
|
{
|
||||||
@ -66,10 +60,7 @@ static void touch_cb(int8_t x, int8_t y)
|
|||||||
busy_wait_ms(reg_get_value(REG_ID_IND));
|
busy_wait_ms(reg_get_value(REG_ID_IND));
|
||||||
gpio_put(PIN_INT, 1);
|
gpio_put(PIN_INT, 1);
|
||||||
}
|
}
|
||||||
static struct touch_callback touch_callback =
|
static struct touch_callback touch_callback = { .func = touch_cb };
|
||||||
{
|
|
||||||
.func = touch_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void gpioexp_cb(uint8_t gpio, uint8_t gpio_idx)
|
static void gpioexp_cb(uint8_t gpio, uint8_t gpio_idx)
|
||||||
{
|
{
|
||||||
@ -85,10 +76,7 @@ static void gpioexp_cb(uint8_t gpio, uint8_t gpio_idx)
|
|||||||
busy_wait_ms(reg_get_value(REG_ID_IND));
|
busy_wait_ms(reg_get_value(REG_ID_IND));
|
||||||
gpio_put(PIN_INT, 1);
|
gpio_put(PIN_INT, 1);
|
||||||
}
|
}
|
||||||
static struct gpioexp_callback gpioexp_callback =
|
static struct gpioexp_callback gpioexp_callback = { .func = gpioexp_cb };
|
||||||
{
|
|
||||||
.func = gpioexp_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
void interrupt_init(void)
|
void interrupt_init(void)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "touchpad.h"
|
#include "touchpad.h"
|
||||||
|
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
#include <RP2040.h>
|
#include <RP2040.h> // TODO: When there's more than one RP chip, change this to be more generic
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// We don't enable this by default cause it spams quite a lot
|
// We don't enable this by default cause it spams quite a lot
|
||||||
@ -29,11 +29,7 @@ static void touch_cb(int8_t x, int8_t y)
|
|||||||
self.regs[REG_ID_TOX] = MAX(INT8_MIN, MIN(dx, INT8_MAX));
|
self.regs[REG_ID_TOX] = MAX(INT8_MIN, MIN(dx, INT8_MAX));
|
||||||
self.regs[REG_ID_TOY] = MAX(INT8_MIN, MIN(dy, INT8_MAX));
|
self.regs[REG_ID_TOY] = MAX(INT8_MIN, MIN(dy, INT8_MAX));
|
||||||
}
|
}
|
||||||
static struct touch_callback touch_callback =
|
static struct touch_callback touch_callback = { .func = touch_cb };
|
||||||
{
|
|
||||||
.func = touch_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void reg_process_packet(uint8_t in_reg, uint8_t in_data, uint8_t *out_buffer, uint8_t *out_len)
|
void reg_process_packet(uint8_t in_reg, uint8_t in_data, uint8_t *out_buffer, uint8_t *out_len)
|
||||||
{
|
{
|
||||||
|
62
app/usb.c
62
app/usb.c
@ -22,7 +22,6 @@ static struct
|
|||||||
uint8_t write_len;
|
uint8_t write_len;
|
||||||
} self;
|
} self;
|
||||||
|
|
||||||
// TODO: Should mods always be sent?
|
|
||||||
// TODO: What about Ctrl?
|
// TODO: What about Ctrl?
|
||||||
// TODO: What should L1, L2, R1, R2 do
|
// TODO: What should L1, L2, R1, R2 do
|
||||||
// TODO: Should touch send arrow keys as an option?
|
// TODO: Should touch send arrow keys as an option?
|
||||||
@ -86,10 +85,7 @@ static void key_cb(char key, enum key_state state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static struct key_callback key_callback =
|
static struct key_callback key_callback = { .func = key_cb };
|
||||||
{
|
|
||||||
.func = key_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
static void touch_cb(int8_t x, int8_t y)
|
static void touch_cb(int8_t x, int8_t y)
|
||||||
{
|
{
|
||||||
@ -100,10 +96,7 @@ static void touch_cb(int8_t x, int8_t y)
|
|||||||
|
|
||||||
tud_hid_n_mouse_report(USB_ITF_MOUSE, 0, self.mouse_btn, x, y, 0, 0);
|
tud_hid_n_mouse_report(USB_ITF_MOUSE, 0, self.mouse_btn, x, y, 0, 0);
|
||||||
}
|
}
|
||||||
static struct touch_callback touch_callback =
|
static struct touch_callback touch_callback = { .func = touch_cb };
|
||||||
{
|
|
||||||
.func = touch_cb
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen)
|
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen)
|
||||||
{
|
{
|
||||||
@ -115,15 +108,6 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
|
|||||||
(void)reqlen;
|
(void)reqlen;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// if (itf != USB_ITF_HID_GENERIC)
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
// printf("%s: itf: %d, report id: %d, type: %d, len: %d\r\n", __func__, itf, report_id, report_type, reqlen);
|
|
||||||
|
|
||||||
// memcpy(buffer, self.write_buffer, self.write_len);
|
|
||||||
|
|
||||||
// return self.write_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t len)
|
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t len)
|
||||||
@ -134,35 +118,11 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
|||||||
(void)report_type;
|
(void)report_type;
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
(void)len;
|
(void)len;
|
||||||
|
|
||||||
// if (itf != USB_ITF_HID_GENERIC)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// printf("%s: itf: %d, report id: %d, type: %d, buff: %02X %02X %02X len: %d\r\n", __func__, itf, report_id, report_type, buffer[0], buffer[1], buffer[2], len);
|
|
||||||
|
|
||||||
// if (len < 1)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// const bool is_write = (buffer[0] & PACKET_WRITE_MASK);
|
|
||||||
// const uint8_t reg = (buffer[0] & ~PACKET_WRITE_MASK);
|
|
||||||
|
|
||||||
// printf("%s: read complete, is_write: %d, reg: 0x%02X\r\n", __func__, is_write, reg);
|
|
||||||
|
|
||||||
// if (is_write && (len < 2))
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// printf("%s: data: 0x%02X\r\n", __func__, buffer[1]);
|
|
||||||
|
|
||||||
// reg_process_packet(buffer[0], buffer[1], (uint8_t*)&self.write_buffer, &self.write_len);
|
|
||||||
|
|
||||||
// printf("%s: write_buff: %02X %02X, len: %d\r\n", __func__, self.write_buffer[0], self.write_buffer[1], self.write_len);
|
|
||||||
|
|
||||||
// tud_hid_n_report(itf, report_id, self.write_buffer, self.write_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_vendor_rx_cb(uint8_t itf)
|
void tud_vendor_rx_cb(uint8_t itf)
|
||||||
{
|
{
|
||||||
printf("%s: itf: %d, avail: %d\r\n", __func__, itf, tud_vendor_n_available(itf));
|
// printf("%s: itf: %d, avail: %d\r\n", __func__, itf, tud_vendor_n_available(itf));
|
||||||
|
|
||||||
uint8_t buff[64] = { 0 };
|
uint8_t buff[64] = { 0 };
|
||||||
tud_vendor_n_read(itf, buff, 64);
|
tud_vendor_n_read(itf, buff, 64);
|
||||||
@ -173,6 +133,17 @@ void tud_vendor_rx_cb(uint8_t itf)
|
|||||||
tud_vendor_n_write(itf, self.write_buffer, self.write_len);
|
tud_vendor_n_write(itf, self.write_buffer, self.write_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tud_mount_cb(void)
|
||||||
|
{
|
||||||
|
// Send mods over USB by default if USB connected
|
||||||
|
reg_set_value(REG_ID_CFG, reg_get_value(REG_ID_CFG) | CFG_REPORT_MODS);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_t *usb_get_mutex(void)
|
||||||
|
{
|
||||||
|
return &self.mutex;
|
||||||
|
}
|
||||||
|
|
||||||
void usb_init(void)
|
void usb_init(void)
|
||||||
{
|
{
|
||||||
tusb_init();
|
tusb_init();
|
||||||
@ -188,8 +159,3 @@ void usb_init(void)
|
|||||||
mutex_init(&self.mutex);
|
mutex_init(&self.mutex);
|
||||||
add_alarm_in_us(USB_TASK_INTERVAL_US, timer_task, NULL, true);
|
add_alarm_in_us(USB_TASK_INTERVAL_US, timer_task, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_t *usb_get_mutex(void)
|
|
||||||
{
|
|
||||||
return &self.mutex;
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <tusb.h>
|
#include <tusb.h>
|
||||||
|
|
||||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_HID_DESC_LEN /*+ TUD_HID_DESC_LEN*/ + TUD_VENDOR_DESC_LEN + TUD_CDC_DESC_LEN)
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_HID_DESC_LEN + TUD_VENDOR_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||||
|
|
||||||
#define EPNUM_HID_KEYBOARD 0x81
|
#define EPNUM_HID_KEYBOARD 0x81
|
||||||
#define EPNUM_HID_MOUSE 0x82
|
#define EPNUM_HID_MOUSE 0x82
|
||||||
@ -61,11 +61,6 @@ uint8_t const hid_mouse_descriptor[] =
|
|||||||
TUD_HID_REPORT_DESC_MOUSE()
|
TUD_HID_REPORT_DESC_MOUSE()
|
||||||
};
|
};
|
||||||
|
|
||||||
//uint8_t const hid_generic_descriptor[] =
|
|
||||||
//{
|
|
||||||
// TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE)
|
|
||||||
//};
|
|
||||||
|
|
||||||
uint8_t const config_descriptor[] =
|
uint8_t const config_descriptor[] =
|
||||||
{
|
{
|
||||||
TUD_CONFIG_DESCRIPTOR(1, USB_ITF_MAX, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
TUD_CONFIG_DESCRIPTOR(1, USB_ITF_MAX, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||||
@ -73,8 +68,6 @@ uint8_t const config_descriptor[] =
|
|||||||
TUD_HID_DESCRIPTOR(USB_ITF_KEYBOARD, 4, HID_ITF_PROTOCOL_NONE, sizeof(hid_keyboard_descriptor), EPNUM_HID_KEYBOARD, CFG_TUD_HID_EP_BUFSIZE, 10),
|
TUD_HID_DESCRIPTOR(USB_ITF_KEYBOARD, 4, HID_ITF_PROTOCOL_NONE, sizeof(hid_keyboard_descriptor), EPNUM_HID_KEYBOARD, CFG_TUD_HID_EP_BUFSIZE, 10),
|
||||||
TUD_HID_DESCRIPTOR(USB_ITF_MOUSE, 5, HID_ITF_PROTOCOL_NONE, sizeof(hid_mouse_descriptor), EPNUM_HID_MOUSE, CFG_TUD_HID_EP_BUFSIZE, 10),
|
TUD_HID_DESCRIPTOR(USB_ITF_MOUSE, 5, HID_ITF_PROTOCOL_NONE, sizeof(hid_mouse_descriptor), EPNUM_HID_MOUSE, CFG_TUD_HID_EP_BUFSIZE, 10),
|
||||||
|
|
||||||
// TUD_HID_DESCRIPTOR(USB_ITF_HID_GENERIC, 6, HID_ITF_PROTOCOL_NONE, sizeof(hid_generic_descriptor), EPNUM_HID_GENERIC, CFG_TUD_HID_EP_BUFSIZE, 10),
|
|
||||||
|
|
||||||
TUD_VENDOR_DESCRIPTOR(USB_ITF_VENDOR, 7, EPNUM_VENDOR_OUT, EPNUM_VENDOR_IN, CFG_TUD_VENDOR_EPSIZE),
|
TUD_VENDOR_DESCRIPTOR(USB_ITF_VENDOR, 7, EPNUM_VENDOR_OUT, EPNUM_VENDOR_IN, CFG_TUD_VENDOR_EPSIZE),
|
||||||
|
|
||||||
TUD_CDC_DESCRIPTOR(USB_ITF_CDC, 7, EPNUM_CDC_CMD, CDC_CMD_MAX_SIZE, EPNUM_CDC_OUT, EPNUM_CDC_IN, CDC_IN_OUT_MAX_SIZE),
|
TUD_CDC_DESCRIPTOR(USB_ITF_CDC, 7, EPNUM_CDC_CMD, CDC_CMD_MAX_SIZE, EPNUM_CDC_OUT, EPNUM_CDC_IN, CDC_IN_OUT_MAX_SIZE),
|
||||||
@ -93,9 +86,6 @@ uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf)
|
|||||||
if (itf == USB_ITF_MOUSE)
|
if (itf == USB_ITF_MOUSE)
|
||||||
return hid_mouse_descriptor;
|
return hid_mouse_descriptor;
|
||||||
|
|
||||||
// if (itf == USB_ITF_HID_GENERIC)
|
|
||||||
// return hid_generic_descriptor;
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define USB_PID 0x4009
|
#define USB_VID 0x1209
|
||||||
#define USB_VID 0xABBA
|
#define USB_PID 0xB182
|
||||||
#define USB_PRODUCT "BBQ20KBD"
|
#define USB_PRODUCT "BBQ20KBD"
|
||||||
|
|
||||||
#define PIN_INT 0
|
#define PIN_INT 0
|
||||||
@ -50,5 +50,3 @@
|
|||||||
|
|
||||||
#define PICO_DEFAULT_UART 1
|
#define PICO_DEFAULT_UART 1
|
||||||
#define PICO_DEFAULT_UART_TX_PIN 20
|
#define PICO_DEFAULT_UART_TX_PIN 20
|
||||||
|
|
||||||
//{ MP_ROM_QSTR(MP_QSTR_MIC), MP_ROM_PTR(&pin_GPIO27) },
|
|
||||||
|
4
etc/99-i2c_puppet.rules
Normal file
4
etc/99-i2c_puppet.rules
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# I2C Puppet devices
|
||||||
|
|
||||||
|
# BBQ10KBD
|
||||||
|
SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="b182", MODE:="0660", TAG+="uaccess"
|
Loading…
Reference in New Issue
Block a user