Snap for 10648389 from 3d019b57c4dfe7b9b8b8a5bf1df69f3bfebcfa36 to android13-msm-pixelwatch-5.15-eos-release
Change-Id: Ic17463cff606451b4a1efd958b7534767443a679
diff --git a/bl_nxp.c b/bl_nxp.c
index b6433d2..de4c94a 100644
--- a/bl_nxp.c
+++ b/bl_nxp.c
@@ -151,29 +151,39 @@
int nanohub_bl_download_firmware(struct nanohub_data *data,
const uint8_t *buffer, uint32_t size)
{
- const uint32_t kSpOffset = 0;
- const uint32_t kPcOffset = 1;
- const uint32_t kLoadOffset = 13;
+
+ uint32_t firmware_size = size;
+ uint32_t firmware_offset = 0;
+
+ // Handle signed firmware
const uint32_t kSignedOffset = 0x1000;
const uint32_t kMagicOffset = 0x400;
const uint8_t kMagic[] = { 'C', 'H', 'R', 'E' };
- uint32_t *firmware;
- uint32_t ram_addr, stack_ptr, prgm_counter;
- int ret = 0;
-
- // Handle signed firmware
- if (size > kSignedOffset &&
+ if (firmware_size > kSignedOffset &&
memcmp(buffer + kMagicOffset, kMagic, sizeof(kMagic)) == 0) {
- buffer += kSignedOffset;
- size -= kSignedOffset;
+ firmware_offset = kSignedOffset;
+ firmware_size -= kSignedOffset;
}
- if (size < 64) {
+ if (firmware_size < 64) {
pr_err("nanohub: %s invalid size\n", __func__);
return -ETOOSMALL;
}
- firmware = (uint32_t *)buffer;
+ return nanohub_bl_download_firmware_buffer(
+ data, buffer + firmware_offset, firmware_size);
+}
+
+int nanohub_bl_download_firmware_buffer(struct nanohub_data *data,
+ const uint8_t *buffer,
+ uint32_t size) {
+ const uint32_t kSpOffset = 0;
+ const uint32_t kPcOffset = 1;
+ const uint32_t kLoadOffset = 13;
+ uint32_t ram_addr, stack_ptr, prgm_counter;
+ uint32_t *firmware = (uint32_t *)buffer;
+ int ret = 0;
+
ram_addr = firmware[kLoadOffset];
stack_ptr = firmware[kSpOffset];
prgm_counter = firmware[kPcOffset];
diff --git a/bl_nxp.h b/bl_nxp.h
index 35b733c..0ecc04c 100644
--- a/bl_nxp.h
+++ b/bl_nxp.h
@@ -46,6 +46,9 @@
int nanohub_bl_download_firmware(struct nanohub_data *, const uint8_t *firmware,
uint32_t size);
+int nanohub_bl_download_firmware_buffer(struct nanohub_data *,
+ const uint8_t *firmware,
+ uint32_t size);
#define BL_COMMAND_WRITE_MEMORY 0x04
#define BL_COMMAND_EXECUTE 0x09
diff --git a/display.c b/display.c
index 481860b..3593e99 100644
--- a/display.c
+++ b/display.c
@@ -13,6 +13,14 @@
*/
#include "main.h"
#include "display.h"
+#include "nanohub_exports.h"
+#include <asm-generic/errno.h>
+
+#define NANOHUB_DISPLAY_COMMAND_VERSION 0x01
+
+static DEFINE_MUTEX(nanohub_display_mutex);
+static DECLARE_COMPLETION(message_callback);
+static int display_state;
ssize_t nanohub_pin_display_select_get(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -36,3 +44,59 @@
}
return count;
}
+
+ssize_t nanohub_get_display_state(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int display_state = nanohub_query_display_state();
+ return scnprintf(buf, PAGE_SIZE, "%d", display_state);
+}
+
+#define NANOHUB_DISPLAY_COMMAND_TYPE_GET_STATE 0x06
+#define NANOHUB_DISPLAY_GET_STATE_TIMEOUT_MS 100
+
+static void on_message_received(const char *buffer, size_t length)
+{
+ if (length == 3 && buffer[0] == NANOHUB_DISPLAY_COMMAND_VERSION &&
+ buffer[1] == NANOHUB_DISPLAY_COMMAND_TYPE_GET_STATE) {
+ display_state = buffer[2];
+ }
+ complete(&message_callback);
+}
+
+int nanohub_query_display_state_internal(struct nanohub_data *data)
+{
+ const char message[] = { NANOHUB_DISPLAY_COMMAND_VERSION,
+ NANOHUB_DISPLAY_COMMAND_TYPE_GET_STATE };
+ long ret;
+ const struct nanohub_platform_data *pdata;
+
+ if (unlikely(data == NULL))
+ return -EINVAL;
+
+ pdata = data->pdata;
+ if (gpio_get_value(pdata->display_select_gpio) == 1)
+ return MCU_DISPLAY_NONE;
+
+ mutex_lock(&nanohub_display_mutex);
+
+ nanohub_register_listener(NANOHUB_DISPLAY_KERNEL_CHANNEL_ID, on_message_received);
+ reinit_completion(&message_callback);
+ display_state = -ENODATA;
+
+ nanohub_send_message(NANOHUB_DISPLAY_CHANNEL_ID, message, sizeof(message));
+
+ ret = wait_for_completion_interruptible_timeout(
+ &message_callback, msecs_to_jiffies(NANOHUB_DISPLAY_GET_STATE_TIMEOUT_MS));
+
+ nanohub_unregister_listener(NANOHUB_DISPLAY_KERNEL_CHANNEL_ID);
+
+ mutex_unlock(&nanohub_display_mutex);
+
+ if (ret < 0)
+ return ret;
+
+ if (ret == 0)
+ return -ETIMEDOUT;
+
+ return display_state;
+}
diff --git a/display.h b/display.h
index 3ca06a7..f48e589 100644
--- a/display.h
+++ b/display.h
@@ -23,4 +23,8 @@
struct device_attribute *attr,
const char *buf, size_t count);
+ssize_t nanohub_get_display_state(struct device *dev, struct device_attribute *attr, char *buf);
+
+int nanohub_query_display_state_internal(struct nanohub_data *data);
+
#endif
diff --git a/main.c b/main.c
index 2f72eef..92ff055 100644
--- a/main.c
+++ b/main.c
@@ -76,6 +76,13 @@
#define WAKEUP_ERR_CNT 4
#define BL_MAX_SPEED_HZ 1000000
+#define GPIO05_INT_SET_TYPE 0x00008C11
+#define GPIO05_INT_POLARITY_HIGH 0x00008C12
+#define GPIO05_INT_EN_SET 0x00008C15
+#define GPIO05_INT_EN_CLR 0x00008C16
+#define GPIO05_INT_MID_SEL 0x00008C1A
+#define GPIO05_OUTPUT_CTRL 0x00008C44
+
/**
* struct gpio_config - this is a binding between platform data and driver data
* @label: for diagnostics
@@ -117,12 +124,14 @@
static unsigned int nanohub_poll(struct file *, poll_table *);
static int nanohub_release(struct inode *, struct file *);
static int nanohub_hw_reset(struct nanohub_data *data, int boot_mode);
+static int nanohub_pmic_irq_config(struct regmap *pmic_regmap);
// Kernel client support.
static struct nanohub_data *priv_nanohub_data;
EXPORT_SYMBOL(nanohub_send_message);
EXPORT_SYMBOL(nanohub_register_listener);
EXPORT_SYMBOL(nanohub_unregister_listener);
+EXPORT_SYMBOL(nanohub_query_display_state);
static struct class *sensor_class;
static int major;
@@ -887,6 +896,24 @@
return ret;
}
+// Configure PM_GPIO_05 to function as PMIC_IRQ
+static int nanohub_pmic_irq_config(struct regmap *pmic_regmap)
+{
+ int ret;
+ // Command seqeuence provided by QCOM in Case #06209787
+ // GPIO05 kernel write permission enabled by gpar/529000
+ ret = regmap_write(pmic_regmap, GPIO05_INT_SET_TYPE, 0x1);
+ ret |= regmap_write(pmic_regmap, GPIO05_INT_POLARITY_HIGH, 0x1);
+ ret |= regmap_write(pmic_regmap, GPIO05_INT_EN_SET, 0x1);
+ ret |= regmap_write(pmic_regmap, GPIO05_INT_EN_CLR, 0x1);
+ ret |= regmap_write(pmic_regmap, GPIO05_OUTPUT_CTRL, 0x82);
+ if (ret) {
+ pr_warn("nanohob: a PMIC_IRQ write operation failed, ret=%x\n", ret);
+ }
+
+ return ret;
+}
+
static ssize_t nanohub_try_hw_reset(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1089,7 +1116,8 @@
struct nanohub_data *data = dev_get_drvdata(dev);
struct firmware_request *fw_request = &data->firmware_request;
char *fw_name = fw_request->fw_name;
- int ret;
+ uint32_t* fw_image_offset = &fw_request->fw_image_offset;
+ int i, ret;
if (atomic_cmpxchg(&fw_request->state, FW_IDLE, FW_PENDING) !=
FW_IDLE) {
@@ -1108,6 +1136,17 @@
fw_name[count - 1] = 0;
fw_name[count] = 0;
+ // Parse firmware name then firmware image offset which are expected
+ // to be separated by a space. Offset is optional.
+ *fw_image_offset = 0;
+ for (i = 0; i < strlen(fw_name); i++) {
+ if (fw_name[i] == ' ') {
+ ret = kstrtou32(fw_name + i + 1, 10, fw_image_offset);
+ fw_name[i] = 0;
+ break;
+ }
+ }
+
atomic_set(&fw_request->state, FW_REQUESTED);
nanohub_notify_thread(data);
wait_for_completion(&fw_request->fw_complete);
@@ -1130,6 +1169,8 @@
int ret;
pr_info("nanohub: firmware download: %s\n", fw_request->fw_name);
+ pr_info("nanohub: firmware image offset: %lu\n",
+ fw_request->fw_image_offset);
atomic_set(&fw_request->state, FW_IN_PROGRESS);
ret = request_firmware(&fw_entry, fw_request->fw_name, dev);
@@ -1147,8 +1188,14 @@
// FW download uses SERIAL_ISP mode 110.
__nanohub_hw_reset(data, 0b110);
- ret = nanohub_bl_download_firmware(data, fw_entry->data,
- fw_entry->size);
+ if (fw_request->fw_image_offset != 0) {
+ ret = nanohub_bl_download_firmware_buffer(
+ data, fw_entry->data + fw_request->fw_image_offset,
+ fw_entry->size - fw_request->fw_image_offset);
+ } else {
+ ret = nanohub_bl_download_firmware(data, fw_entry->data,
+ fw_entry->size);
+ }
mcu_wakeup_gpio_set_value(data, 1);
if (data->irq1)
@@ -1351,7 +1398,9 @@
__ATTR(boot0, 0660, nanohub_pin_boot0_get, nanohub_pin_boot0_set),
__ATTR(boot2, 0660, nanohub_pin_boot2_get, nanohub_pin_boot2_set),
#ifdef CONFIG_NANOHUB_DISPLAY
- __ATTR(display_select, 0660, nanohub_pin_display_select_get, nanohub_pin_display_select_set),
+ __ATTR(display_select, 0660, nanohub_pin_display_select_get,
+ nanohub_pin_display_select_set),
+ __ATTR(display_state, 0440, nanohub_get_display_state, NULL),
#endif
#ifdef CONFIG_NANOHUB_BL_ST
__ATTR(lock, 0220, NULL, nanohub_lock_bl),
@@ -1361,7 +1410,8 @@
__ATTR(firmware_name, 0440, nanohub_firmware_name_query, NULL),
__ATTR(download_firmware, 0220, NULL, nanohub_download_firmware_request),
#endif
- __ATTR(wakeup_event_msec, 0660, nanohub_wakeup_event_msec_get, nanohub_wakeup_event_msec_set),
+ __ATTR(wakeup_event_msec, 0660, nanohub_wakeup_event_msec_get,
+ nanohub_wakeup_event_msec_set),
};
static inline int nanohub_create_sensor(struct nanohub_data *data)
@@ -1399,18 +1449,21 @@
{
int i, j, k, ret;
static const struct device_config device_configs[] = {
- {"nanohub_comms", 1, false},
- {"nanohub", ID_NANOHUB_CLIENT_NUM_IDS, false},
- {"nanohub_audio", 1, true},
- {"nanohub_display", 1, false},
- {"nanohub_render", 1, false},
- {"nanohub_debug_log", 1, false},
- {"nanohub_metrics", 1, false},
- {"nanohub_console", 1, false},
- {"nanohub_rpc0", 1, false},
- {"nanohub_rpc1", 1, false},
- {"nanohub_brightness", 1, false},
+ { "nanohub_comms", 1, false },
+ { "nanohub", ID_NANOHUB_CLIENT_NUM_IDS, false },
+ { "nanohub_audio", 1, true },
+ { "nanohub_display", 1, false },
+ { "nanohub_render", 1, false },
+ { "nanohub_debug_log", 1, false },
+ { "nanohub_metrics", 1, false },
+ { "nanohub_console", 1, false },
+ { "nanohub_rpc0", 1, false },
+ { "nanohub_rpc1", 1, false },
+ { "nanohub_brightness", 1, false },
+ { "nanohub_touch", 1, true },
+ { "nanohub_display_kernel", 1, true },
};
+ static_assert(ARRAY_SIZE(device_configs) == ID_NANOHUB_MAX - ID_NANOHUB_CLIENT_NUM_IDS + 1);
for (i = 0, j = 0; j < ID_NANOHUB_MAX - ID_NANOHUB_CLIENT_NUM_IDS + 1; ++j) {
struct device *dev = NULL;
@@ -1571,6 +1624,15 @@
io->on_message_received = NULL;
}
+int nanohub_query_display_state(void)
+{
+#ifdef CONFIG_NANOHUB_DISPLAY
+ return nanohub_query_display_state_internal(priv_nanohub_data);
+#else
+ return -ENOSYS;
+#endif
+}
+
static unsigned int nanohub_poll(struct file *file, poll_table *wait)
{
struct nanohub_io *io = file->private_data;
@@ -1858,6 +1920,7 @@
uint32_t u, i;
#endif
int ret;
+ u32 val = 0;
if (!dt)
return ERR_PTR(-ENODEV);
@@ -1982,6 +2045,11 @@
goto free_pdata;
}
+ ret = of_property_read_u32(dt, "sensorhub,pmic_irq_enable", &val);
+ if (!ret && val) {
+ nanohub_pmic_irq_config(pdata->pmic_regmap);
+ }
+
#ifdef CONFIG_NANOHUB_BL_ST
/* optional (bl-max-frequency) */
pdata->bl_max_speed_hz = BL_MAX_SPEED_HZ;
diff --git a/main.h b/main.h
index b956343..a70fec3 100644
--- a/main.h
+++ b/main.h
@@ -66,6 +66,7 @@
#define FW_NAME_SIZE 64
struct firmware_request {
char fw_name[FW_NAME_SIZE];
+ uint32_t fw_image_offset;
atomic_t state;
int result;
struct completion fw_complete;
@@ -86,7 +87,9 @@
#define ID_NANOHUB_RPC0 22
#define ID_NANOHUB_RPC1 23
#define ID_NANOHUB_BRIGHTNESS 24
- #define ID_NANOHUB_MAX 25
+ #define ID_NANOHUB_TOUCH 25
+ #define ID_NANOHUB_DISPLAY_KERNEL 26
+ #define ID_NANOHUB_MAX 27
struct iio_dev *iio_dev;
struct nanohub_io io[ID_NANOHUB_MAX];
diff --git a/nanohub_exports.h b/nanohub_exports.h
index f09a8af..aab40c8 100644
--- a/nanohub_exports.h
+++ b/nanohub_exports.h
@@ -5,7 +5,7 @@
//
// Please add the exported symvers to your module's Makefile:
// all: (MAKE) -C $(KERNEL_SRC) M=$(M) modules ...
-// KBUILD_EXTRA_SYMBOLS="$(OUT_DIR)/../exynos-google-cw-extra/drivers/sensorhub/nanohub/Module.symvers"
+// KBUILD_EXTRA_SYMBOLS="$(OUT_DIR)/../google-modules/nanohub/Module.symvers"
//
// Your module will have a module dependency on nanohub.
@@ -19,6 +19,8 @@
#define NANOHUB_RPC0_CHANNEL_ID 22
#define NANOHUB_RPC1_CHANNEL_ID 23
#define NANOHUB_BRIGHTNESS_CHANNEL_ID 24
+#define NANOHUB_TOUCH_CHANNEL_ID 25
+#define NANOHUB_DISPLAY_KERNEL_CHANNEL_ID 26
/**
* Sends a message over a nanohub channel.
@@ -46,4 +48,24 @@
*/
extern void nanohub_unregister_listener(int channel_id);
+/**
+ * MCU display power state returned from nanohub_query_display_state
+ */
+enum mcu_display_mode {
+ MCU_DISPLAY_NONE = 0,
+ MCU_DISPLAY_INIT = 1,
+ MCU_DISPLAY_SLEEP = 2,
+ MCU_DISPLAY_OFF = 3,
+ MCU_DISPLAY_IDLE = 4,
+ MCU_DISPLAY_ON = 5,
+ MCU_DISPLAY_HIGH_BRIGHTNESS = 6,
+};
+
+/**
+ * Query the display power state from MCU when display is controlled by MCU.
+ * MCU_DISPLAY_NONE, when MCU doesn't control display.
+ */
+
+extern int nanohub_query_display_state(void);
+
#endif /* _NANOHUB_EXPORTS_H_ */