Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: light: vcnl4000: Prepare for more generic setup

In order to allow the chip_spec array reference the function pointers
for interrupts, the code for these functions need to be moved above the
chip_spec array.

This is a prestep to support a more generic setup of interrupts.

Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20230117190017.3789181-2-marten.lindahl@axis.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Mårten Lindahl and committed by
Jonathan Cameron
3a52d32a 3b5eea32

+128 -128
+128 -128
drivers/iio/light/vcnl4000.c
··· 887 887 return sprintf(buf, "%u\n", data->near_level); 888 888 } 889 889 890 + static irqreturn_t vcnl4010_irq_thread(int irq, void *p) 891 + { 892 + struct iio_dev *indio_dev = p; 893 + struct vcnl4000_data *data = iio_priv(indio_dev); 894 + unsigned long isr; 895 + int ret; 896 + 897 + ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 898 + if (ret < 0) 899 + goto end; 900 + 901 + isr = ret; 902 + 903 + if (isr & VCNL4010_INT_THR) { 904 + if (test_bit(VCNL4010_INT_THR_LOW, &isr)) { 905 + iio_push_event(indio_dev, 906 + IIO_UNMOD_EVENT_CODE( 907 + IIO_PROXIMITY, 908 + 1, 909 + IIO_EV_TYPE_THRESH, 910 + IIO_EV_DIR_FALLING), 911 + iio_get_time_ns(indio_dev)); 912 + } 913 + 914 + if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) { 915 + iio_push_event(indio_dev, 916 + IIO_UNMOD_EVENT_CODE( 917 + IIO_PROXIMITY, 918 + 1, 919 + IIO_EV_TYPE_THRESH, 920 + IIO_EV_DIR_RISING), 921 + iio_get_time_ns(indio_dev)); 922 + } 923 + 924 + i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 925 + isr & VCNL4010_INT_THR); 926 + } 927 + 928 + if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev)) 929 + iio_trigger_poll_chained(indio_dev->trig); 930 + 931 + end: 932 + return IRQ_HANDLED; 933 + } 934 + 935 + static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) 936 + { 937 + struct iio_poll_func *pf = p; 938 + struct iio_dev *indio_dev = pf->indio_dev; 939 + struct vcnl4000_data *data = iio_priv(indio_dev); 940 + const unsigned long *active_scan_mask = indio_dev->active_scan_mask; 941 + u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */ 942 + bool data_read = false; 943 + unsigned long isr; 944 + int val = 0; 945 + int ret; 946 + 947 + ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 948 + if (ret < 0) 949 + goto end; 950 + 951 + isr = ret; 952 + 953 + if (test_bit(0, active_scan_mask)) { 954 + if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) { 955 + ret = vcnl4000_read_data(data, 956 + VCNL4000_PS_RESULT_HI, 957 + &val); 958 + if (ret < 0) 959 + goto end; 960 + 961 + buffer[0] = val; 962 + data_read = true; 963 + } 964 + } 965 + 966 + ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 967 + isr & VCNL4010_INT_DRDY); 968 + if (ret < 0) 969 + goto end; 970 + 971 + if (!data_read) 972 + goto end; 973 + 974 + iio_push_to_buffers_with_timestamp(indio_dev, buffer, 975 + iio_get_time_ns(indio_dev)); 976 + 977 + end: 978 + iio_trigger_notify_done(indio_dev->trig); 979 + return IRQ_HANDLED; 980 + } 981 + 982 + static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev) 983 + { 984 + struct vcnl4000_data *data = iio_priv(indio_dev); 985 + int ret; 986 + int cmd; 987 + 988 + /* Do not enable the buffer if we are already capturing events. */ 989 + if (vcnl4010_is_in_periodic_mode(data)) 990 + return -EBUSY; 991 + 992 + ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 993 + VCNL4010_INT_PROX_EN); 994 + if (ret < 0) 995 + return ret; 996 + 997 + cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; 998 + return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd); 999 + } 1000 + 1001 + static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev) 1002 + { 1003 + struct vcnl4000_data *data = iio_priv(indio_dev); 1004 + int ret; 1005 + 1006 + ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0); 1007 + if (ret < 0) 1008 + return ret; 1009 + 1010 + return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0); 1011 + } 1012 + 1013 + static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = { 1014 + .postenable = &vcnl4010_buffer_postenable, 1015 + .predisable = &vcnl4010_buffer_predisable, 1016 + }; 1017 + 890 1018 static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = { 891 1019 { 892 1020 .name = "nearlevel", ··· 1156 1028 .info = &vcnl4000_info, 1157 1029 .irq_support = false, 1158 1030 }, 1159 - }; 1160 - 1161 - static irqreturn_t vcnl4010_irq_thread(int irq, void *p) 1162 - { 1163 - struct iio_dev *indio_dev = p; 1164 - struct vcnl4000_data *data = iio_priv(indio_dev); 1165 - unsigned long isr; 1166 - int ret; 1167 - 1168 - ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 1169 - if (ret < 0) 1170 - goto end; 1171 - 1172 - isr = ret; 1173 - 1174 - if (isr & VCNL4010_INT_THR) { 1175 - if (test_bit(VCNL4010_INT_THR_LOW, &isr)) { 1176 - iio_push_event(indio_dev, 1177 - IIO_UNMOD_EVENT_CODE( 1178 - IIO_PROXIMITY, 1179 - 1, 1180 - IIO_EV_TYPE_THRESH, 1181 - IIO_EV_DIR_FALLING), 1182 - iio_get_time_ns(indio_dev)); 1183 - } 1184 - 1185 - if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) { 1186 - iio_push_event(indio_dev, 1187 - IIO_UNMOD_EVENT_CODE( 1188 - IIO_PROXIMITY, 1189 - 1, 1190 - IIO_EV_TYPE_THRESH, 1191 - IIO_EV_DIR_RISING), 1192 - iio_get_time_ns(indio_dev)); 1193 - } 1194 - 1195 - i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 1196 - isr & VCNL4010_INT_THR); 1197 - } 1198 - 1199 - if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev)) 1200 - iio_trigger_poll_chained(indio_dev->trig); 1201 - 1202 - end: 1203 - return IRQ_HANDLED; 1204 - } 1205 - 1206 - static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) 1207 - { 1208 - struct iio_poll_func *pf = p; 1209 - struct iio_dev *indio_dev = pf->indio_dev; 1210 - struct vcnl4000_data *data = iio_priv(indio_dev); 1211 - const unsigned long *active_scan_mask = indio_dev->active_scan_mask; 1212 - u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */ 1213 - bool data_read = false; 1214 - unsigned long isr; 1215 - int val = 0; 1216 - int ret; 1217 - 1218 - ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 1219 - if (ret < 0) 1220 - goto end; 1221 - 1222 - isr = ret; 1223 - 1224 - if (test_bit(0, active_scan_mask)) { 1225 - if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) { 1226 - ret = vcnl4000_read_data(data, 1227 - VCNL4000_PS_RESULT_HI, 1228 - &val); 1229 - if (ret < 0) 1230 - goto end; 1231 - 1232 - buffer[0] = val; 1233 - data_read = true; 1234 - } 1235 - } 1236 - 1237 - ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 1238 - isr & VCNL4010_INT_DRDY); 1239 - if (ret < 0) 1240 - goto end; 1241 - 1242 - if (!data_read) 1243 - goto end; 1244 - 1245 - iio_push_to_buffers_with_timestamp(indio_dev, buffer, 1246 - iio_get_time_ns(indio_dev)); 1247 - 1248 - end: 1249 - iio_trigger_notify_done(indio_dev->trig); 1250 - return IRQ_HANDLED; 1251 - } 1252 - 1253 - static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev) 1254 - { 1255 - struct vcnl4000_data *data = iio_priv(indio_dev); 1256 - int ret; 1257 - int cmd; 1258 - 1259 - /* Do not enable the buffer if we are already capturing events. */ 1260 - if (vcnl4010_is_in_periodic_mode(data)) 1261 - return -EBUSY; 1262 - 1263 - ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 1264 - VCNL4010_INT_PROX_EN); 1265 - if (ret < 0) 1266 - return ret; 1267 - 1268 - cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; 1269 - return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd); 1270 - } 1271 - 1272 - static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev) 1273 - { 1274 - struct vcnl4000_data *data = iio_priv(indio_dev); 1275 - int ret; 1276 - 1277 - ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0); 1278 - if (ret < 0) 1279 - return ret; 1280 - 1281 - return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0); 1282 - } 1283 - 1284 - static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = { 1285 - .postenable = &vcnl4010_buffer_postenable, 1286 - .predisable = &vcnl4010_buffer_predisable, 1287 1031 }; 1288 1032 1289 1033 static const struct iio_trigger_ops vcnl4010_trigger_ops = {