Skip to content

Instantly share code, notes, and snippets.

@loxK
Created December 24, 2010 04:12
Show Gist options
  • Select an option

  • Save loxK/753887 to your computer and use it in GitHub Desktop.

Select an option

Save loxK/753887 to your computer and use it in GitHub Desktop.
31a32
> #include <linux/capella_cm3602.h>
42c43
< #define MAX_NUM_SENSORS 5
---
> #define MAX_NUM_SENSORS 6
52c53,54
< #define ID_L (4)
---
> #define ID_P (4)
> #define ID_L (5)
58a61
> [ID_P] = SENSOR_TYPE_PROXIMITY,
62,66c65,72
< #define SENSORS_ACCELERATION (1<<ID_A)
< #define SENSORS_MAGNETIC_FIELD (1<<ID_M)
< #define SENSORS_ORIENTATION (1<<ID_O)
< #define SENSORS_TEMPERATURE (1<<ID_T)
< #define SENSORS_GROUP ((1<<ID_A)|(1<<ID_M)|(1<<ID_O)|(1<<ID_T))
---
> #define SENSORS_AKM_ACCELERATION (1<<ID_A)
> #define SENSORS_AKM_MAGNETIC_FIELD (1<<ID_M)
> #define SENSORS_AKM_ORIENTATION (1<<ID_O)
> #define SENSORS_AKM_TEMPERATURE (1<<ID_T)
> #define SENSORS_AKM_GROUP ((1<<ID_A)|(1<<ID_M)|(1<<ID_O)|(1<<ID_T))
>
> #define SENSORS_CM_PROXIMITY (1<<ID_P)
> #define SENSORS_CM_GROUP (1<<ID_P)
75a82
> int cmd_fd;
82c89
< int events_fd[2];
---
> int events_fd[3];
90a98,107
> /* the CM3602 is a binary proximity sensor that triggers around 9 cm on
> * this hardware */
> #define PROXIMITY_THRESHOLD_CM 9.0f
>
> /*
> * the AK8973 has a 8-bit ADC but the firmware seems to average 16 samples,
> * or at least makes its calibration on 12-bits values. This increases the
> * resolution by 4 bits.
> */
>
93c110
< "The Android Open Source Project",
---
> "Bosh",
95c112
< SENSOR_TYPE_ACCELEROMETER, 2.8f, 1.0f/4032.0f, 3.0f, { } },
---
> SENSOR_TYPE_ACCELEROMETER, 4.0f*9.81f, (4.0f*9.81f)/256.0f, 0.2f, { } },
97c114
< "The Android Open Source Project",
---
> "Asahi Kasei",
99c116
< SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f, 1.0f, 6.7f, { } },
---
> SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f, 1.0f/16.0f, 6.8f, { } },
101c118
< "The Android Open Source Project",
---
> "Asahi Kasei",
103,107c120,126
< SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, { } },
< { "AK8973 Temperature sensor",
< "The Android Open Source Project",
< 1, SENSORS_HANDLE_BASE+ID_T,
< SENSOR_TYPE_TEMPERATURE, 80.0f, 1.0f, 0.0f, { } },
---
> SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 7.0f, { } },
> { "CM3602 Proximity sensor",
> "Capella Microsystems",
> 1, SENSORS_HANDLE_BASE+ID_P,
> SENSOR_TYPE_PROXIMITY,
> PROXIMITY_THRESHOLD_CM, PROXIMITY_THRESHOLD_CM,
> 0.5f, { } },
116,117d134
< 40.0,
< 90.0,
123a141,142
> 5800.0,
> 8000.0,
130,131c149,150
< static uint32_t sensors__get_sensors_list(struct sensors_module_t* module,
< struct sensor_t const** list)
---
> static int sensors__get_sensors_list(struct sensors_module_t* module,
> struct sensor_t const** list)
134c153
< return sizeof(sSensorList)/sizeof(sSensorList[0]);
---
> return ARRAY_SIZE(sSensorList);
147c166
< .name = "AK8973 & Light SENSORS Module",
---
> .name = "AK8973A & CM3602 Sensors Module",
156a176
> #define CM_DEVICE_NAME "/dev/cm3602"
158a179
>
176a198
> #define EVENT_TYPE_PROXIMITY ABS_DISTANCE
181a204
>
198c221
< static int open_inputs(int mode, int *akm_fd, int *l_fd)
---
> static int open_inputs(int mode, int *akm_fd, int *p_fd, int *l_fd)
213,214c236
< *akm_fd = *l_fd = -1;
<
---
> *akm_fd = *p_fd = -1;
230a253,256
> else if (!strcmp(name, "proximity")) {
> LOGV("using %s (name=%s)", devname, name);
> *p_fd = fd;
> }
245a272,275
> if (*p_fd < 0) {
> LOGE("Couldn't find or open 'proximity' driver (%s)", strerror(errno));
> fd = -1;
> }
255c285
< if (dev->akmd_fd <= 0) {
---
> if (dev->akmd_fd < 0) {
257c287
< //LOGD("%s, fd=%d", __PRETTY_FUNCTION__, dev->akmd_fd);
---
> LOGV("%s, fd=%d", __PRETTY_FUNCTION__, dev->akmd_fd);
261c291
< dev->active_sensors &= ~SENSORS_GROUP;
---
> dev->active_sensors &= ~SENSORS_AKM_GROUP;
269c299
< if (dev->akmd_fd > 0) {
---
> if (dev->akmd_fd >= 0) {
276c306
< static uint32_t read_sensors_state(int fd)
---
> static uint32_t read_akm_sensors_state(int fd)
278d307
< if (fd<0) return 0;
283,284c312,313
< if (flags) sensors |= SENSORS_ORIENTATION;
< else sensors &= ~SENSORS_ORIENTATION;
---
> if (flags) sensors |= SENSORS_AKM_ORIENTATION;
> else sensors &= ~SENSORS_AKM_ORIENTATION;
287,288c316,317
< if (flags) sensors |= SENSORS_ACCELERATION;
< else sensors &= ~SENSORS_ACCELERATION;
---
> if (flags) sensors |= SENSORS_AKM_ACCELERATION;
> else sensors &= ~SENSORS_AKM_ACCELERATION;
291,292c320,321
< if (flags) sensors |= SENSORS_TEMPERATURE;
< else sensors &= ~SENSORS_TEMPERATURE;
---
> if (flags) sensors |= SENSORS_AKM_TEMPERATURE;
> else sensors &= ~SENSORS_AKM_TEMPERATURE;
295,296c324,325
< if (flags) sensors |= SENSORS_MAGNETIC_FIELD;
< else sensors &= ~SENSORS_MAGNETIC_FIELD;
---
> if (flags) sensors |= SENSORS_AKM_MAGNETIC_FIELD;
> else sensors &= ~SENSORS_AKM_MAGNETIC_FIELD;
301c330
< static uint32_t enable_disable(struct sensors_control_context_t *dev,
---
> static uint32_t enable_disable_akm(struct sensors_control_context_t *dev,
312c341
< sensors, read_sensors_state(fd));
---
> sensors, read_akm_sensors_state(fd));
315,316c344,345
< if (mask & SENSORS_ORIENTATION) {
< flags = (sensors & SENSORS_ORIENTATION) ? 1 : 0;
---
> if (mask & SENSORS_AKM_ORIENTATION) {
> flags = (sensors & SENSORS_AKM_ORIENTATION) ? 1 : 0;
321,322c350,351
< if (mask & SENSORS_ACCELERATION) {
< flags = (sensors & SENSORS_ACCELERATION) ? 1 : 0;
---
> if (mask & SENSORS_AKM_ACCELERATION) {
> flags = (sensors & SENSORS_AKM_ACCELERATION) ? 1 : 0;
327,328c356,357
< if (mask & SENSORS_TEMPERATURE) {
< flags = (sensors & SENSORS_TEMPERATURE) ? 1 : 0;
---
> if (mask & SENSORS_AKM_TEMPERATURE) {
> flags = (sensors & SENSORS_AKM_TEMPERATURE) ? 1 : 0;
333,334c362,363
< if (mask & SENSORS_MAGNETIC_FIELD) {
< flags = (sensors & SENSORS_MAGNETIC_FIELD) ? 1 : 0;
---
> if (mask & SENSORS_AKM_MAGNETIC_FIELD) {
> flags = (sensors & SENSORS_AKM_MAGNETIC_FIELD) ? 1 : 0;
340c369
< now_active_akm_sensors = read_sensors_state(fd);
---
> now_active_akm_sensors = read_akm_sensors_state(fd);
350a380,405
> static uint32_t read_cm_sensors_state(int fd)
> {
> int flags;
> uint32_t sensors = 0;
> // read the actual value of all sensors
> if (!ioctl(fd, CAPELLA_CM3602_IOCTL_GET_ENABLED, &flags)) {
> if (flags) sensors |= SENSORS_CM_PROXIMITY;
> else sensors &= ~SENSORS_CM_PROXIMITY;
> }
>
> return sensors;
> }
>
> static int open_cm(struct sensors_control_context_t* dev)
> {
> if (dev->cmd_fd < 0) {
> dev->cmd_fd = open(CM_DEVICE_NAME, O_RDONLY);
> LOGV("%s, fd=%d", __PRETTY_FUNCTION__, dev->cmd_fd);
> LOGE_IF(dev->cmd_fd<0, "Couldn't open %s (%s)",
> CM_DEVICE_NAME, strerror(errno));
> if (dev->cmd_fd >= 0) {
> dev->active_sensors &= ~SENSORS_CM_GROUP;
> }
> }
> return dev->cmd_fd;
> }
351a407,444
> static void close_cm(struct sensors_control_context_t* dev)
> {
> if (dev->cmd_fd >= 0) {
> LOGV("%s, fd=%d", __PRETTY_FUNCTION__, dev->cmd_fd);
> close(dev->cmd_fd);
> dev->cmd_fd = -1;
> }
> }
>
> static int enable_disable_cm(struct sensors_control_context_t *dev,
> uint32_t active, uint32_t sensors, uint32_t mask)
> {
> int rc = 0;
> uint32_t now_active_cm_sensors;
> int fd = open_cm(dev);
>
> if (fd < 0) {
> LOGE("Couldn't open %s (%s)", CM_DEVICE_NAME, strerror(errno));
> return 0;
> }
>
> LOGV("(before) cm sensors = %08x, real = %08x",
> sensors, read_cm_sensors_state(fd));
>
> if (mask & SENSORS_CM_PROXIMITY) {
> int flags = (sensors & SENSORS_CM_PROXIMITY) ? 1 : 0;
> rc = ioctl(fd, CAPELLA_CM3602_IOCTL_ENABLE, &flags);
> if (rc < 0)
> LOGE("CAPELLA_CM3602_IOCTL_ENABLE error (%s)", strerror(errno));
> }
>
> now_active_cm_sensors = read_cm_sensors_state(fd);
>
> LOGV("(after) cm sensors = %08x, real = %08x",
> sensors, now_active_cm_sensors);
>
> return now_active_cm_sensors;
> }
424,427c517,520
< int akm_fd, l_fd;
<
< if (open_inputs(O_RDONLY, &akm_fd, &l_fd) < 0 ||
< akm_fd < 0 || l_fd < 0) {
---
> int akm_fd, p_fd, l_fd;
>
> if (open_inputs(O_RDONLY, &akm_fd, &p_fd, &l_fd) < 0 ||
> akm_fd < 0 || p_fd < 0 || l_fd < 0) {
431c524
< handle = native_handle_create(2, 0);
---
> handle = native_handle_create(3, 0);
433c526,528
< handle->data[1] = l_fd;
---
> handle->data[1] = p_fd;
> handle->data[2] = l_fd;
>
457,460c552,559
< enable_disable(dev,
< active & SENSORS_GROUP,
< new_sensors & SENSORS_GROUP,
< changed & SENSORS_GROUP) |
---
> enable_disable_akm(dev,
> active & SENSORS_AKM_GROUP,
> new_sensors & SENSORS_AKM_GROUP,
> changed & SENSORS_AKM_GROUP) |
> enable_disable_cm(dev,
> active & SENSORS_CM_GROUP,
> new_sensors & SENSORS_CM_GROUP,
> changed & SENSORS_CM_GROUP) |
489,491c588,590
< int akm_fd, l_fd;
< if (open_inputs(O_RDWR, &akm_fd, &l_fd) < 0 ||
< akm_fd < 0 || l_fd < 0) {
---
> int akm_fd, p_fd, l_fd;
> if (open_inputs(O_RDWR, &akm_fd, &p_fd, &l_fd) < 0 ||
> akm_fd < 0 || p_fd < 0 || l_fd < 0) {
494c593
<
---
>
504a604,608
> err = write(p_fd, event, sizeof(event));
> LOGV_IF(err<0, "control__wake(proximity), fd=%d (%s)",
> p_fd, strerror(errno));
> close(p_fd);
>
531a636
> dev->sensors[ID_P].sensor = SENSOR_TYPE_PROXIMITY;
535a641
> dev->events_fd[2] = dup(handle->data[2]);
537c643,644
< LOGV("data__data_open: light fd = %d", handle->data[1]);
---
> LOGV("data__data_open: proximity fd = %d", handle->data[1]);
> LOGV("data__data_open: light fd = %d", handle->data[2]);
542c649,659
<
---
> if (!ioctl(dev->events_fd[1], EVIOCGABS(ABS_DISTANCE), &absinfo)) {
> LOGV("proximity sensor initial value %d\n", absinfo.value);
> dev->pendingSensors |= SENSORS_CM_PROXIMITY;
> // FIXME: we should save here absinfo.{minimum, maximum, etc}
> // and use them to scale the return value according to
> // the sensor description.
> dev->sensors[ID_P].distance = (float)absinfo.value;
> }
> else LOGE("Cannot get proximity sensor initial value: %s\n",
> strerror(errno));
>
557a675,679
> if (dev->events_fd[2] >= 0) {
> //LOGV("(data close) about to close light fd=%d", dev->events_fd[1]);
> close(dev->events_fd[2]);
> dev->events_fd[2] = -1;
> }
571,572c693,695
< values->sensor = (1<<i);
< LOGD_IF(0, "%d [%f, %f, %f]", (1<<i),
---
> values->sensor = id_to_sensor[i];
> LOGV_IF(0, "%d [%f, %f, %f]",
> values->sensor,
579,581c702,703
< LOGE("No sensor to return!!! pendingSensors=%08x", dev->pendingSensors);
< // we may end-up in a busy loop, slow things down, just in case.
< usleep(10000);
---
>
> LOGE("no sensor to return: pendingSensors = %08x", dev->pendingSensors);
583a706
>
595c718
< new_sensors |= SENSORS_ACCELERATION;
---
> new_sensors |= SENSORS_AKM_ACCELERATION;
599c722
< new_sensors |= SENSORS_ACCELERATION;
---
> new_sensors |= SENSORS_AKM_ACCELERATION;
603c726
< new_sensors |= SENSORS_ACCELERATION;
---
> new_sensors |= SENSORS_AKM_ACCELERATION;
607c730
< new_sensors |= SENSORS_MAGNETIC_FIELD;
---
> new_sensors |= SENSORS_AKM_MAGNETIC_FIELD;
611c734
< new_sensors |= SENSORS_MAGNETIC_FIELD;
---
> new_sensors |= SENSORS_AKM_MAGNETIC_FIELD;
615c738
< new_sensors |= SENSORS_MAGNETIC_FIELD;
---
> new_sensors |= SENSORS_AKM_MAGNETIC_FIELD;
619c742
< new_sensors |= SENSORS_ORIENTATION;
---
> new_sensors |= SENSORS_AKM_ORIENTATION;
623c746
< new_sensors |= SENSORS_ORIENTATION;
---
> new_sensors |= SENSORS_AKM_ORIENTATION;
627c750
< new_sensors |= SENSORS_ORIENTATION;
---
> new_sensors |= SENSORS_AKM_ORIENTATION;
631c754
< new_sensors |= SENSORS_TEMPERATURE;
---
> new_sensors |= SENSORS_AKM_TEMPERATURE;
655a779,796
> static uint32_t data__poll_process_cm_abs(struct sensors_data_context_t *dev,
> int fd __attribute__((unused)),
> struct input_event *event)
> {
> uint32_t new_sensors = 0;
> if (event->type == EV_ABS) {
> LOGV("proximity type: %d code: %d value: %-5d time: %ds",
> event->type, event->code, event->value,
> (int)event->time.tv_sec);
> if (event->code == EVENT_TYPE_PROXIMITY) {
> new_sensors |= SENSORS_CM_PROXIMITY;
> /* event->value seems to be 0 or 1, scale it to the threshold */
> dev->sensors[ID_P].distance = event->value * PROXIMITY_THRESHOLD_CM;
> }
> }
> return new_sensors;
> }
>
666,675c807,811
< struct input_absinfo absinfo;
< int index;
< if (!ioctl(fd, EVIOCGABS(ABS_DISTANCE), &absinfo)) {
< index = event->value;
< if (index >= 0) {
< new_sensors |= SENSORS_LIGHT;
< if (index >= (int) ARRAY_SIZE(sLuxValues)) {
< index = (int) ARRAY_SIZE(sLuxValues) - 1;
< }
< dev->sensors[ID_L].light = sLuxValues[index];
---
> int index= event->value;
> if (index >= 0) {
> new_sensors |= SENSORS_LIGHT;
> if (index >= ARRAY_SIZE(sLuxValues)) {
> index = ARRAY_SIZE(sLuxValues) - 1;
676a813
> dev->sensors[ID_L].light = sLuxValues[index];
702c839,840
< int ls_fd = dev->events_fd[1];
---
> int cm_fd = dev->events_fd[1];
> int ls_fd = dev->events_fd[2];
708a847,851
> if (cm_fd < 0) {
> LOGE("invalid proximity-sensor file descriptor, fd=%d", cm_fd);
> return -1;
> }
>
733a877
> FD_SET(cm_fd, &rfds);
735c879
< n = select(__MAX(akm_fd, ls_fd) + 1, &rfds,
---
> n = select(__MAX(akm_fd, __MAX(cm_fd, ls_fd)) + 1, &rfds,
741c885
< akm_fd, ls_fd, strerror(errno));
---
> akm_fd, cm_fd, strerror(errno));
761a906,922
> if (FD_ISSET(cm_fd, &rfds)) {
> nread = read(cm_fd, &event, sizeof(event));
> if (nread == sizeof(event)) {
> new_sensors |= data__poll_process_cm_abs(dev, cm_fd, &event);
> LOGV("cm abs %08x", new_sensors);
> got_syn |= event.type == EV_SYN;
> exit |= got_syn && event.code == SYN_CONFIG;
> if (got_syn) {
> LOGV("cm syn %08x", new_sensors);
> data__poll_process_syn(dev, &event, new_sensors);
> new_sensors = 0;
> }
> }
> else LOGE("cm read too small %d", nread);
> }
> else LOGV("cm fd is not set");
>
794,795d954
<
<
803a963
> close_cm(ctx);
830a991
> dev->cmd_fd = -1;
846a1008
> dev->events_fd[2] = -1;
857a1020
>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment