From 85a43c3e8d0267a1681763ffea48ee100d7c2770 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 6 May 2013 00:04:01 -0400 Subject: [PATCH 1/2] Right Alt --> Fn key This applies a patch written by Dirk Hohndel to convert the right alt key to a Fn key. This allows functions such as Pg Up to be mapped to right alt + up. --- drivers/input/keyboard/atkbd.c | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 2626773ff29..1ff98b8525b 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -161,6 +161,19 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_KEY_UNKNOWN 0 #define ATKBD_KEY_NULL 255 +#define ATKBD_KEY_IGNORE 0x8000 +#define ATKBD_KEY_BS 0x0e +#define ATKBD_KEY_DEL 0x53 /* actually E0 53 - same for the rest here */ +#define ATKBD_KEY_ALT_R 0x38 +#define ATKBD_KEY_HOME 0x47 +#define ATKBD_KEY_UP 0x48 +#define ATKBD_KEY_PGUP 0x49 +#define ATKBD_KEY_LEFT 0x4b +#define ATKBD_KEY_RIGHT 0x4d +#define ATKBD_KEY_END 0x4f +#define ATKBD_KEY_DOWN 0x50 +#define ATKBD_KEY_PGDN 0x51 + #define ATKBD_SCR_1 0xfffe #define ATKBD_SCR_2 0xfffd #define ATKBD_SCR_4 0xfffc @@ -218,6 +231,7 @@ struct atkbd { bool softraw; bool scroll; bool enabled; + bool fake_fn; /* Accessed only from interrupt */ unsigned char emul; @@ -242,6 +256,7 @@ struct atkbd { static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); static void *atkbd_platform_fixup_data; static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); +static unsigned int (*atkbd_fake_fn_fixup)(struct atkbd *, unsigned int); static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)); @@ -398,6 +413,13 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (!atkbd->enabled) goto out; + if (atkbd_fake_fn_fixup) { + code = atkbd_fake_fn_fixup(atkbd, code); + if (code == ATKBD_KEY_IGNORE) + /* fake Fn key pressed - ignore */ + goto out; + } + input_event(dev, EV_MSC, MSC_RAW, code); if (atkbd_platform_scancode_fixup) @@ -987,6 +1009,48 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd, return code; } +/* + * Google Chromebook Pixel is lacking an Fn key. In order to use as + * a regular Linux laptop we steal the right Alt key and turn it into + * an Fn key + */ +static unsigned int atkbd_pixel_fake_fn_fixup(struct atkbd *atkbd, unsigned int code) +{ + if (atkbd->emul != 1) { + /* handle backspace here as it's the only one w/o + * a leading E0/E1 (i.e., emul == 0) */ + if (atkbd->emul == 0 && atkbd->fake_fn && (code & 0x7f) == ATKBD_KEY_BS) { + /* when pretending that Delete was pressed we need + * to set emul as well as Delete is E0 53 */ + atkbd->emul = 1; + code = (code & 0x80) | ATKBD_KEY_DEL; + } + } else if ((code & 0x7f) == ATKBD_KEY_ALT_R) { + atkbd->fake_fn = (code & 0x80) ? 0 : 1; + atkbd->emul = 0; + code = ATKBD_KEY_IGNORE; + } else if (atkbd->fake_fn) { + unsigned int oldcode = code; + switch(code & 0x7f) { + case ATKBD_KEY_UP: + code = ATKBD_KEY_PGUP; + break; + case ATKBD_KEY_DOWN: + code = ATKBD_KEY_PGDN; + break; + case ATKBD_KEY_LEFT: + code = ATKBD_KEY_HOME; + break; + case ATKBD_KEY_RIGHT: + code = ATKBD_KEY_END; + break; + } + code |= oldcode & 0x80; + } + return code; +} + + /* * atkbd_set_keycode_table() initializes keyboard's keycode table * according to the selected scancode set @@ -1638,6 +1702,13 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) return 1; } +static int __init atkbd_setup_fake_fn_fixup(const struct dmi_system_id *id) +{ + atkbd_fake_fn_fixup = id->driver_data; + + return 1; +} + static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { { .matches = { @@ -1775,6 +1846,15 @@ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { .callback = atkbd_setup_scancode_fixup, .driver_data = atkbd_oqo_01plus_scancode_fixup, }, + { + /* Google Chromebook Pixel */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Link"), + }, + .callback = atkbd_setup_fake_fn_fixup, + .driver_data = atkbd_pixel_fake_fn_fixup, + }, { } }; From 4361939af0fce0d6db7376290fd34542a312a1c6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 May 2013 23:27:08 -0400 Subject: [PATCH 2/2] Proximity Sensor and Keyboard Reversed Dirk Hohndel keyboard patch for now. I folded in patches to the proximity sensor that add features like IR sensing. Set CONFIG_SENSORS_ISL29018 in kernel config to compile the driver. The accompanying documentation explains where to find the device in sysfs. --- drivers/input/keyboard/atkbd.c | 80 ------------------- drivers/staging/iio/light/isl29018.c | 110 ++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 84 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 1ff98b8525b..2626773ff29 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -161,19 +161,6 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_KEY_UNKNOWN 0 #define ATKBD_KEY_NULL 255 -#define ATKBD_KEY_IGNORE 0x8000 -#define ATKBD_KEY_BS 0x0e -#define ATKBD_KEY_DEL 0x53 /* actually E0 53 - same for the rest here */ -#define ATKBD_KEY_ALT_R 0x38 -#define ATKBD_KEY_HOME 0x47 -#define ATKBD_KEY_UP 0x48 -#define ATKBD_KEY_PGUP 0x49 -#define ATKBD_KEY_LEFT 0x4b -#define ATKBD_KEY_RIGHT 0x4d -#define ATKBD_KEY_END 0x4f -#define ATKBD_KEY_DOWN 0x50 -#define ATKBD_KEY_PGDN 0x51 - #define ATKBD_SCR_1 0xfffe #define ATKBD_SCR_2 0xfffd #define ATKBD_SCR_4 0xfffc @@ -231,7 +218,6 @@ struct atkbd { bool softraw; bool scroll; bool enabled; - bool fake_fn; /* Accessed only from interrupt */ unsigned char emul; @@ -256,7 +242,6 @@ struct atkbd { static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); static void *atkbd_platform_fixup_data; static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); -static unsigned int (*atkbd_fake_fn_fixup)(struct atkbd *, unsigned int); static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)); @@ -413,13 +398,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (!atkbd->enabled) goto out; - if (atkbd_fake_fn_fixup) { - code = atkbd_fake_fn_fixup(atkbd, code); - if (code == ATKBD_KEY_IGNORE) - /* fake Fn key pressed - ignore */ - goto out; - } - input_event(dev, EV_MSC, MSC_RAW, code); if (atkbd_platform_scancode_fixup) @@ -1009,48 +987,6 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd, return code; } -/* - * Google Chromebook Pixel is lacking an Fn key. In order to use as - * a regular Linux laptop we steal the right Alt key and turn it into - * an Fn key - */ -static unsigned int atkbd_pixel_fake_fn_fixup(struct atkbd *atkbd, unsigned int code) -{ - if (atkbd->emul != 1) { - /* handle backspace here as it's the only one w/o - * a leading E0/E1 (i.e., emul == 0) */ - if (atkbd->emul == 0 && atkbd->fake_fn && (code & 0x7f) == ATKBD_KEY_BS) { - /* when pretending that Delete was pressed we need - * to set emul as well as Delete is E0 53 */ - atkbd->emul = 1; - code = (code & 0x80) | ATKBD_KEY_DEL; - } - } else if ((code & 0x7f) == ATKBD_KEY_ALT_R) { - atkbd->fake_fn = (code & 0x80) ? 0 : 1; - atkbd->emul = 0; - code = ATKBD_KEY_IGNORE; - } else if (atkbd->fake_fn) { - unsigned int oldcode = code; - switch(code & 0x7f) { - case ATKBD_KEY_UP: - code = ATKBD_KEY_PGUP; - break; - case ATKBD_KEY_DOWN: - code = ATKBD_KEY_PGDN; - break; - case ATKBD_KEY_LEFT: - code = ATKBD_KEY_HOME; - break; - case ATKBD_KEY_RIGHT: - code = ATKBD_KEY_END; - break; - } - code |= oldcode & 0x80; - } - return code; -} - - /* * atkbd_set_keycode_table() initializes keyboard's keycode table * according to the selected scancode set @@ -1702,13 +1638,6 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) return 1; } -static int __init atkbd_setup_fake_fn_fixup(const struct dmi_system_id *id) -{ - atkbd_fake_fn_fixup = id->driver_data; - - return 1; -} - static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { { .matches = { @@ -1846,15 +1775,6 @@ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { .callback = atkbd_setup_scancode_fixup, .driver_data = atkbd_oqo_01plus_scancode_fixup, }, - { - /* Google Chromebook Pixel */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), - DMI_MATCH(DMI_PRODUCT_NAME, "Link"), - }, - .callback = atkbd_setup_fake_fn_fixup, - .driver_data = atkbd_pixel_fake_fn_fixup, - }, { } }; diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 82478a59e42..5c07766e823 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -58,6 +58,10 @@ #define ISL29018_TEST_SHIFT 0 #define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT) +#define ISL29018_REG_TEST 0x08 +#define ISL29018_TEST_SHIFT 0 +#define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT) + struct isl29018_chip { struct device *dev; struct regmap *regmap; @@ -221,6 +225,95 @@ static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme, } /* Sysfs interface */ +/* lux_scale */ +static ssize_t show_lux_scale(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct isl29018_chip *chip = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", chip->lux_scale); +} + +static ssize_t store_lux_scale(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct isl29018_chip *chip = iio_priv(indio_dev); + unsigned long lval; + + lval = simple_strtoul(buf, NULL, 10); + if (lval == 0) + return -EINVAL; + + mutex_lock(&chip->lock); + chip->lux_scale = lval; + mutex_unlock(&chip->lock); + + return count; +} + +static ssize_t get_sensor_data(struct device *dev, char *buf, int mode) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct isl29018_chip *chip = iio_priv(indio_dev); + int value = 0; + int status; + + mutex_lock(&chip->lock); + switch (mode) { + case COMMMAND1_OPMODE_PROX_ONCE: + status = isl29018_read_proximity_ir(chip, + chip->prox_scheme, &value); + break; + + case COMMMAND1_OPMODE_ALS_ONCE: + status = isl29018_read_lux(chip, &value); + break; + + case COMMMAND1_OPMODE_IR_ONCE: + status = isl29018_read_ir(chip, &value); + break; + + default: + dev_err(dev, "Mode %d is not supported\n", mode); + mutex_unlock(&chip->lock); + return -EBUSY; + } + + if (status < 0) { + dev_err(dev, "Error in Reading data"); + mutex_unlock(&chip->lock); + return status; + } + + mutex_unlock(&chip->lock); + + return sprintf(buf, "%d\n", value); +} + + +/* Read lux */ +static ssize_t show_lux(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return get_sensor_data(dev, buf, COMMMAND1_OPMODE_ALS_ONCE); +} + +/* Read ir */ +static ssize_t show_ir(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return get_sensor_data(dev, buf, COMMMAND1_OPMODE_IR_ONCE); +} + +/* Read nearest ir */ +static ssize_t show_proxim_ir(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return get_sensor_data(dev, buf, COMMMAND1_OPMODE_PROX_ONCE); +} + /* range */ static ssize_t show_range(struct device *dev, struct device_attribute *attr, char *buf) @@ -412,17 +505,17 @@ static const struct iio_chan_spec isl29018_channels[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | - BIT(IIO_CHAN_INFO_CALIBSCALE), + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, }, { .type = IIO_INTENSITY, .modified = 1, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .channel2 = IIO_MOD_LIGHT_IR, }, { /* Unindexed in current ABI. But perhaps it should be. */ .type = IIO_PROXIMITY, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; @@ -435,6 +528,11 @@ static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_suppression, S_IRUGO | S_IWUSR, show_prox_infrared_suppression, store_prox_infrared_suppression, 0); +static IIO_DEVICE_ATTR(illuminance0_input, S_IRUGO, show_lux, NULL, 0); +static IIO_DEVICE_ATTR(illuminance0_calibscale, S_IRUGO | S_IWUSR, + show_lux_scale, store_lux_scale, 0); +static IIO_DEVICE_ATTR(intensity_infrared_raw, S_IRUGO, show_ir, NULL, 0); +static IIO_DEVICE_ATTR(proximity_raw, S_IRUGO, show_proxim_ir, NULL, 0); #define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) #define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) @@ -444,6 +542,10 @@ static struct attribute *isl29018_attributes[] = { ISL29018_DEV_ATTR(adc_resolution), ISL29018_CONST_ATTR(adc_resolution_available), ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_suppression), + ISL29018_DEV_ATTR(illuminance0_input), + ISL29018_DEV_ATTR(illuminance0_calibscale), + ISL29018_DEV_ATTR(intensity_infrared_raw), + ISL29018_DEV_ATTR(proximity_raw), NULL };