diff options
-rw-r--r-- | drivers/iio/light/gp2ap020a00f.c | 105 |
1 files changed, 71 insertions, 34 deletions
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index b1e4615b87e8..2a65bc34face 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c | |||
@@ -996,11 +996,10 @@ done: | |||
996 | return IRQ_HANDLED; | 996 | return IRQ_HANDLED; |
997 | } | 997 | } |
998 | 998 | ||
999 | static u8 gp2ap020a00f_get_reg_by_event_code(u64 event_code) | 999 | static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan, |
1000 | enum iio_event_direction event_dir) | ||
1000 | { | 1001 | { |
1001 | int event_dir = IIO_EVENT_CODE_EXTRACT_DIR(event_code); | 1002 | switch (chan->type) { |
1002 | |||
1003 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { | ||
1004 | case IIO_PROXIMITY: | 1003 | case IIO_PROXIMITY: |
1005 | if (event_dir == IIO_EV_DIR_RISING) | 1004 | if (event_dir == IIO_EV_DIR_RISING) |
1006 | return GP2AP020A00F_PH_L_REG; | 1005 | return GP2AP020A00F_PH_L_REG; |
@@ -1011,13 +1010,19 @@ static u8 gp2ap020a00f_get_reg_by_event_code(u64 event_code) | |||
1011 | return GP2AP020A00F_TH_L_REG; | 1010 | return GP2AP020A00F_TH_L_REG; |
1012 | else | 1011 | else |
1013 | return GP2AP020A00F_TL_L_REG; | 1012 | return GP2AP020A00F_TL_L_REG; |
1013 | default: | ||
1014 | break; | ||
1014 | } | 1015 | } |
1015 | 1016 | ||
1016 | return -EINVAL; | 1017 | return -EINVAL; |
1017 | } | 1018 | } |
1018 | 1019 | ||
1019 | static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev, | 1020 | static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev, |
1020 | u64 event_code, int val) | 1021 | const struct iio_chan_spec *chan, |
1022 | enum iio_event_type type, | ||
1023 | enum iio_event_direction dir, | ||
1024 | enum iio_event_info info, | ||
1025 | int val, int val2) | ||
1021 | { | 1026 | { |
1022 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); | 1027 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); |
1023 | bool event_en = false; | 1028 | bool event_en = false; |
@@ -1027,7 +1032,7 @@ static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev, | |||
1027 | 1032 | ||
1028 | mutex_lock(&data->lock); | 1033 | mutex_lock(&data->lock); |
1029 | 1034 | ||
1030 | thresh_reg_l = gp2ap020a00f_get_reg_by_event_code(event_code); | 1035 | thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir); |
1031 | thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l); | 1036 | thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l); |
1032 | 1037 | ||
1033 | if (thresh_val_id > GP2AP020A00F_THRESH_PH) { | 1038 | if (thresh_val_id > GP2AP020A00F_THRESH_PH) { |
@@ -1072,15 +1077,19 @@ error_unlock: | |||
1072 | } | 1077 | } |
1073 | 1078 | ||
1074 | static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev, | 1079 | static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev, |
1075 | u64 event_code, int *val) | 1080 | const struct iio_chan_spec *chan, |
1081 | enum iio_event_type type, | ||
1082 | enum iio_event_direction dir, | ||
1083 | enum iio_event_info info, | ||
1084 | int *val, int *val2) | ||
1076 | { | 1085 | { |
1077 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); | 1086 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); |
1078 | u8 thresh_reg_l; | 1087 | u8 thresh_reg_l; |
1079 | int err = 0; | 1088 | int err = IIO_VAL_INT; |
1080 | 1089 | ||
1081 | mutex_lock(&data->lock); | 1090 | mutex_lock(&data->lock); |
1082 | 1091 | ||
1083 | thresh_reg_l = gp2ap020a00f_get_reg_by_event_code(event_code); | 1092 | thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir); |
1084 | 1093 | ||
1085 | if (thresh_reg_l > GP2AP020A00F_PH_L_REG) { | 1094 | if (thresh_reg_l > GP2AP020A00F_PH_L_REG) { |
1086 | err = -EINVAL; | 1095 | err = -EINVAL; |
@@ -1096,7 +1105,7 @@ error_unlock: | |||
1096 | } | 1105 | } |
1097 | 1106 | ||
1098 | static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev, | 1107 | static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev, |
1099 | u64 event_code, int state) | 1108 | int state) |
1100 | { | 1109 | { |
1101 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); | 1110 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); |
1102 | enum gp2ap020a00f_cmd cmd_high_ev, cmd_low_ev; | 1111 | enum gp2ap020a00f_cmd cmd_high_ev, cmd_low_ev; |
@@ -1151,7 +1160,10 @@ static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev, | |||
1151 | } | 1160 | } |
1152 | 1161 | ||
1153 | static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, | 1162 | static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, |
1154 | u64 event_code, int state) | 1163 | const struct iio_chan_spec *chan, |
1164 | enum iio_event_type type, | ||
1165 | enum iio_event_direction dir, | ||
1166 | int state) | ||
1155 | { | 1167 | { |
1156 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); | 1168 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); |
1157 | enum gp2ap020a00f_cmd cmd; | 1169 | enum gp2ap020a00f_cmd cmd; |
@@ -1159,14 +1171,12 @@ static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, | |||
1159 | 1171 | ||
1160 | mutex_lock(&data->lock); | 1172 | mutex_lock(&data->lock); |
1161 | 1173 | ||
1162 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { | 1174 | switch (chan->type) { |
1163 | case IIO_PROXIMITY: | 1175 | case IIO_PROXIMITY: |
1164 | err = gp2ap020a00f_write_prox_event_config(indio_dev, | 1176 | err = gp2ap020a00f_write_prox_event_config(indio_dev, state); |
1165 | event_code, state); | ||
1166 | break; | 1177 | break; |
1167 | case IIO_LIGHT: | 1178 | case IIO_LIGHT: |
1168 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) | 1179 | if (dir == IIO_EV_DIR_RISING) { |
1169 | == IIO_EV_DIR_RISING) { | ||
1170 | cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN : | 1180 | cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN : |
1171 | GP2AP020A00F_CMD_ALS_HIGH_EV_DIS; | 1181 | GP2AP020A00F_CMD_ALS_HIGH_EV_DIS; |
1172 | err = gp2ap020a00f_exec_cmd(data, cmd); | 1182 | err = gp2ap020a00f_exec_cmd(data, cmd); |
@@ -1186,17 +1196,18 @@ static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, | |||
1186 | } | 1196 | } |
1187 | 1197 | ||
1188 | static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev, | 1198 | static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev, |
1189 | u64 event_code) | 1199 | const struct iio_chan_spec *chan, |
1200 | enum iio_event_type type, | ||
1201 | enum iio_event_direction dir) | ||
1190 | { | 1202 | { |
1191 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); | 1203 | struct gp2ap020a00f_data *data = iio_priv(indio_dev); |
1192 | int event_en = 0; | 1204 | int event_en = 0; |
1193 | 1205 | ||
1194 | mutex_lock(&data->lock); | 1206 | mutex_lock(&data->lock); |
1195 | 1207 | ||
1196 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { | 1208 | switch (chan->type) { |
1197 | case IIO_PROXIMITY: | 1209 | case IIO_PROXIMITY: |
1198 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) | 1210 | if (dir == IIO_EV_DIR_RISING) |
1199 | == IIO_EV_DIR_RISING) | ||
1200 | event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, | 1211 | event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, |
1201 | &data->flags); | 1212 | &data->flags); |
1202 | else | 1213 | else |
@@ -1204,14 +1215,16 @@ static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev, | |||
1204 | &data->flags); | 1215 | &data->flags); |
1205 | break; | 1216 | break; |
1206 | case IIO_LIGHT: | 1217 | case IIO_LIGHT: |
1207 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) | 1218 | if (dir == IIO_EV_DIR_RISING) |
1208 | == IIO_EV_DIR_RISING) | ||
1209 | event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, | 1219 | event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, |
1210 | &data->flags); | 1220 | &data->flags); |
1211 | else | 1221 | else |
1212 | event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, | 1222 | event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, |
1213 | &data->flags); | 1223 | &data->flags); |
1214 | break; | 1224 | break; |
1225 | default: | ||
1226 | event_en = -EINVAL; | ||
1227 | break; | ||
1215 | } | 1228 | } |
1216 | 1229 | ||
1217 | mutex_unlock(&data->lock); | 1230 | mutex_unlock(&data->lock); |
@@ -1292,6 +1305,34 @@ error_unlock: | |||
1292 | return err < 0 ? err : IIO_VAL_INT; | 1305 | return err < 0 ? err : IIO_VAL_INT; |
1293 | } | 1306 | } |
1294 | 1307 | ||
1308 | static const struct iio_event_spec gp2ap020a00f_event_spec_light[] = { | ||
1309 | { | ||
1310 | .type = IIO_EV_TYPE_THRESH, | ||
1311 | .dir = IIO_EV_DIR_RISING, | ||
1312 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | ||
1313 | BIT(IIO_EV_INFO_ENABLE), | ||
1314 | }, { | ||
1315 | .type = IIO_EV_TYPE_THRESH, | ||
1316 | .dir = IIO_EV_DIR_FALLING, | ||
1317 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | ||
1318 | BIT(IIO_EV_INFO_ENABLE), | ||
1319 | }, | ||
1320 | }; | ||
1321 | |||
1322 | static const struct iio_event_spec gp2ap020a00f_event_spec_prox[] = { | ||
1323 | { | ||
1324 | .type = IIO_EV_TYPE_ROC, | ||
1325 | .dir = IIO_EV_DIR_RISING, | ||
1326 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | ||
1327 | BIT(IIO_EV_INFO_ENABLE), | ||
1328 | }, { | ||
1329 | .type = IIO_EV_TYPE_ROC, | ||
1330 | .dir = IIO_EV_DIR_FALLING, | ||
1331 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | | ||
1332 | BIT(IIO_EV_INFO_ENABLE), | ||
1333 | }, | ||
1334 | }; | ||
1335 | |||
1295 | static const struct iio_chan_spec gp2ap020a00f_channels[] = { | 1336 | static const struct iio_chan_spec gp2ap020a00f_channels[] = { |
1296 | { | 1337 | { |
1297 | .type = IIO_LIGHT, | 1338 | .type = IIO_LIGHT, |
@@ -1307,10 +1348,8 @@ static const struct iio_chan_spec gp2ap020a00f_channels[] = { | |||
1307 | }, | 1348 | }, |
1308 | .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR, | 1349 | .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR, |
1309 | .address = GP2AP020A00F_D0_L_REG, | 1350 | .address = GP2AP020A00F_D0_L_REG, |
1310 | .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, | 1351 | .event_spec = gp2ap020a00f_event_spec_light, |
1311 | IIO_EV_DIR_RISING) | | 1352 | .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_light), |
1312 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, | ||
1313 | IIO_EV_DIR_FALLING), | ||
1314 | }, | 1353 | }, |
1315 | { | 1354 | { |
1316 | .type = IIO_LIGHT, | 1355 | .type = IIO_LIGHT, |
@@ -1340,20 +1379,18 @@ static const struct iio_chan_spec gp2ap020a00f_channels[] = { | |||
1340 | }, | 1379 | }, |
1341 | .scan_index = GP2AP020A00F_SCAN_MODE_PROXIMITY, | 1380 | .scan_index = GP2AP020A00F_SCAN_MODE_PROXIMITY, |
1342 | .address = GP2AP020A00F_D2_L_REG, | 1381 | .address = GP2AP020A00F_D2_L_REG, |
1343 | .event_mask = IIO_EV_BIT(IIO_EV_TYPE_ROC, | 1382 | .event_spec = gp2ap020a00f_event_spec_prox, |
1344 | IIO_EV_DIR_RISING) | | 1383 | .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_prox), |
1345 | IIO_EV_BIT(IIO_EV_TYPE_ROC, | ||
1346 | IIO_EV_DIR_FALLING), | ||
1347 | }, | 1384 | }, |
1348 | IIO_CHAN_SOFT_TIMESTAMP(GP2AP020A00F_CHAN_TIMESTAMP), | 1385 | IIO_CHAN_SOFT_TIMESTAMP(GP2AP020A00F_CHAN_TIMESTAMP), |
1349 | }; | 1386 | }; |
1350 | 1387 | ||
1351 | static const struct iio_info gp2ap020a00f_info = { | 1388 | static const struct iio_info gp2ap020a00f_info = { |
1352 | .read_raw = &gp2ap020a00f_read_raw, | 1389 | .read_raw = &gp2ap020a00f_read_raw, |
1353 | .read_event_value = &gp2ap020a00f_read_event_val, | 1390 | .read_event_value_new = &gp2ap020a00f_read_event_val, |
1354 | .read_event_config = &gp2ap020a00f_read_event_config, | 1391 | .read_event_config_new = &gp2ap020a00f_read_event_config, |
1355 | .write_event_value = &gp2ap020a00f_write_event_val, | 1392 | .write_event_value_new = &gp2ap020a00f_write_event_val, |
1356 | .write_event_config = &gp2ap020a00f_write_event_config, | 1393 | .write_event_config_new = &gp2ap020a00f_write_event_config, |
1357 | .driver_module = THIS_MODULE, | 1394 | .driver_module = THIS_MODULE, |
1358 | }; | 1395 | }; |
1359 | 1396 | ||