aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 14:30:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 14:30:39 -0500
commit46f7b635569731ff81a3b72d1bcd4415b293b637 (patch)
treee97e5e28d1768bb281116d92292851758ea20024
parent9682ec9692e5ac11c6caebd079324e727b19e7ce (diff)
parent533e80b1ea709577ec5cf73b8b566569bc711259 (diff)
Merge tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging drivers patches from Greg KH: "Here's the big staging driver tree update for 3.20-rc1. Lots of little things in here, adding up to lots of overall cleanups. The IIO driver updates are also in here as they cross the staging tree boundry a lot. I2O has moved into staging as well, as a plan to drop it from the tree eventually as that's a dead subsystem. All of this has been in linux-next with no reported issues for a while" * tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (740 commits) staging: lustre: lustre: libcfs: define symbols as static staging: rtl8712: Do coding style cleanup staging: lustre: make obd_updatemax_lock static staging: rtl8188eu: core: switch with redundant cases staging: rtl8188eu: odm: conditional setting with no effect staging: rtl8188eu: odm: condition with no effect staging: ft1000: fix braces warning staging: sm7xxfb: fix remaining CamelCase staging: sm7xxfb: fix CamelCase staging: rtl8723au: multiple condition with no effect - if identical to else staging: sm7xxfb: make smtc_scr_info static staging/lustre/mdc: Initialize req in mdc_enqueue for !it case staging/lustre/clio: Do not allow group locks with gid 0 staging/lustre/llite: don't add to page cache upon failure staging/lustre/llite: Add exception entry check after radix_tree staging/lustre/libcfs: protect kkuc_groups from write access staging/lustre/fld: refer to MDT0 for fld lookup in some cases staging/lustre/llite: Solve a race to access lli_has_smd in read case staging/lustre/ptlrpc: hold rq_lock when modify rq_flags staging/lustre/lnet: portal spreading rotor should be unsigned ...
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio200
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt1
-rw-r--r--Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt22
-rw-r--r--Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt129
-rw-r--r--Documentation/devicetree/bindings/iio/sensorhub.txt25
-rw-r--r--Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt4
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/driver-model/devres.txt2
-rw-r--r--MAINTAINERS20
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/iio/Kconfig1
-rw-r--r--drivers/iio/accel/Kconfig31
-rw-r--r--drivers/iio/accel/Makefile6
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c8
-rw-r--r--drivers/iio/accel/kxcjk-1013.c52
-rw-r--r--drivers/iio/accel/mma8452.c2
-rw-r--r--drivers/iio/accel/mma9551.c637
-rw-r--r--drivers/iio/accel/mma9551_core.c798
-rw-r--r--drivers/iio/accel/mma9551_core.h81
-rw-r--r--drivers/iio/accel/mma9553.c1334
-rw-r--r--drivers/iio/accel/ssp_accel_sensor.c169
-rw-r--r--drivers/iio/adc/Kconfig25
-rw-r--r--drivers/iio/adc/Makefile2
-rw-r--r--drivers/iio/adc/cc10001_adc.c423
-rw-r--r--drivers/iio/adc/qcom-spmi-vadc.c1016
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c11
-rw-r--r--drivers/iio/amplifiers/ad8366.c4
-rw-r--r--drivers/iio/common/Kconfig1
-rw-r--r--drivers/iio/common/Makefile1
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c75
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.h5
-rw-r--r--drivers/iio/common/ssp_sensors/Kconfig26
-rw-r--r--drivers/iio/common/ssp_sensors/Makefile8
-rw-r--r--drivers/iio/common/ssp_sensors/ssp.h257
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_dev.c712
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio.c107
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio_sensor.h71
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_spi.c608
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_spi.c2
-rw-r--r--drivers/iio/frequency/ad9523.c2
-rw-r--r--drivers/iio/frequency/adf4350.c7
-rw-r--r--drivers/iio/gyro/Makefile2
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c8
-rw-r--r--drivers/iio/gyro/ssp_gyro_sensor.c168
-rw-r--r--drivers/iio/iio_core.h9
-rw-r--r--drivers/iio/imu/Kconfig11
-rw-r--r--drivers/iio/imu/Makefile2
-rw-r--r--drivers/iio/imu/inv_mpu6050/Kconfig1
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_core.c124
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h6
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c39
-rw-r--r--drivers/iio/imu/kmx61.c1595
-rw-r--r--drivers/iio/industrialio-buffer.c410
-rw-r--r--drivers/iio/industrialio-core.c57
-rw-r--r--drivers/iio/industrialio-event.c15
-rw-r--r--drivers/iio/industrialio-triggered-buffer.c13
-rw-r--r--drivers/iio/inkern.c30
-rw-r--r--drivers/iio/kfifo_buf.c87
-rw-r--r--drivers/iio/light/Kconfig24
-rw-r--r--drivers/iio/light/Makefile2
-rw-r--r--drivers/iio/light/cm32181.c2
-rw-r--r--drivers/iio/light/cm3232.c403
-rw-r--r--drivers/iio/light/hid-sensor-als.c9
-rw-r--r--drivers/iio/light/hid-sensor-prox.c10
-rw-r--r--drivers/iio/light/jsa1212.c471
-rw-r--r--drivers/iio/light/lm3533-als.c2
-rw-r--r--drivers/iio/light/tcs3414.c4
-rw-r--r--drivers/iio/magnetometer/Kconfig15
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/ak09911.c326
-rw-r--r--drivers/iio/magnetometer/ak8975.c505
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c9
-rw-r--r--drivers/iio/orientation/hid-sensor-incl-3d.c9
-rw-r--r--drivers/iio/pressure/bmp280.c150
-rw-r--r--drivers/iio/pressure/hid-sensor-press.c9
-rw-r--r--drivers/iio/proximity/Kconfig17
-rw-r--r--drivers/iio/proximity/Makefile1
-rw-r--r--drivers/iio/proximity/as3935.c18
-rw-r--r--drivers/iio/proximity/sx9500.c752
-rw-r--r--drivers/iio/trigger/iio-trig-sysfs.c2
-rw-r--r--drivers/message/Makefile1
-rw-r--r--drivers/staging/Kconfig8
-rw-r--r--drivers/staging/Makefile4
-rw-r--r--drivers/staging/android/Kconfig26
-rw-r--r--drivers/staging/android/Makefile2
-rw-r--r--drivers/staging/android/alarm-dev.c446
-rw-r--r--drivers/staging/android/android_alarm.h41
-rw-r--r--drivers/staging/android/ashmem.c12
-rw-r--r--drivers/staging/android/ion/ion.c3
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c20
-rw-r--r--drivers/staging/android/ion/ion_heap.c2
-rw-r--r--drivers/staging/android/logger.c808
-rw-r--r--drivers/staging/android/logger.h89
-rw-r--r--drivers/staging/android/sync_debug.c3
-rw-r--r--drivers/staging/android/uapi/android_alarm.h62
-rw-r--r--drivers/staging/board/board.c3
-rw-r--r--drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c5
-rw-r--r--drivers/staging/comedi/Kconfig21
-rw-r--r--drivers/staging/comedi/comedi_compat32.c99
-rw-r--r--drivers/staging/comedi/comedi_compat32.h38
-rw-r--r--drivers/staging/comedi/comedi_fops.c467
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.c5
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.h55
-rw-r--r--drivers/staging/comedi/comedi_usb.c3
-rw-r--r--drivers/staging/comedi/comedi_usb.h50
-rw-r--r--drivers/staging/comedi/comedidev.h103
-rw-r--r--drivers/staging/comedi/drivers.c2
-rw-r--r--drivers/staging/comedi/drivers/8253.h92
-rw-r--r--drivers/staging/comedi/drivers/8255.c174
-rw-r--r--drivers/staging/comedi/drivers/8255.h32
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c65
-rw-r--r--drivers/staging/comedi/drivers/Makefile1
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c2365
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c78
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c844
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c3
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c3
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7x3x.c62
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c2
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c2
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c4
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c665
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c2
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1724.c2
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c240
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c5
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c124
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c10
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c1
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.c262
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.h116
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c2
-rw-r--r--drivers/staging/comedi/drivers/dac02.c2
-rw-r--r--drivers/staging/comedi/drivers/das08.c17
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c5
-rw-r--r--drivers/staging/comedi/drivers/das08_isa.c18
-rw-r--r--drivers/staging/comedi/drivers/das08_pci.c2
-rw-r--r--drivers/staging/comedi/drivers/das16.c469
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c2
-rw-r--r--drivers/staging/comedi/drivers/das1800.c340
-rw-r--r--drivers/staging/comedi/drivers/das6402.c4
-rw-r--r--drivers/staging/comedi/drivers/das800.c2
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c4
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c231
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c2
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c3
-rw-r--r--drivers/staging/comedi/drivers/dyna_pci10xx.c35
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c4
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c2
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h5
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c2
-rw-r--r--drivers/staging/comedi/drivers/me4000.c4
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c5
-rw-r--r--drivers/staging/comedi/drivers/mf6x4.c2
-rw-r--r--drivers/staging/comedi/drivers/mite.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c3
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c30
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c192
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c3
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c5
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c6
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c16
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h8
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_common.c55
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c15
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.c149
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.h23
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_pci.c7
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c7
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c9
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c4
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c43
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c43
-rw-r--r--drivers/staging/comedi/drivers/ni_usb6501.c3
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c6
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c12
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c7
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c19
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c258
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c240
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c422
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c3
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c2
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c2
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c3
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c12
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c16
-rw-r--r--drivers/staging/comedi/drivers/rti800.c3
-rw-r--r--drivers/staging/comedi/drivers/rti802.c2
-rw-r--r--drivers/staging/comedi/drivers/s626.c2
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c6
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c5
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c9
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c80
-rw-r--r--drivers/staging/comedi/drivers/z8536.h202
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c2
-rw-r--r--drivers/staging/comedi/range.c56
-rw-r--r--drivers/staging/cptm1217/Kconfig12
-rw-r--r--drivers/staging/cptm1217/Makefile2
-rw-r--r--drivers/staging/cptm1217/TODO5
-rw-r--r--drivers/staging/cptm1217/clearpad_tm1217.c665
-rw-r--r--drivers/staging/cptm1217/cp_tm1217.h8
-rw-r--r--drivers/staging/dgap/dgap.c38
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c40
-rw-r--r--drivers/staging/dgnc/dgnc_utils.c2
-rw-r--r--drivers/staging/dgnc/digi.h60
-rw-r--r--drivers/staging/dgnc/dpacompat.h12
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.c52
-rw-r--r--drivers/staging/fbtft/Kconfig169
-rw-r--r--drivers/staging/fbtft/Makefile34
-rw-r--r--drivers/staging/fbtft/README32
-rw-r--r--drivers/staging/fbtft/fb_agm1264k-fl.c462
-rw-r--r--drivers/staging/fbtft/fb_bd663474.c193
-rw-r--r--drivers/staging/fbtft/fb_hx8340bn.c229
-rw-r--r--drivers/staging/fbtft/fb_hx8347d.c181
-rw-r--r--drivers/staging/fbtft/fb_hx8353d.c166
-rw-r--r--drivers/staging/fbtft/fb_ili9320.c234
-rw-r--r--drivers/staging/fbtft/fb_ili9325.c291
-rw-r--r--drivers/staging/fbtft/fb_ili9340.c163
-rw-r--r--drivers/staging/fbtft/fb_ili9341.c179
-rw-r--r--drivers/staging/fbtft/fb_ili9481.c117
-rw-r--r--drivers/staging/fbtft/fb_ili9486.c121
-rw-r--r--drivers/staging/fbtft/fb_pcd8544.c177
-rw-r--r--drivers/staging/fbtft/fb_ra8875.c331
-rw-r--r--drivers/staging/fbtft/fb_s6d02a1.c168
-rw-r--r--drivers/staging/fbtft/fb_s6d1121.c208
-rw-r--r--drivers/staging/fbtft/fb_ssd1289.c206
-rw-r--r--drivers/staging/fbtft/fb_ssd1306.c229
-rw-r--r--drivers/staging/fbtft/fb_ssd1331.c205
-rw-r--r--drivers/staging/fbtft/fb_ssd1351.c258
-rw-r--r--drivers/staging/fbtft/fb_st7735r.c195
-rw-r--r--drivers/staging/fbtft/fb_tinylcd.c124
-rw-r--r--drivers/staging/fbtft/fb_tls8204.c176
-rw-r--r--drivers/staging/fbtft/fb_uc1701.c210
-rw-r--r--drivers/staging/fbtft/fb_upd161704.c206
-rw-r--r--drivers/staging/fbtft/fb_watterott.c324
-rw-r--r--drivers/staging/fbtft/fbtft-bus.c256
-rw-r--r--drivers/staging/fbtft/fbtft-core.c1521
-rw-r--r--drivers/staging/fbtft/fbtft-io.c239
-rw-r--r--drivers/staging/fbtft/fbtft-sysfs.c222
-rw-r--r--drivers/staging/fbtft/fbtft.h447
-rw-r--r--drivers/staging/fbtft/fbtft_device.c1444
-rw-r--r--drivers/staging/fbtft/flexfb.c592
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c111
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_hw.c8
-rw-r--r--drivers/staging/gdm724x/gdm_lte.c3
-rw-r--r--drivers/staging/gdm724x/gdm_mux.c2
-rw-r--r--drivers/staging/gs_fpgaboot/io.c9
-rw-r--r--drivers/staging/i2o/Kconfig (renamed from drivers/message/i2o/Kconfig)1
-rw-r--r--drivers/staging/i2o/Makefile (renamed from drivers/message/i2o/Makefile)0
-rw-r--r--drivers/staging/i2o/README (renamed from drivers/message/i2o/README)0
-rw-r--r--drivers/staging/i2o/README.ioctl (renamed from drivers/message/i2o/README.ioctl)0
-rw-r--r--drivers/staging/i2o/bus-osm.c (renamed from drivers/message/i2o/bus-osm.c)2
-rw-r--r--drivers/staging/i2o/config-osm.c (renamed from drivers/message/i2o/config-osm.c)2
-rw-r--r--drivers/staging/i2o/core.h (renamed from drivers/message/i2o/core.h)0
-rw-r--r--drivers/staging/i2o/debug.c (renamed from drivers/message/i2o/debug.c)2
-rw-r--r--drivers/staging/i2o/device.c (renamed from drivers/message/i2o/device.c)2
-rw-r--r--drivers/staging/i2o/driver.c (renamed from drivers/message/i2o/driver.c)2
-rw-r--r--drivers/staging/i2o/exec-osm.c (renamed from drivers/message/i2o/exec-osm.c)2
-rw-r--r--drivers/staging/i2o/i2o.h (renamed from include/linux/i2o.h)0
-rw-r--r--drivers/staging/i2o/i2o_block.c (renamed from drivers/message/i2o/i2o_block.c)2
-rw-r--r--drivers/staging/i2o/i2o_block.h (renamed from drivers/message/i2o/i2o_block.h)0
-rw-r--r--drivers/staging/i2o/i2o_config.c (renamed from drivers/message/i2o/i2o_config.c)0
-rw-r--r--drivers/staging/i2o/i2o_proc.c (renamed from drivers/message/i2o/i2o_proc.c)2
-rw-r--r--drivers/staging/i2o/i2o_scsi.c (renamed from drivers/message/i2o/i2o_scsi.c)2
-rw-r--r--drivers/staging/i2o/iop.c (renamed from drivers/message/i2o/iop.c)2
-rw-r--r--drivers/staging/i2o/memory.c (renamed from drivers/message/i2o/memory.c)2
-rw-r--r--drivers/staging/i2o/pci.c (renamed from drivers/message/i2o/pci.c)2
-rw-r--r--drivers/staging/iio/Documentation/iio_event_monitor.c23
-rw-r--r--drivers/staging/iio/Documentation/ring.txt8
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c13
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c2
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c45
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c29
-rw-r--r--drivers/staging/iio/adc/ad7192.c2
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c45
-rw-r--r--drivers/staging/iio/iio_dummy_evgen.c17
-rw-r--r--drivers/staging/iio/iio_dummy_evgen.h6
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c210
-rw-r--r--drivers/staging/iio/iio_simple_dummy.h13
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c12
-rw-r--r--drivers/staging/iio/iio_simple_dummy_events.c66
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c53
-rw-r--r--drivers/staging/iio/light/tsl2583.c2
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c2
-rw-r--r--drivers/staging/iio/meter/ade7758.h1
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c15
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c7
-rw-r--r--drivers/staging/iio/meter/ade7759.c2
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs.h3
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h28
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_private.h8
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-lnet.h36
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-types.h8
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c14
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h2
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c13
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c2
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h14
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c28
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c36
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-move.c49
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-ptl.c8
-rw-r--r--drivers/staging/lustre/lnet/lnet/lo.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/module.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/router.c40
-rw-r--r--drivers/staging/lustre/lnet/lnet/router_proc.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conctl.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.h2
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.c30
-rw-r--r--drivers/staging/lustre/lnet/selftest/framework.c4
-rw-r--r--drivers/staging/lustre/lnet/selftest/module.c50
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.c8
-rw-r--r--drivers/staging/lustre/lnet/selftest/selftest.h12
-rw-r--r--drivers/staging/lustre/lnet/selftest/timer.c2
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_request.c4
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_cache.c6
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_request.c11
-rw-r--r--drivers/staging/lustre/lustre/fld/lproc_fld.c16
-rw-r--r--drivers/staging/lustre/lustre/include/lclient.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lprocfs_status.h44
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_idl.h5
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fid.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fld.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_update.h189
-rw-r--r--drivers/staging/lustre/lustre/lclient/lcommon_cl.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_internal.h5
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_pool.c36
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_resource.c7
-rw-r--r--drivers/staging/lustre/lustre/libcfs/debug.c12
-rw-r--r--drivers/staging/lustre/lustre/libcfs/hash.c18
-rw-r--r--drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c4
-rw-r--r--drivers/staging/lustre/lustre/libcfs/libcfs_string.c16
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c7
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c24
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c4
-rw-r--r--drivers/staging/lustre/lustre/libcfs/module.c8
-rw-r--r--drivers/staging/lustre/lustre/libcfs/nidstrings.c233
-rw-r--r--drivers/staging/lustre/lustre/libcfs/tracefile.c3
-rw-r--r--drivers/staging/lustre/lustre/llite/dir.c11
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/lproc_llite.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/super25.c141
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_io.c15
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_lock.c1
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c87
-rw-r--r--drivers/staging/lustre/lustre/lmv/lproc_lmv.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lproc_lov.c20
-rw-r--r--drivers/staging/lustre/lustre/mdc/lproc_mdc.c9
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_lib.c7
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_locks.c1
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_request.c62
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_object.c5
-rw-r--r--drivers/staging/lustre/lustre/obdclass/class_obd.c2
-rw-r--r--drivers/staging/lustre/lustre/obdclass/genops.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-module.c31
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_swab.c5
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lprocfs_status.c26
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_mount.c5
-rw-r--r--drivers/staging/lustre/lustre/osc/lproc_osc.c77
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cache.c12
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_internal.h5
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_lock.c12
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_request.c2
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/client.c14
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/layout.c1
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c41
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c23
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_gc.c2
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe.c4
-rw-r--r--drivers/staging/mt29f_spinand/Kconfig2
-rw-r--r--drivers/staging/mt29f_spinand/mt29f_spinand.c17
-rw-r--r--drivers/staging/netlogic/xlr_net.c2
-rw-r--r--drivers/staging/nvec/nvec.c2
-rw-r--r--drivers/staging/octeon-usb/octeon-hcd.c2
-rw-r--r--drivers/staging/octeon/ethernet-rx.c2
-rw-r--r--drivers/staging/octeon/ethernet.c2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1.c2
-rw-r--r--drivers/staging/panel/panel.c104
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ap.c2
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c67
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_wlan_util.c7
-rw-r--r--drivers/staging/rtl8188eu/hal/odm.c22
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c36
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c14
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_service.h2
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_cmd.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_hal.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme_ext.h4
-rw-r--r--drivers/staging/rtl8188eu/include/usb_ops_linux.h1
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c27
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.c29
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.h2
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_dm.c4
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pm.c14
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pm.h2
-rw-r--r--drivers/staging/rtl8192e/rtl819x_HTProc.c4
-rw-r--r--drivers/staging/rtl8192e/rtllib_module.c4
-rw-r--r--drivers/staging/rtl8192e/rtllib_rx.c127
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c28
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c2
-rw-r--r--drivers/staging/rtl8192u/r8190_rtl8256.c2
-rw-r--r--drivers/staging/rtl8192u/r8192U_dm.c2309
-rw-r--r--drivers/staging/rtl8712/drv_types.h6
-rw-r--r--drivers/staging/rtl8712/osdep_service.h9
-rw-r--r--drivers/staging/rtl8712/recv_linux.c14
-rw-r--r--drivers/staging/rtl8712/recv_osdep.h1
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.h12
-rw-r--r--drivers/staging/rtl8712/rtl8712_event.h2
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.c525
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.h46
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.h22
-rw-r--r--drivers/staging/rtl8712/rtl871x_sta_mgt.c5
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.c2
-rw-r--r--drivers/staging/rtl8712/sta_info.h2
-rw-r--r--drivers/staging/rtl8712/usb_intf.c5
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ap.c10
-rw-r--r--drivers/staging/rtl8723au/core/rtw_cmd.c61
-rw-r--r--drivers/staging/rtl8723au/core/rtw_efuse.c32
-rw-r--r--drivers/staging/rtl8723au/core/rtw_xmit.c9
-rw-r--r--drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c8
-rw-r--r--drivers/staging/rtl8723au/hal/odm.c87
-rw-r--r--drivers/staging/rtl8723au/hal/odm_HWConfig.c8
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c62
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c35
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_xmit.c4
-rw-r--r--drivers/staging/rtl8723au/hal/usb_halinit.c14
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723APhyCfg.h55
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723PwrSeq.h46
-rw-r--r--drivers/staging/rtl8723au/include/osdep_intf.h3
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h177
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_recv.h4
-rw-r--r--drivers/staging/rtl8723au/include/rtw_cmd.h10
-rw-r--r--drivers/staging/rtl8723au/include/rtw_mlme_ext.h2
-rw-r--r--drivers/staging/rtl8723au/include/wifi.h14
-rw-r--r--drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c3
-rw-r--r--drivers/staging/rtl8723au/os_dep/os_intfs.c2
-rw-r--r--drivers/staging/rtl8723au/os_dep/usb_intf.c170
-rw-r--r--drivers/staging/rts5208/ms.c12
-rw-r--r--drivers/staging/rts5208/rtsx_transport.c12
-rw-r--r--drivers/staging/skein/skein_block.c17
-rw-r--r--drivers/staging/skein/skein_generic.c1
-rw-r--r--drivers/staging/sm7xxfb/Kconfig13
-rw-r--r--drivers/staging/sm7xxfb/Makefile1
-rw-r--r--drivers/staging/sm7xxfb/TODO12
-rw-r--r--drivers/staging/sm7xxfb/sm7xx.h779
-rw-r--r--drivers/staging/sm7xxfb/sm7xxfb.c1024
-rw-r--r--drivers/staging/speakup/i18n.h2
-rw-r--r--drivers/staging/speakup/kobjects.c2
-rw-r--r--drivers/staging/speakup/selection.c2
-rw-r--r--drivers/staging/speakup/synth.c6
-rw-r--r--drivers/staging/unisys/Kconfig1
-rw-r--r--drivers/staging/unisys/Makefile1
-rw-r--r--drivers/staging/unisys/channels/Kconfig10
-rw-r--r--drivers/staging/unisys/channels/Makefile11
-rw-r--r--drivers/staging/unisys/channels/channel.c219
-rw-r--r--drivers/staging/unisys/channels/chanstub.c75
-rw-r--r--drivers/staging/unisys/channels/chanstub.h23
-rw-r--r--drivers/staging/unisys/common-spar/include/version.h1
-rw-r--r--drivers/staging/unisys/include/timskmod.h4
-rw-r--r--drivers/staging/unisys/uislib/Kconfig2
-rw-r--r--drivers/staging/unisys/uislib/uislib.c755
-rw-r--r--drivers/staging/unisys/uislib/uisqueue.c215
-rw-r--r--drivers/staging/unisys/uislib/uisthread.c1
-rw-r--r--drivers/staging/unisys/uislib/uisutils.c99
-rw-r--r--drivers/staging/unisys/virthba/Kconfig2
-rw-r--r--drivers/staging/unisys/virthba/virthba.c353
-rw-r--r--drivers/staging/unisys/virtpci/virtpci.c61
-rw-r--r--drivers/staging/unisys/visorchannel/visorchannel.h69
-rw-r--r--drivers/staging/unisys/visorchannel/visorchannel_funcs.c206
-rw-r--r--drivers/staging/unisys/visorchipset/file.c122
-rw-r--r--drivers/staging/unisys/visorchipset/file.h3
-rw-r--r--drivers/staging/unisys/visorchipset/globals.h2
-rw-r--r--drivers/staging/unisys/visorchipset/testing.h43
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset.h55
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset_main.c5
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset_umode.h2
-rw-r--r--drivers/staging/unisys/visorutil/charqueue.c2
-rw-r--r--drivers/staging/unisys/visorutil/procobjecttree.c21
-rw-r--r--drivers/staging/vt6655/baseband.c343
-rw-r--r--drivers/staging/vt6655/baseband.h17
-rw-r--r--drivers/staging/vt6655/card.c9
-rw-r--r--drivers/staging/vt6655/channel.c18
-rw-r--r--drivers/staging/vt6655/channel.h2
-rw-r--r--drivers/staging/vt6655/device.h25
-rw-r--r--drivers/staging/vt6655/device_main.c172
-rw-r--r--drivers/staging/vt6655/dpc.c15
-rw-r--r--drivers/staging/vt6655/mac.c25
-rw-r--r--drivers/staging/vt6655/mac.h684
-rw-r--r--drivers/staging/vt6655/power.c26
-rw-r--r--drivers/staging/vt6655/rf.c27
-rw-r--r--drivers/staging/vt6655/rf.h8
-rw-r--r--drivers/staging/vt6655/rxtx.c3
-rw-r--r--drivers/staging/vt6655/upc.h8
-rw-r--r--drivers/staging/vt6656/card.c2
-rw-r--r--drivers/staging/vt6656/device.h6
-rw-r--r--drivers/staging/vt6656/dpc.h2
-rw-r--r--drivers/staging/vt6656/main_usb.c3
-rw-r--r--drivers/staging/vt6656/rxtx.c109
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h6
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c17
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c2
-rw-r--r--drivers/staging/wlan-ng/p80211req.c2
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h2
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c4
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c10
-rw-r--r--include/dt-bindings/iio/qcom,spmi-vadc.h119
-rw-r--r--include/linux/iio/buffer.h76
-rw-r--r--include/linux/iio/common/ssp_sensors.h82
-rw-r--r--include/linux/iio/consumer.h12
-rw-r--r--include/linux/iio/iio.h11
-rw-r--r--include/linux/iio/kfifo_buf.h5
-rw-r--r--include/linux/iio/types.h14
525 files changed, 31906 insertions, 15103 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 117521dbf2b3..9a70c31619ea 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -92,6 +92,18 @@ Description:
92 is required is a consistent labeling. Units after application 92 is required is a consistent labeling. Units after application
93 of scale and offset are millivolts. 93 of scale and offset are millivolts.
94 94
95What: /sys/bus/iio/devices/iio:deviceX/in_currentY_raw
96What: /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_raw
97KernelVersion: 3.17
98Contact: linux-iio@vger.kernel.org
99Description:
100 Raw (unscaled no bias removal etc.) current measurement from
101 channel Y. In special cases where the channel does not
102 correspond to externally available input one of the named
103 versions may be used. The number must always be specified and
104 unique to allow association with event codes. Units after
105 application of scale and offset are milliamps.
106
95What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw 107What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw
96KernelVersion: 3.2 108KernelVersion: 3.2
97Contact: linux-iio@vger.kernel.org 109Contact: linux-iio@vger.kernel.org
@@ -234,6 +246,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
234What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_offset 246What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_offset
235What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset 247What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset
236What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset 248What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset
249What: /sys/bus/iio/devices/iio:deviceX/in_currentY_offset
250What: /sys/bus/iio/devices/iio:deviceX/in_current_offset
237What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset 251What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
238What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset 252What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
239What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset 253What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
@@ -262,9 +276,14 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale
262What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_scale 276What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_scale
263What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale 277What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale
264What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale 278What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale
279What: /sys/bus/iio/devices/iio:deviceX/in_currentY_scale
280What: /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_scale
281What: /sys/bus/iio/devices/iio:deviceX/in_current_scale
265What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale 282What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale
266What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale 283What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale
267What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale 284What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale
285What: /sys/bus/iio/devices/iio:deviceX/in_energy_scale
286What: /sys/bus/iio/devices/iio:deviceX/in_distance_scale
268What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale 287What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale
269What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale 288What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
270What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale 289What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
@@ -276,6 +295,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
276What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale 295What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
277What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale 296What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
278What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_scale 297What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_scale
298What: /sys/bus/iio/devices/iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_scale
279KernelVersion: 2.6.35 299KernelVersion: 2.6.35
280Contact: linux-iio@vger.kernel.org 300Contact: linux-iio@vger.kernel.org
281Description: 301Description:
@@ -323,6 +343,44 @@ Description:
323 production inaccuracies). If shared across all channels, 343 production inaccuracies). If shared across all channels,
324 <type>_calibscale is used. 344 <type>_calibscale is used.
325 345
346What: /sys/bus/iio/devices/iio:deviceX/in_activity_calibgender
347What: /sys/bus/iio/devices/iio:deviceX/in_energy_calibgender
348What: /sys/bus/iio/devices/iio:deviceX/in_distance_calibgender
349What: /sys/bus/iio/devices/iio:deviceX/in_velocity_calibgender
350KernelVersion: 3.20
351Contact: linux-iio@vger.kernel.org
352Description:
353 Gender of the user (e.g.: male, female) used by some pedometers
354 to compute the stride length, distance, speed and activity
355 type.
356
357What: /sys/bus/iio/devices/iio:deviceX/in_activity_calibgender_available
358What: /sys/bus/iio/devices/iio:deviceX/in_energy_calibgender_available
359What: /sys/bus/iio/devices/iio:deviceX/in_distance_calibgender_available
360What: /sys/bus/iio/devices/iio:deviceX/in_velocity_calibgender_available
361KernelVersion: 3.20
362Contact: linux-iio@vger.kernel.org
363Description:
364 Lists all available gender values (e.g.: male, female).
365
366What: /sys/bus/iio/devices/iio:deviceX/in_activity_calibheight
367What: /sys/bus/iio/devices/iio:deviceX/in_energy_calibheight
368What: /sys/bus/iio/devices/iio:deviceX/in_distance_calibheight
369What: /sys/bus/iio/devices/iio:deviceX/in_velocity_calibheight
370KernelVersion: 3.19
371Contact: linux-iio@vger.kernel.org
372Description:
373 Height of the user (in meters) used by some pedometers
374 to compute the stride length, distance, speed and activity
375 type.
376
377What: /sys/bus/iio/devices/iio:deviceX/in_energy_calibweight
378KernelVersion: 3.20
379Contact: linux-iio@vger.kernel.org
380Description:
381 Weight of the user (in kg). It is needed by some pedometers
382 to compute the calories burnt by the user.
383
326What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available 384What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
327What: /sys/.../iio:deviceX/in_voltageX_scale_available 385What: /sys/.../iio:deviceX/in_voltageX_scale_available
328What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available 386What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
@@ -783,6 +841,14 @@ What: /sys/.../events/in_tempY_roc_falling_period
783What: /sys/.../events/in_accel_x&y&z_mag_falling_period 841What: /sys/.../events/in_accel_x&y&z_mag_falling_period
784What: /sys/.../events/in_intensity0_thresh_period 842What: /sys/.../events/in_intensity0_thresh_period
785What: /sys/.../events/in_proximity0_thresh_period 843What: /sys/.../events/in_proximity0_thresh_period
844What: /sys/.../events/in_activity_still_thresh_rising_period
845What: /sys/.../events/in_activity_still_thresh_falling_period
846What: /sys/.../events/in_activity_walking_thresh_rising_period
847What: /sys/.../events/in_activity_walking_thresh_falling_period
848What: /sys/.../events/in_activity_jogging_thresh_rising_period
849What: /sys/.../events/in_activity_jogging_thresh_falling_period
850What: /sys/.../events/in_activity_running_thresh_rising_period
851What: /sys/.../events/in_activity_running_thresh_falling_period
786KernelVersion: 2.6.37 852KernelVersion: 2.6.37
787Contact: linux-iio@vger.kernel.org 853Contact: linux-iio@vger.kernel.org
788Description: 854Description:
@@ -790,6 +856,40 @@ Description:
790 met before an event is generated. If direction is not 856 met before an event is generated. If direction is not
791 specified then this period applies to both directions. 857 specified then this period applies to both directions.
792 858
859What: /sys/.../events/in_activity_still_thresh_rising_en
860What: /sys/.../events/in_activity_still_thresh_falling_en
861What: /sys/.../events/in_activity_walking_thresh_rising_en
862What: /sys/.../events/in_activity_walking_thresh_falling_en
863What: /sys/.../events/in_activity_jogging_thresh_rising_en
864What: /sys/.../events/in_activity_jogging_thresh_falling_en
865What: /sys/.../events/in_activity_running_thresh_rising_en
866What: /sys/.../events/in_activity_running_thresh_falling_en
867KernelVersion: 3.19
868Contact: linux-iio@vger.kernel.org
869Description:
870 Enables or disables activitity events. Depending on direction
871 an event is generated when sensor ENTERS or LEAVES a given state.
872
873What: /sys/.../events/in_activity_still_thresh_rising_value
874What: /sys/.../events/in_activity_still_thresh_falling_value
875What: /sys/.../events/in_activity_walking_thresh_rising_value
876What: /sys/.../events/in_activity_walking_thresh_falling_value
877What: /sys/.../events/in_activity_jogging_thresh_rising_value
878What: /sys/.../events/in_activity_jogging_thresh_falling_value
879What: /sys/.../events/in_activity_running_thresh_rising_value
880What: /sys/.../events/in_activity_running_thresh_falling_value
881KernelVersion: 3.19
882Contact: linux-iio@vger.kernel.org
883Description:
884 Confidence value (in units as percentage) to be used
885 for deciding when an event should be generated. E.g for
886 running: If the confidence value reported by the sensor
887 is greater than in_activity_running_thresh_rising_value
888 then the sensor ENTERS running state. Conversely, if the
889 confidence value reported by the sensor is lower than
890 in_activity_running_thresh_falling_value then the sensor
891 is LEAVING running state.
892
793What: /sys/.../iio:deviceX/events/in_accel_mag_en 893What: /sys/.../iio:deviceX/events/in_accel_mag_en
794What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en 894What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en
795What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en 895What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en
@@ -822,6 +922,25 @@ Description:
822 number or direction is not specified, applies to all channels of 922 number or direction is not specified, applies to all channels of
823 this type. 923 this type.
824 924
925What: /sys/.../events/in_steps_change_en
926KernelVersion: 3.20
927Contact: linux-iio@vger.kernel.org
928Description:
929 Event generated when channel passes a threshold on the absolute
930 change in value. E.g. for steps: a step change event is
931 generated each time the user takes N steps, where N is set using
932 in_steps_change_value.
933
934What: /sys/.../events/in_steps_change_value
935KernelVersion: 3.20
936Contact: linux-iio@vger.kernel.org
937Description:
938 Specifies the value of change threshold that the
939 device is comparing against for the events enabled by
940 <type>[Y][_name]_roc[_rising|falling|]_en. E.g. for steps:
941 if set to 3, a step change event will be generated every 3
942 steps.
943
825What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger 944What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger
826KernelVersion: 2.6.35 945KernelVersion: 2.6.35
827Contact: linux-iio@vger.kernel.org 946Contact: linux-iio@vger.kernel.org
@@ -956,6 +1075,16 @@ Description:
956 and the relevant _type attributes to establish the data storage 1075 and the relevant _type attributes to establish the data storage
957 format. 1076 format.
958 1077
1078What: /sys/.../iio:deviceX/in_activity_still_input
1079What: /sys/.../iio:deviceX/in_activity_walking_input
1080What: /sys/.../iio:deviceX/in_activity_jogging_input
1081What: /sys/.../iio:deviceX/in_activity_running_input
1082KernelVersion: 3.19
1083Contact: linux-iio@vger.kernel.org
1084Description:
1085 This attribute is used to read the confidence for an activity
1086 expressed in units as percentage.
1087
959What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw 1088What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw
960KernelVersion: 2.6.38 1089KernelVersion: 2.6.38
961Contact: linux-iio@vger.kernel.org 1090Contact: linux-iio@vger.kernel.org
@@ -973,6 +1102,24 @@ Description:
973 For a list of available output power modes read 1102 For a list of available output power modes read
974 in_accel_power_mode_available. 1103 in_accel_power_mode_available.
975 1104
1105What: /sys/.../iio:deviceX/in_energy_input
1106What: /sys/.../iio:deviceX/in_energy_raw
1107KernelVersion: 3.20
1108Contact: linux-iio@vger.kernel.org
1109Description:
1110 This attribute is used to read the energy value reported by the
1111 device (e.g.: human activity sensors report energy burnt by the
1112 user). Units after application of scale are Joules.
1113
1114What: /sys/.../iio:deviceX/in_distance_input
1115What: /sys/.../iio:deviceX/in_distance_raw
1116KernelVersion: 3.20
1117Contact: linux-iio@vger.kernel.org
1118Description:
1119 This attribute is used to read the distance covered by the user
1120 since the last reboot while activated. Units after application
1121 of scale are meters.
1122
976What: /sys/bus/iio/devices/iio:deviceX/store_eeprom 1123What: /sys/bus/iio/devices/iio:deviceX/store_eeprom
977KernelVersion: 3.4.0 1124KernelVersion: 3.4.0
978Contact: linux-iio@vger.kernel.org 1125Contact: linux-iio@vger.kernel.org
@@ -992,7 +1139,9 @@ Description:
992 reflectivity of infrared or ultrasound emitted. 1139 reflectivity of infrared or ultrasound emitted.
993 Often these sensors are unit less and as such conversion 1140 Often these sensors are unit less and as such conversion
994 to SI units is not possible. Where it is, the units should 1141 to SI units is not possible. Where it is, the units should
995 be meters. 1142 be meters. If such a conversion is not possible, the reported
1143 values should behave in the same way as a distance, i.e. lower
1144 values indicate something is closer to the sensor.
996 1145
997What: /sys/.../iio:deviceX/in_illuminanceY_input 1146What: /sys/.../iio:deviceX/in_illuminanceY_input
998What: /sys/.../iio:deviceX/in_illuminanceY_raw 1147What: /sys/.../iio:deviceX/in_illuminanceY_raw
@@ -1024,6 +1173,12 @@ Description:
1024 This attribute is used to get/set the integration time in 1173 This attribute is used to get/set the integration time in
1025 seconds. 1174 seconds.
1026 1175
1176What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_integration_time
1177KernelVersion: 3.20
1178Contact: linux-iio@vger.kernel.org
1179Description:
1180 Number of seconds in which to compute speed.
1181
1027What: /sys/bus/iio/devices/iio:deviceX/in_rot_quaternion_raw 1182What: /sys/bus/iio/devices/iio:deviceX/in_rot_quaternion_raw
1028KernelVersion: 3.15 1183KernelVersion: 3.15
1029Contact: linux-iio@vger.kernel.org 1184Contact: linux-iio@vger.kernel.org
@@ -1051,3 +1206,46 @@ Description:
1051 after application of scale and offset. If no offset or scale is 1206 after application of scale and offset. If no offset or scale is
1052 present, output should be considered as processed with the 1207 present, output should be considered as processed with the
1053 unit in milliamps. 1208 unit in milliamps.
1209
1210What: /sys/.../iio:deviceX/in_energy_en
1211What: /sys/.../iio:deviceX/in_distance_en
1212What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_en
1213What: /sys/.../iio:deviceX/in_steps_en
1214KernelVersion: 3.19
1215Contact: linux-iio@vger.kernel.org
1216Description:
1217 Activates a device feature that runs in firmware/hardware.
1218 E.g. for steps: the pedometer saves power while not used;
1219 when activated, it will count the steps taken by the user in
1220 firmware and export them through in_steps_input.
1221
1222What: /sys/.../iio:deviceX/in_steps_input
1223KernelVersion: 3.19
1224Contact: linux-iio@vger.kernel.org
1225Description:
1226 This attribute is used to read the number of steps taken by the user
1227 since the last reboot while activated.
1228
1229What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_input
1230What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_raw
1231KernelVersion: 3.19
1232Contact: linux-iio@vger.kernel.org
1233Description:
1234 This attribute is used to read the current speed value of the
1235 user (which is the norm or magnitude of the velocity vector).
1236 Units after application of scale are m/s.
1237
1238What: /sys/.../iio:deviceX/in_steps_debounce_count
1239KernelVersion: 3.20
1240Contact: linux-iio@vger.kernel.org
1241Description:
1242 Specifies the number of steps that must occur within
1243 in_steps_filter_debounce_time for the pedometer to decide the
1244 consumer is making steps.
1245
1246What: /sys/.../iio:deviceX/in_steps_debounce_time
1247KernelVersion: 3.20
1248Contact: linux-iio@vger.kernel.org
1249Description:
1250 Specifies number of seconds in which we compute the steps
1251 that occur in order to decide if the consumer is making steps.
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index f9463b492f44..4dcd88d5f7ca 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -35,6 +35,7 @@ atmel,24c512 i2c serial eeprom (24cxx)
35atmel,24c1024 i2c serial eeprom (24cxx) 35atmel,24c1024 i2c serial eeprom (24cxx)
36atmel,at97sc3204t i2c trusted platform module (TPM) 36atmel,at97sc3204t i2c trusted platform module (TPM)
37capella,cm32181 CM32181: Ambient Light Sensor 37capella,cm32181 CM32181: Ambient Light Sensor
38capella,cm3232 CM3232: Ambient Light Sensor
38catalyst,24c32 i2c serial eeprom 39catalyst,24c32 i2c serial eeprom
39cirrus,cs42l51 Cirrus Logic CS42L51 audio codec 40cirrus,cs42l51 Cirrus Logic CS42L51 audio codec
40dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock 41dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock
diff --git a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
new file mode 100644
index 000000000000..904f76de9055
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
@@ -0,0 +1,22 @@
1* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC)
2
3Required properties:
4 - compatible: Should be "cosmic,10001-adc"
5 - reg: Should contain adc registers location and length.
6 - clock-names: Should contain "adc".
7 - clocks: Should contain a clock specifier for each entry in clock-names
8 - vref-supply: The regulator supply ADC reference voltage.
9
10Optional properties:
11 - adc-reserved-channels: Bitmask of reserved channels,
12 i.e. channels that cannot be used by the OS.
13
14Example:
15adc: adc@18101600 {
16 compatible = "cosmic,10001-adc";
17 reg = <0x18101600 0x24>;
18 adc-reserved-channels = <0x2>;
19 clocks = <&adc_clk>;
20 clock-names = "adc";
21 vref-supply = <&reg_1v8>;
22};
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
new file mode 100644
index 000000000000..0fb46137f936
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
@@ -0,0 +1,129 @@
1Qualcomm's SPMI PMIC voltage ADC
2
3SPMI PMIC voltage ADC (VADC) provides interface to clients to read
4voltage. The VADC is a 15-bit sigma-delta ADC.
5
6VADC node:
7
8- compatible:
9 Usage: required
10 Value type: <string>
11 Definition: Should contain "qcom,spmi-vadc".
12
13- reg:
14 Usage: required
15 Value type: <prop-encoded-array>
16 Definition: VADC base address and length in the SPMI PMIC register map.
17
18- #address-cells:
19 Usage: required
20 Value type: <u32>
21 Definition: Must be one. Child node 'reg' property should define ADC
22 channel number.
23
24- #size-cells:
25 Usage: required
26 Value type: <u32>
27 Definition: Must be zero.
28
29- #io-channel-cells:
30 Usage: required
31 Value type: <u32>
32 Definition: Must be one. For details about IIO bindings see:
33 Documentation/devicetree/bindings/iio/iio-bindings.txt
34
35- interrupts:
36 Usage: optional
37 Value type: <prop-encoded-array>
38 Definition: End of conversion interrupt.
39
40Channel node properties:
41
42- reg:
43 Usage: required
44 Value type: <u32>
45 Definition: ADC channel number.
46 See include/dt-bindings/iio/qcom,spmi-vadc.h
47
48- qcom,decimation:
49 Usage: optional
50 Value type: <u32>
51 Definition: This parameter is used to decrease ADC sampling rate.
52 Quicker measurements can be made by reducing decimation ratio.
53 Valid values are 512, 1024, 2048, 4096.
54 If property is not found, default value of 512 will be used.
55
56- qcom,pre-scaling:
57 Usage: optional
58 Value type: <u32 array>
59 Definition: Used for scaling the channel input signal before the signal is
60 fed to VADC. The configuration for this node is to know the
61 pre-determined ratio and use it for post scaling. Select one from
62 the following options.
63 <1 1>, <1 3>, <1 4>, <1 6>, <1 20>, <1 8>, <10 81>, <1 10>
64 If property is not found default value depending on chip will be used.
65
66- qcom,ratiometric:
67 Usage: optional
68 Value type: <empty>
69 Definition: Channel calibration type. If this property is specified
70 VADC will use the VDD reference (1.8V) and GND for channel
71 calibration. If property is not found, channel will be
72 calibrated with 0.625V and 1.25V reference channels, also
73 known as absolute calibration.
74
75- qcom,hw-settle-time:
76 Usage: optional
77 Value type: <u32>
78 Definition: Time between AMUX getting configured and the ADC starting
79 conversion. Delay = 100us * (value) for value < 11, and
80 2ms * (value - 10) otherwise.
81 Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800,
82 900 us and 1, 2, 4, 6, 8, 10 ms
83 If property is not found, channel will use 0us.
84
85- qcom,avg-samples:
86 Usage: optional
87 Value type: <u32>
88 Definition: Number of samples to be used for measurement.
89 Averaging provides the option to obtain a single measurement
90 from the ADC that is an average of multiple samples. The value
91 selected is 2^(value).
92 Valid values are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
93 If property is not found, 1 sample will be used.
94
95NOTE:
96
97Following channels, also known as reference point channels, are used for
98result calibration and their channel configuration nodes should be defined:
99VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
100VADC_GND_REF and VADC_VDD_VADC.
101
102Example:
103
104 /* VADC node */
105 pmic_vadc: vadc@3100 {
106 compatible = "qcom,spmi-vadc";
107 reg = <0x3100 0x100>;
108 interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
109 #address-cells = <1>;
110 #size-cells = <0>;
111 #io-channel-cells = <1>;
112 io-channel-ranges;
113
114 /* Channel node */
115 usb_id_nopull {
116 reg = <VADC_LR_MUX10_USB_ID>;
117 qcom,decimation = <512>;
118 qcom,ratiometric;
119 qcom,hw-settle-time = <200>;
120 qcom,avg-samples = <1>;
121 qcom,pre-scaling = <1 3>;
122 };
123 };
124
125 /* IIO client node */
126 usb {
127 io-channels = <&pmic_vadc VADC_LR_MUX10_USB_ID>;
128 io-channel-names = "vadc";
129 };
diff --git a/Documentation/devicetree/bindings/iio/sensorhub.txt b/Documentation/devicetree/bindings/iio/sensorhub.txt
new file mode 100644
index 000000000000..8d57571d5c0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/sensorhub.txt
@@ -0,0 +1,25 @@
1Samsung Sensorhub driver
2
3Sensorhub is a MCU which manages several sensors and also plays the role
4of a virtual sensor device.
5
6Required properties:
7- compatible: "samsung,sensorhub-rinato" or "samsung,sensorhub-thermostat"
8- spi-max-frequency: max SPI clock frequency
9- interrupt-parent: interrupt parent
10- interrupts: communication interrupt
11- ap-mcu-gpios: [out] ap to sensorhub line - used during communication
12- mcu-ap-gpios: [in] sensorhub to ap - used during communication
13- mcu-reset-gpios: [out] sensorhub reset
14
15Example:
16
17 shub_spi: shub {
18 compatible = "samsung,sensorhub-rinato";
19 spi-max-frequency = <5000000>;
20 interrupt-parent = <&gpx0>;
21 interrupts = <2 0>;
22 ap-mcu-gpios = <&gpx0 0 0>;
23 mcu-ap-gpios = <&gpx0 4 0>;
24 mcu-reset-gpios = <&gpx0 5 0>;
25 };
diff --git a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
index ee05dc390694..307537787574 100644
--- a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
+++ b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
@@ -12,9 +12,9 @@ Optional properties:
12 property is not present, then the touchscreen is 12 property is not present, then the touchscreen is
13 disabled. 5 wires is valid for i.MX28 SoC only. 13 disabled. 5 wires is valid for i.MX28 SoC only.
14- fsl,ave-ctrl: number of samples per direction to calculate an average value. 14- fsl,ave-ctrl: number of samples per direction to calculate an average value.
15 Allowed value is 1 ... 31, default is 4 15 Allowed value is 1 ... 32, default is 4
16- fsl,ave-delay: delay between consecutive samples. Allowed value is 16- fsl,ave-delay: delay between consecutive samples. Allowed value is
17 1 ... 2047. It is used if 'fsl,ave-ctrl' > 1, counts at 17 2 ... 2048. It is used if 'fsl,ave-ctrl' > 1, counts at
18 2 kHz and its default is 2 (= 1 ms) 18 2 kHz and its default is 2 (= 1 ms)
19- fsl,settling: delay between plate switch to next sample. Allowed value is 19- fsl,settling: delay between plate switch to next sample. Allowed value is
20 1 ... 2047. It counts at 2 kHz and its default is 20 1 ... 2047. It counts at 2 kHz and its default is
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 797e6b024241..1eb6444a48c4 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -38,6 +38,7 @@ chunghwa Chunghwa Picture Tubes Ltd.
38cirrus Cirrus Logic, Inc. 38cirrus Cirrus Logic, Inc.
39cnm Chips&Media, Inc. 39cnm Chips&Media, Inc.
40cortina Cortina Systems, Inc. 40cortina Cortina Systems, Inc.
41cosmic Cosmic Circuits
41crystalfontz Crystalfontz America, Inc. 42crystalfontz Crystalfontz America, Inc.
42dallas Maxim Integrated Products (formerly Dallas Semiconductor) 43dallas Maxim Integrated Products (formerly Dallas Semiconductor)
43davicom DAVICOM Semiconductor, Inc. 44davicom DAVICOM Semiconductor, Inc.
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index b5ab416cd53a..6d1e8eeb5990 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -258,6 +258,8 @@ IIO
258 devm_iio_device_free() 258 devm_iio_device_free()
259 devm_iio_device_register() 259 devm_iio_device_register()
260 devm_iio_device_unregister() 260 devm_iio_device_unregister()
261 devm_iio_kfifo_allocate()
262 devm_iio_kfifo_free()
261 devm_iio_trigger_alloc() 263 devm_iio_trigger_alloc()
262 devm_iio_trigger_free() 264 devm_iio_trigger_free()
263 265
diff --git a/MAINTAINERS b/MAINTAINERS
index 71a65389ca4d..348f5c16ef50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2399,6 +2399,12 @@ F: security/capability.c
2399F: security/commoncap.c 2399F: security/commoncap.c
2400F: kernel/capability.c 2400F: kernel/capability.c
2401 2401
2402CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
2403M: Kevin Tsai <ktsai@capellamicro.com>
2404S: Maintained
2405F: drivers/iio/light/cm*
2406F: Documentation/devicetree/bindings/i2c/trivial-devices.txt
2407
2402CC2520 IEEE-802.15.4 RADIO DRIVER 2408CC2520 IEEE-802.15.4 RADIO DRIVER
2403M: Varka Bhadram <varkabhadram@gmail.com> 2409M: Varka Bhadram <varkabhadram@gmail.com>
2404L: linux-wpan@vger.kernel.org 2410L: linux-wpan@vger.kernel.org
@@ -3904,6 +3910,12 @@ S: Supported
3904F: Documentation/fault-injection/ 3910F: Documentation/fault-injection/
3905F: lib/fault-inject.c 3911F: lib/fault-inject.c
3906 3912
3913FBTFT Framebuffer drivers
3914M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
3915M: Noralf Trønnes <noralf@tronnes.org>
3916S: Maintained
3917F: drivers/staging/fbtft/
3918
3907FCOE SUBSYSTEM (libfc, libfcoe, fcoe) 3919FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
3908M: Robert Love <robert.w.love@intel.com> 3920M: Robert Love <robert.w.love@intel.com>
3909L: fcoe-devel@open-fcoe.org 3921L: fcoe-devel@open-fcoe.org
@@ -9262,6 +9274,14 @@ L: linux-wireless@vger.kernel.org
9262S: Maintained 9274S: Maintained
9263F: drivers/staging/rtl8723au/ 9275F: drivers/staging/rtl8723au/
9264 9276
9277STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
9278M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
9279M: Teddy Wang <teddy.wang@siliconmotion.com>
9280M: Sudip Mukherjee <sudip@vectorindia.org>
9281L: linux-fbdev@vger.kernel.org
9282S: Maintained
9283F: drivers/staging/sm7xxfb/
9284
9265STAGING - SLICOSS 9285STAGING - SLICOSS
9266M: Lior Dotan <liodot@gmail.com> 9286M: Lior Dotan <liodot@gmail.com>
9267M: Christopher Harrer <charrer@alacritech.com> 9287M: Christopher Harrer <charrer@alacritech.com>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c70d6e45dc10..c0cc96bab9e7 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -36,8 +36,6 @@ source "drivers/message/fusion/Kconfig"
36 36
37source "drivers/firewire/Kconfig" 37source "drivers/firewire/Kconfig"
38 38
39source "drivers/message/i2o/Kconfig"
40
41source "drivers/macintosh/Kconfig" 39source "drivers/macintosh/Kconfig"
42 40
43source "drivers/net/Kconfig" 41source "drivers/net/Kconfig"
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 345395e9dc6e..4132935dc929 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -27,7 +27,6 @@ boolean "IIO callback buffer used for push in-kernel interfaces"
27 usage. That is, those where the data is pushed to the consumer. 27 usage. That is, those where the data is pushed to the consumer.
28 28
29config IIO_KFIFO_BUF 29config IIO_KFIFO_BUF
30 select IIO_TRIGGER
31 tristate "Industrial I/O buffering based on kfifo" 30 tristate "Industrial I/O buffering based on kfifo"
32 help 31 help
33 A simple fifo based on kfifo. Note that this currently provides 32 A simple fifo based on kfifo. Note that this currently provides
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 9b9be8725e9d..7c9a9a94a8ce 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -43,6 +43,9 @@ config HID_SENSOR_ACCEL_3D
43 Say yes here to build support for the HID SENSOR 43 Say yes here to build support for the HID SENSOR
44 accelerometers 3D. 44 accelerometers 3D.
45 45
46 To compile this driver as a module, choose M here: the
47 module will be called hid-sensor-accel-3d.
48
46config IIO_ST_ACCEL_3AXIS 49config IIO_ST_ACCEL_3AXIS
47 tristate "STMicroelectronics accelerometers 3-Axis Driver" 50 tristate "STMicroelectronics accelerometers 3-Axis Driver"
48 depends on (I2C || SPI_MASTER) && SYSFS 51 depends on (I2C || SPI_MASTER) && SYSFS
@@ -80,6 +83,9 @@ config KXSD9
80 Say yes here to build support for the Kionix KXSD9 accelerometer. 83 Say yes here to build support for the Kionix KXSD9 accelerometer.
81 Currently this only supports the device via an SPI interface. 84 Currently this only supports the device via an SPI interface.
82 85
86 To compile this driver as a module, choose M here: the module
87 will be called kxsd9.
88
83config MMA8452 89config MMA8452
84 tristate "Freescale MMA8452Q Accelerometer Driver" 90 tristate "Freescale MMA8452Q Accelerometer Driver"
85 depends on I2C 91 depends on I2C
@@ -105,4 +111,29 @@ config KXCJK1013
105 To compile this driver as a module, choose M here: the module will 111 To compile this driver as a module, choose M here: the module will
106 be called kxcjk-1013. 112 be called kxcjk-1013.
107 113
114config MMA9551_CORE
115 tristate
116
117config MMA9551
118 tristate "Freescale MMA9551L Intelligent Motion-Sensing Platform Driver"
119 depends on I2C
120 select MMA9551_CORE
121
122 help
123 Say yes here to build support for the Freescale MMA9551L
124 Intelligent Motion-Sensing Platform Driver.
125
126 To compile this driver as a module, choose M here: the module
127 will be called mma9551.
128
129config MMA9553
130 tristate "Freescale MMA9553L Intelligent Pedometer Platform Driver"
131 depends on I2C
132 select MMA9551_CORE
133 help
134 Say yes here to build support for the Freescale MMA9553L
135 Intelligent Pedometer Platform Driver.
136
137 To compile this driver as a module, choose M here: the module
138 will be called mma9553.
108endmenu 139endmenu
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index a593996c6539..99d89e46cad1 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -10,6 +10,12 @@ obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
10obj-$(CONFIG_KXSD9) += kxsd9.o 10obj-$(CONFIG_KXSD9) += kxsd9.o
11obj-$(CONFIG_MMA8452) += mma8452.o 11obj-$(CONFIG_MMA8452) += mma8452.o
12 12
13obj-$(CONFIG_MMA9551_CORE) += mma9551_core.o
14obj-$(CONFIG_MMA9551) += mma9551.o
15obj-$(CONFIG_MMA9553) += mma9553.o
16
17obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_accel_sensor.o
18
13obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o 19obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
14st_accel-y := st_accel_core.o 20st_accel-y := st_accel_core.o
15st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o 21st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index d5d95317003a..df6a593bd4bd 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -111,19 +111,12 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
111 int report_id = -1; 111 int report_id = -1;
112 u32 address; 112 u32 address;
113 int ret_type; 113 int ret_type;
114 s32 poll_value;
115 114
116 *val = 0; 115 *val = 0;
117 *val2 = 0; 116 *val2 = 0;
118 switch (mask) { 117 switch (mask) {
119 case 0: 118 case 0:
120 poll_value = hid_sensor_read_poll_value(
121 &accel_state->common_attributes);
122 if (poll_value < 0)
123 return -EINVAL;
124
125 hid_sensor_power_state(&accel_state->common_attributes, true); 119 hid_sensor_power_state(&accel_state->common_attributes, true);
126 msleep_interruptible(poll_value * 2);
127 report_id = accel_state->accel[chan->scan_index].report_id; 120 report_id = accel_state->accel[chan->scan_index].report_id;
128 address = accel_3d_addresses[chan->scan_index]; 121 address = accel_3d_addresses[chan->scan_index];
129 if (report_id >= 0) 122 if (report_id >= 0)
@@ -419,6 +412,7 @@ static struct platform_driver hid_accel_3d_platform_driver = {
419 .id_table = hid_accel_3d_ids, 412 .id_table = hid_accel_3d_ids,
420 .driver = { 413 .driver = {
421 .name = KBUILD_MODNAME, 414 .name = KBUILD_MODNAME,
415 .pm = &hid_sensor_pm_ops,
422 }, 416 },
423 .probe = hid_accel_3d_probe, 417 .probe = hid_accel_3d_probe,
424 .remove = hid_accel_3d_remove, 418 .remove = hid_accel_3d_remove,
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index da2fe93739a2..567de269cc00 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -108,6 +108,7 @@ struct kxcjk1013_data {
108 bool motion_trigger_on; 108 bool motion_trigger_on;
109 int64_t timestamp; 109 int64_t timestamp;
110 enum kx_chipset chipset; 110 enum kx_chipset chipset;
111 bool is_smo8500_device;
111}; 112};
112 113
113enum kxcjk1013_axis { 114enum kxcjk1013_axis {
@@ -377,6 +378,7 @@ static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
377 378
378static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on) 379static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
379{ 380{
381#ifdef CONFIG_PM
380 int ret; 382 int ret;
381 383
382 if (on) 384 if (on)
@@ -388,8 +390,11 @@ static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
388 if (ret < 0) { 390 if (ret < 0) {
389 dev_err(&data->client->dev, 391 dev_err(&data->client->dev,
390 "Failed: kxcjk1013_set_power_state for %d\n", on); 392 "Failed: kxcjk1013_set_power_state for %d\n", on);
393 if (on)
394 pm_runtime_put_noidle(&data->client->dev);
391 return ret; 395 return ret;
392 } 396 }
397#endif
393 398
394 return 0; 399 return 0;
395} 400}
@@ -858,6 +863,8 @@ static int kxcjk1013_write_event_config(struct iio_dev *indio_dev,
858 863
859 ret = kxcjk1013_setup_any_motion_interrupt(data, state); 864 ret = kxcjk1013_setup_any_motion_interrupt(data, state);
860 if (ret < 0) { 865 if (ret < 0) {
866 kxcjk1013_set_power_state(data, false);
867 data->ev_enable_state = 0;
861 mutex_unlock(&data->mutex); 868 mutex_unlock(&data->mutex);
862 return ret; 869 return ret;
863 } 870 }
@@ -1008,6 +1015,7 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
1008 else 1015 else
1009 ret = kxcjk1013_setup_new_data_interrupt(data, state); 1016 ret = kxcjk1013_setup_new_data_interrupt(data, state);
1010 if (ret < 0) { 1017 if (ret < 0) {
1018 kxcjk1013_set_power_state(data, false);
1011 mutex_unlock(&data->mutex); 1019 mutex_unlock(&data->mutex);
1012 return ret; 1020 return ret;
1013 } 1021 }
@@ -1131,12 +1139,16 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)
1131} 1139}
1132 1140
1133static const char *kxcjk1013_match_acpi_device(struct device *dev, 1141static const char *kxcjk1013_match_acpi_device(struct device *dev,
1134 enum kx_chipset *chipset) 1142 enum kx_chipset *chipset,
1143 bool *is_smo8500_device)
1135{ 1144{
1136 const struct acpi_device_id *id; 1145 const struct acpi_device_id *id;
1146
1137 id = acpi_match_device(dev->driver->acpi_match_table, dev); 1147 id = acpi_match_device(dev->driver->acpi_match_table, dev);
1138 if (!id) 1148 if (!id)
1139 return NULL; 1149 return NULL;
1150 if (strcmp(id->id, "SMO8500") == 0)
1151 *is_smo8500_device = true;
1140 *chipset = (enum kx_chipset)id->driver_data; 1152 *chipset = (enum kx_chipset)id->driver_data;
1141 1153
1142 return dev_name(dev); 1154 return dev_name(dev);
@@ -1151,6 +1163,8 @@ static int kxcjk1013_gpio_probe(struct i2c_client *client,
1151 1163
1152 if (!client) 1164 if (!client)
1153 return -EINVAL; 1165 return -EINVAL;
1166 if (data->is_smo8500_device)
1167 return -ENOTSUPP;
1154 1168
1155 dev = &client->dev; 1169 dev = &client->dev;
1156 1170
@@ -1200,7 +1214,8 @@ static int kxcjk1013_probe(struct i2c_client *client,
1200 name = id->name; 1214 name = id->name;
1201 } else if (ACPI_HANDLE(&client->dev)) { 1215 } else if (ACPI_HANDLE(&client->dev)) {
1202 name = kxcjk1013_match_acpi_device(&client->dev, 1216 name = kxcjk1013_match_acpi_device(&client->dev,
1203 &data->chipset); 1217 &data->chipset,
1218 &data->is_smo8500_device);
1204 } else 1219 } else
1205 return -ENODEV; 1220 return -ENODEV;
1206 1221
@@ -1228,21 +1243,25 @@ static int kxcjk1013_probe(struct i2c_client *client,
1228 KXCJK1013_IRQ_NAME, 1243 KXCJK1013_IRQ_NAME,
1229 indio_dev); 1244 indio_dev);
1230 if (ret) 1245 if (ret)
1231 return ret; 1246 goto err_poweroff;
1232 1247
1233 data->dready_trig = devm_iio_trigger_alloc(&client->dev, 1248 data->dready_trig = devm_iio_trigger_alloc(&client->dev,
1234 "%s-dev%d", 1249 "%s-dev%d",
1235 indio_dev->name, 1250 indio_dev->name,
1236 indio_dev->id); 1251 indio_dev->id);
1237 if (!data->dready_trig) 1252 if (!data->dready_trig) {
1238 return -ENOMEM; 1253 ret = -ENOMEM;
1254 goto err_poweroff;
1255 }
1239 1256
1240 data->motion_trig = devm_iio_trigger_alloc(&client->dev, 1257 data->motion_trig = devm_iio_trigger_alloc(&client->dev,
1241 "%s-any-motion-dev%d", 1258 "%s-any-motion-dev%d",
1242 indio_dev->name, 1259 indio_dev->name,
1243 indio_dev->id); 1260 indio_dev->id);
1244 if (!data->motion_trig) 1261 if (!data->motion_trig) {
1245 return -ENOMEM; 1262 ret = -ENOMEM;
1263 goto err_poweroff;
1264 }
1246 1265
1247 data->dready_trig->dev.parent = &client->dev; 1266 data->dready_trig->dev.parent = &client->dev;
1248 data->dready_trig->ops = &kxcjk1013_trigger_ops; 1267 data->dready_trig->ops = &kxcjk1013_trigger_ops;
@@ -1251,7 +1270,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
1251 iio_trigger_get(indio_dev->trig); 1270 iio_trigger_get(indio_dev->trig);
1252 ret = iio_trigger_register(data->dready_trig); 1271 ret = iio_trigger_register(data->dready_trig);
1253 if (ret) 1272 if (ret)
1254 return ret; 1273 goto err_poweroff;
1255 1274
1256 data->motion_trig->dev.parent = &client->dev; 1275 data->motion_trig->dev.parent = &client->dev;
1257 data->motion_trig->ops = &kxcjk1013_trigger_ops; 1276 data->motion_trig->ops = &kxcjk1013_trigger_ops;
@@ -1300,6 +1319,8 @@ err_trigger_unregister:
1300 iio_trigger_unregister(data->dready_trig); 1319 iio_trigger_unregister(data->dready_trig);
1301 if (data->motion_trig) 1320 if (data->motion_trig)
1302 iio_trigger_unregister(data->motion_trig); 1321 iio_trigger_unregister(data->motion_trig);
1322err_poweroff:
1323 kxcjk1013_set_mode(data, STANDBY);
1303 1324
1304 return ret; 1325 return ret;
1305} 1326}
@@ -1349,10 +1370,7 @@ static int kxcjk1013_resume(struct device *dev)
1349 int ret = 0; 1370 int ret = 0;
1350 1371
1351 mutex_lock(&data->mutex); 1372 mutex_lock(&data->mutex);
1352 /* Check, if the suspend occured while active */ 1373 ret = kxcjk1013_set_mode(data, OPERATION);
1353 if (data->dready_trigger_on || data->motion_trigger_on ||
1354 data->ev_enable_state)
1355 ret = kxcjk1013_set_mode(data, OPERATION);
1356 mutex_unlock(&data->mutex); 1374 mutex_unlock(&data->mutex);
1357 1375
1358 return ret; 1376 return ret;
@@ -1364,8 +1382,14 @@ static int kxcjk1013_runtime_suspend(struct device *dev)
1364{ 1382{
1365 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 1383 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1366 struct kxcjk1013_data *data = iio_priv(indio_dev); 1384 struct kxcjk1013_data *data = iio_priv(indio_dev);
1385 int ret;
1367 1386
1368 return kxcjk1013_set_mode(data, STANDBY); 1387 ret = kxcjk1013_set_mode(data, STANDBY);
1388 if (ret < 0) {
1389 dev_err(&data->client->dev, "powering off device failed\n");
1390 return -EAGAIN;
1391 }
1392 return 0;
1369} 1393}
1370 1394
1371static int kxcjk1013_runtime_resume(struct device *dev) 1395static int kxcjk1013_runtime_resume(struct device *dev)
@@ -1399,6 +1423,7 @@ static const struct acpi_device_id kx_acpi_match[] = {
1399 {"KXCJ1013", KXCJK1013}, 1423 {"KXCJ1013", KXCJK1013},
1400 {"KXCJ1008", KXCJ91008}, 1424 {"KXCJ1008", KXCJ91008},
1401 {"KXTJ1009", KXTJ21009}, 1425 {"KXTJ1009", KXTJ21009},
1426 {"SMO8500", KXCJ91008},
1402 { }, 1427 { },
1403}; 1428};
1404MODULE_DEVICE_TABLE(acpi, kx_acpi_match); 1429MODULE_DEVICE_TABLE(acpi, kx_acpi_match);
@@ -1407,6 +1432,7 @@ static const struct i2c_device_id kxcjk1013_id[] = {
1407 {"kxcjk1013", KXCJK1013}, 1432 {"kxcjk1013", KXCJK1013},
1408 {"kxcj91008", KXCJ91008}, 1433 {"kxcj91008", KXCJ91008},
1409 {"kxtj21009", KXTJ21009}, 1434 {"kxtj21009", KXTJ21009},
1435 {"SMO8500", KXCJ91008},
1410 {} 1436 {}
1411}; 1437};
1412 1438
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index 3c12d4966376..5b80657883bb 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -111,7 +111,7 @@ static const int mma8452_samp_freq[8][2] = {
111 {6, 250000}, {1, 560000} 111 {6, 250000}, {1, 560000}
112}; 112};
113 113
114/* 114/*
115 * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048 115 * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
116 * The userspace interface uses m/s^2 and we declare micro units 116 * The userspace interface uses m/s^2 and we declare micro units
117 * So scale factor is given by: 117 * So scale factor is given by:
diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c
new file mode 100644
index 000000000000..46c38351c6a3
--- /dev/null
+++ b/drivers/iio/accel/mma9551.c
@@ -0,0 +1,637 @@
1/*
2 * Freescale MMA9551L Intelligent Motion-Sensing Platform driver
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/module.h>
16#include <linux/i2c.h>
17#include <linux/interrupt.h>
18#include <linux/slab.h>
19#include <linux/acpi.h>
20#include <linux/delay.h>
21#include <linux/gpio/consumer.h>
22#include <linux/iio/iio.h>
23#include <linux/iio/sysfs.h>
24#include <linux/iio/events.h>
25#include <linux/pm_runtime.h>
26#include "mma9551_core.h"
27
28#define MMA9551_DRV_NAME "mma9551"
29#define MMA9551_IRQ_NAME "mma9551_event"
30#define MMA9551_GPIO_NAME "mma9551_int"
31#define MMA9551_GPIO_COUNT 4
32
33/* Tilt application (inclination in IIO terms). */
34#define MMA9551_TILT_XZ_ANG_REG 0x00
35#define MMA9551_TILT_YZ_ANG_REG 0x01
36#define MMA9551_TILT_XY_ANG_REG 0x02
37#define MMA9551_TILT_ANGFLG BIT(7)
38#define MMA9551_TILT_QUAD_REG 0x03
39#define MMA9551_TILT_XY_QUAD_SHIFT 0
40#define MMA9551_TILT_YZ_QUAD_SHIFT 2
41#define MMA9551_TILT_XZ_QUAD_SHIFT 4
42#define MMA9551_TILT_CFG_REG 0x01
43#define MMA9551_TILT_ANG_THRESH_MASK GENMASK(3, 0)
44
45#define MMA9551_DEFAULT_SAMPLE_RATE 122 /* Hz */
46
47/* Tilt events are mapped to the first three GPIO pins. */
48enum mma9551_tilt_axis {
49 mma9551_x = 0,
50 mma9551_y,
51 mma9551_z,
52};
53
54struct mma9551_data {
55 struct i2c_client *client;
56 struct mutex mutex;
57 int event_enabled[3];
58 int irqs[MMA9551_GPIO_COUNT];
59};
60
61static int mma9551_read_incli_chan(struct i2c_client *client,
62 const struct iio_chan_spec *chan,
63 int *val)
64{
65 u8 quad_shift, angle, quadrant;
66 u16 reg_addr;
67 int ret;
68
69 switch (chan->channel2) {
70 case IIO_MOD_X:
71 reg_addr = MMA9551_TILT_YZ_ANG_REG;
72 quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT;
73 break;
74 case IIO_MOD_Y:
75 reg_addr = MMA9551_TILT_XZ_ANG_REG;
76 quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT;
77 break;
78 case IIO_MOD_Z:
79 reg_addr = MMA9551_TILT_XY_ANG_REG;
80 quad_shift = MMA9551_TILT_XY_QUAD_SHIFT;
81 break;
82 default:
83 return -EINVAL;
84 }
85
86 ret = mma9551_set_power_state(client, true);
87 if (ret < 0)
88 return ret;
89
90 ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
91 reg_addr, &angle);
92 if (ret < 0)
93 goto out_poweroff;
94
95 ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
96 MMA9551_TILT_QUAD_REG, &quadrant);
97 if (ret < 0)
98 goto out_poweroff;
99
100 angle &= ~MMA9551_TILT_ANGFLG;
101 quadrant = (quadrant >> quad_shift) & 0x03;
102
103 if (quadrant == 1 || quadrant == 3)
104 *val = 90 * (quadrant + 1) - angle;
105 else
106 *val = angle + 90 * quadrant;
107
108 ret = IIO_VAL_INT;
109
110out_poweroff:
111 mma9551_set_power_state(client, false);
112 return ret;
113}
114
115static int mma9551_read_raw(struct iio_dev *indio_dev,
116 struct iio_chan_spec const *chan,
117 int *val, int *val2, long mask)
118{
119 struct mma9551_data *data = iio_priv(indio_dev);
120 int ret;
121
122 switch (mask) {
123 case IIO_CHAN_INFO_PROCESSED:
124 switch (chan->type) {
125 case IIO_INCLI:
126 mutex_lock(&data->mutex);
127 ret = mma9551_read_incli_chan(data->client, chan, val);
128 mutex_unlock(&data->mutex);
129 return ret;
130 default:
131 return -EINVAL;
132 }
133 case IIO_CHAN_INFO_RAW:
134 switch (chan->type) {
135 case IIO_ACCEL:
136 mutex_lock(&data->mutex);
137 ret = mma9551_read_accel_chan(data->client,
138 chan, val, val2);
139 mutex_unlock(&data->mutex);
140 return ret;
141 default:
142 return -EINVAL;
143 }
144 case IIO_CHAN_INFO_SCALE:
145 switch (chan->type) {
146 case IIO_ACCEL:
147 return mma9551_read_accel_scale(val, val2);
148 default:
149 return -EINVAL;
150 }
151 default:
152 return -EINVAL;
153 }
154}
155
156static int mma9551_read_event_config(struct iio_dev *indio_dev,
157 const struct iio_chan_spec *chan,
158 enum iio_event_type type,
159 enum iio_event_direction dir)
160{
161 struct mma9551_data *data = iio_priv(indio_dev);
162
163 switch (chan->type) {
164 case IIO_INCLI:
165 /* IIO counts axes from 1, because IIO_NO_MOD is 0. */
166 return data->event_enabled[chan->channel2 - 1];
167 default:
168 return -EINVAL;
169 }
170}
171
172static int mma9551_config_incli_event(struct iio_dev *indio_dev,
173 enum iio_modifier axis,
174 int state)
175{
176 struct mma9551_data *data = iio_priv(indio_dev);
177 enum mma9551_tilt_axis mma_axis;
178 int ret;
179
180 /* IIO counts axes from 1, because IIO_NO_MOD is 0. */
181 mma_axis = axis - 1;
182
183 if (data->event_enabled[mma_axis] == state)
184 return 0;
185
186 if (state == 0) {
187 ret = mma9551_gpio_config(data->client,
188 (enum mma9551_gpio_pin)mma_axis,
189 MMA9551_APPID_NONE, 0, 0);
190 if (ret < 0)
191 return ret;
192
193 ret = mma9551_set_power_state(data->client, false);
194 if (ret < 0)
195 return ret;
196 } else {
197 int bitnum;
198
199 /* Bit 7 of each angle register holds the angle flag. */
200 switch (axis) {
201 case IIO_MOD_X:
202 bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG;
203 break;
204 case IIO_MOD_Y:
205 bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG;
206 break;
207 case IIO_MOD_Z:
208 bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG;
209 break;
210 default:
211 return -EINVAL;
212 }
213
214
215 ret = mma9551_set_power_state(data->client, true);
216 if (ret < 0)
217 return ret;
218
219 ret = mma9551_gpio_config(data->client,
220 (enum mma9551_gpio_pin)mma_axis,
221 MMA9551_APPID_TILT, bitnum, 0);
222 if (ret < 0) {
223 mma9551_set_power_state(data->client, false);
224 return ret;
225 }
226 }
227
228 data->event_enabled[mma_axis] = state;
229
230 return ret;
231}
232
233static int mma9551_write_event_config(struct iio_dev *indio_dev,
234 const struct iio_chan_spec *chan,
235 enum iio_event_type type,
236 enum iio_event_direction dir,
237 int state)
238{
239 struct mma9551_data *data = iio_priv(indio_dev);
240 int ret;
241
242 switch (chan->type) {
243 case IIO_INCLI:
244 mutex_lock(&data->mutex);
245 ret = mma9551_config_incli_event(indio_dev,
246 chan->channel2, state);
247 mutex_unlock(&data->mutex);
248 return ret;
249 default:
250 return -EINVAL;
251 }
252}
253
254static int mma9551_write_event_value(struct iio_dev *indio_dev,
255 const struct iio_chan_spec *chan,
256 enum iio_event_type type,
257 enum iio_event_direction dir,
258 enum iio_event_info info,
259 int val, int val2)
260{
261 struct mma9551_data *data = iio_priv(indio_dev);
262 int ret;
263
264 switch (chan->type) {
265 case IIO_INCLI:
266 if (val2 != 0 || val < 1 || val > 10)
267 return -EINVAL;
268 mutex_lock(&data->mutex);
269 ret = mma9551_update_config_bits(data->client,
270 MMA9551_APPID_TILT,
271 MMA9551_TILT_CFG_REG,
272 MMA9551_TILT_ANG_THRESH_MASK,
273 val);
274 mutex_unlock(&data->mutex);
275 return ret;
276 default:
277 return -EINVAL;
278 }
279}
280
281static int mma9551_read_event_value(struct iio_dev *indio_dev,
282 const struct iio_chan_spec *chan,
283 enum iio_event_type type,
284 enum iio_event_direction dir,
285 enum iio_event_info info,
286 int *val, int *val2)
287{
288 struct mma9551_data *data = iio_priv(indio_dev);
289 int ret;
290 u8 tmp;
291
292 switch (chan->type) {
293 case IIO_INCLI:
294 mutex_lock(&data->mutex);
295 ret = mma9551_read_config_byte(data->client,
296 MMA9551_APPID_TILT,
297 MMA9551_TILT_CFG_REG, &tmp);
298 mutex_unlock(&data->mutex);
299 if (ret < 0)
300 return ret;
301 *val = tmp & MMA9551_TILT_ANG_THRESH_MASK;
302 *val2 = 0;
303 return IIO_VAL_INT;
304 default:
305 return -EINVAL;
306 }
307}
308
309static const struct iio_event_spec mma9551_incli_event = {
310 .type = IIO_EV_TYPE_ROC,
311 .dir = IIO_EV_DIR_RISING,
312 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
313 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
314};
315
316#define MMA9551_INCLI_CHANNEL(axis) { \
317 .type = IIO_INCLI, \
318 .modified = 1, \
319 .channel2 = axis, \
320 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
321 .event_spec = &mma9551_incli_event, \
322 .num_event_specs = 1, \
323}
324
325static const struct iio_chan_spec mma9551_channels[] = {
326 MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
327 MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
328 MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
329
330 MMA9551_INCLI_CHANNEL(IIO_MOD_X),
331 MMA9551_INCLI_CHANNEL(IIO_MOD_Y),
332 MMA9551_INCLI_CHANNEL(IIO_MOD_Z),
333};
334
335static const struct iio_info mma9551_info = {
336 .driver_module = THIS_MODULE,
337 .read_raw = mma9551_read_raw,
338 .read_event_config = mma9551_read_event_config,
339 .write_event_config = mma9551_write_event_config,
340 .read_event_value = mma9551_read_event_value,
341 .write_event_value = mma9551_write_event_value,
342};
343
344static irqreturn_t mma9551_event_handler(int irq, void *private)
345{
346 struct iio_dev *indio_dev = private;
347 struct mma9551_data *data = iio_priv(indio_dev);
348 int i, ret, mma_axis = -1;
349 u16 reg;
350 u8 val;
351
352 mutex_lock(&data->mutex);
353
354 for (i = 0; i < 3; i++)
355 if (irq == data->irqs[i]) {
356 mma_axis = i;
357 break;
358 }
359
360 if (mma_axis == -1) {
361 /* IRQ was triggered on 4th line, which we don't use. */
362 dev_warn(&data->client->dev,
363 "irq triggered on unused line %d\n", data->irqs[3]);
364 goto out;
365 }
366
367 switch (mma_axis) {
368 case mma9551_x:
369 reg = MMA9551_TILT_YZ_ANG_REG;
370 break;
371 case mma9551_y:
372 reg = MMA9551_TILT_XZ_ANG_REG;
373 break;
374 case mma9551_z:
375 reg = MMA9551_TILT_XY_ANG_REG;
376 break;
377 }
378
379 /*
380 * Read the angle even though we don't use it, otherwise we
381 * won't get any further interrupts.
382 */
383 ret = mma9551_read_status_byte(data->client, MMA9551_APPID_TILT,
384 reg, &val);
385 if (ret < 0) {
386 dev_err(&data->client->dev,
387 "error %d reading tilt register in IRQ\n", ret);
388 goto out;
389 }
390
391 iio_push_event(indio_dev,
392 IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1),
393 IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING),
394 iio_get_time_ns());
395
396out:
397 mutex_unlock(&data->mutex);
398
399 return IRQ_HANDLED;
400}
401
402static int mma9551_init(struct mma9551_data *data)
403{
404 int ret;
405
406 ret = mma9551_read_version(data->client);
407 if (ret)
408 return ret;
409
410 return mma9551_set_device_state(data->client, true);
411}
412
413static int mma9551_gpio_probe(struct iio_dev *indio_dev)
414{
415 struct gpio_desc *gpio;
416 int i, ret;
417 struct mma9551_data *data = iio_priv(indio_dev);
418 struct device *dev = &data->client->dev;
419
420 for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
421 gpio = devm_gpiod_get_index(dev, MMA9551_GPIO_NAME, i);
422 if (IS_ERR(gpio)) {
423 dev_err(dev, "acpi gpio get index failed\n");
424 return PTR_ERR(gpio);
425 }
426
427 ret = gpiod_direction_input(gpio);
428 if (ret)
429 return ret;
430
431 data->irqs[i] = gpiod_to_irq(gpio);
432 ret = devm_request_threaded_irq(dev, data->irqs[i],
433 NULL, mma9551_event_handler,
434 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
435 MMA9551_IRQ_NAME, indio_dev);
436 if (ret < 0) {
437 dev_err(dev, "request irq %d failed\n", data->irqs[i]);
438 return ret;
439 }
440
441 dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
442 desc_to_gpio(gpio), data->irqs[i]);
443 }
444
445 return 0;
446}
447
448static const char *mma9551_match_acpi_device(struct device *dev)
449{
450 const struct acpi_device_id *id;
451
452 id = acpi_match_device(dev->driver->acpi_match_table, dev);
453 if (!id)
454 return NULL;
455
456 return dev_name(dev);
457}
458
459static int mma9551_probe(struct i2c_client *client,
460 const struct i2c_device_id *id)
461{
462 struct mma9551_data *data;
463 struct iio_dev *indio_dev;
464 const char *name = NULL;
465 int ret;
466
467 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
468 if (!indio_dev)
469 return -ENOMEM;
470
471 data = iio_priv(indio_dev);
472 i2c_set_clientdata(client, indio_dev);
473 data->client = client;
474
475 if (id)
476 name = id->name;
477 else if (ACPI_HANDLE(&client->dev))
478 name = mma9551_match_acpi_device(&client->dev);
479
480 ret = mma9551_init(data);
481 if (ret < 0)
482 return ret;
483
484 mutex_init(&data->mutex);
485
486 indio_dev->dev.parent = &client->dev;
487 indio_dev->channels = mma9551_channels;
488 indio_dev->num_channels = ARRAY_SIZE(mma9551_channels);
489 indio_dev->name = name;
490 indio_dev->modes = INDIO_DIRECT_MODE;
491 indio_dev->info = &mma9551_info;
492
493 ret = mma9551_gpio_probe(indio_dev);
494 if (ret < 0)
495 goto out_poweroff;
496
497 ret = iio_device_register(indio_dev);
498 if (ret < 0) {
499 dev_err(&client->dev, "unable to register iio device\n");
500 goto out_poweroff;
501 }
502
503 ret = pm_runtime_set_active(&client->dev);
504 if (ret < 0)
505 goto out_iio_unregister;
506
507 pm_runtime_enable(&client->dev);
508 pm_runtime_set_autosuspend_delay(&client->dev,
509 MMA9551_AUTO_SUSPEND_DELAY_MS);
510 pm_runtime_use_autosuspend(&client->dev);
511
512 return 0;
513
514out_iio_unregister:
515 iio_device_unregister(indio_dev);
516out_poweroff:
517 mma9551_set_device_state(client, false);
518
519 return ret;
520}
521
522static int mma9551_remove(struct i2c_client *client)
523{
524 struct iio_dev *indio_dev = i2c_get_clientdata(client);
525 struct mma9551_data *data = iio_priv(indio_dev);
526
527 pm_runtime_disable(&client->dev);
528 pm_runtime_set_suspended(&client->dev);
529 pm_runtime_put_noidle(&client->dev);
530
531 iio_device_unregister(indio_dev);
532 mutex_lock(&data->mutex);
533 mma9551_set_device_state(data->client, false);
534 mutex_unlock(&data->mutex);
535
536 return 0;
537}
538
539#ifdef CONFIG_PM
540static int mma9551_runtime_suspend(struct device *dev)
541{
542 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
543 struct mma9551_data *data = iio_priv(indio_dev);
544 int ret;
545
546 mutex_lock(&data->mutex);
547 ret = mma9551_set_device_state(data->client, false);
548 mutex_unlock(&data->mutex);
549 if (ret < 0) {
550 dev_err(&data->client->dev, "powering off device failed\n");
551 return -EAGAIN;
552 }
553
554 return 0;
555}
556
557static int mma9551_runtime_resume(struct device *dev)
558{
559 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
560 struct mma9551_data *data = iio_priv(indio_dev);
561 int ret;
562
563 ret = mma9551_set_device_state(data->client, true);
564 if (ret < 0)
565 return ret;
566
567 mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE);
568
569 return 0;
570}
571#endif
572
573#ifdef CONFIG_PM_SLEEP
574static int mma9551_suspend(struct device *dev)
575{
576 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
577 struct mma9551_data *data = iio_priv(indio_dev);
578 int ret;
579
580 mutex_lock(&data->mutex);
581 ret = mma9551_set_device_state(data->client, false);
582 mutex_unlock(&data->mutex);
583
584 return ret;
585}
586
587static int mma9551_resume(struct device *dev)
588{
589 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
590 struct mma9551_data *data = iio_priv(indio_dev);
591 int ret;
592
593 mutex_lock(&data->mutex);
594 ret = mma9551_set_device_state(data->client, true);
595 mutex_unlock(&data->mutex);
596
597 return ret;
598}
599#endif
600
601static const struct dev_pm_ops mma9551_pm_ops = {
602 SET_SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
603 SET_RUNTIME_PM_OPS(mma9551_runtime_suspend,
604 mma9551_runtime_resume, NULL)
605};
606
607static const struct acpi_device_id mma9551_acpi_match[] = {
608 {"MMA9551", 0},
609 {},
610};
611
612MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
613
614static const struct i2c_device_id mma9551_id[] = {
615 {"mma9551", 0},
616 {}
617};
618
619MODULE_DEVICE_TABLE(i2c, mma9551_id);
620
621static struct i2c_driver mma9551_driver = {
622 .driver = {
623 .name = MMA9551_DRV_NAME,
624 .acpi_match_table = ACPI_PTR(mma9551_acpi_match),
625 .pm = &mma9551_pm_ops,
626 },
627 .probe = mma9551_probe,
628 .remove = mma9551_remove,
629 .id_table = mma9551_id,
630};
631
632module_i2c_driver(mma9551_driver);
633
634MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
635MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
636MODULE_LICENSE("GPL v2");
637MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
new file mode 100644
index 000000000000..7f55a6d7cd03
--- /dev/null
+++ b/drivers/iio/accel/mma9551_core.c
@@ -0,0 +1,798 @@
1/*
2 * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/module.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <linux/iio/iio.h>
19#include <linux/pm_runtime.h>
20#include "mma9551_core.h"
21
22/* Command masks for mailbox write command */
23#define MMA9551_CMD_READ_VERSION_INFO 0x00
24#define MMA9551_CMD_READ_CONFIG 0x10
25#define MMA9551_CMD_WRITE_CONFIG 0x20
26#define MMA9551_CMD_READ_STATUS 0x30
27
28/* Mailbox read command */
29#define MMA9551_RESPONSE_COCO BIT(7)
30
31/* Error-Status codes returned in mailbox read command */
32#define MMA9551_MCI_ERROR_NONE 0x00
33#define MMA9551_MCI_ERROR_PARAM 0x04
34#define MMA9551_MCI_INVALID_COUNT 0x19
35#define MMA9551_MCI_ERROR_COMMAND 0x1C
36#define MMA9551_MCI_ERROR_INVALID_LENGTH 0x21
37#define MMA9551_MCI_ERROR_FIFO_BUSY 0x22
38#define MMA9551_MCI_ERROR_FIFO_ALLOCATED 0x23
39#define MMA9551_MCI_ERROR_FIFO_OVERSIZE 0x24
40
41/* GPIO Application */
42#define MMA9551_GPIO_POL_MSB 0x08
43#define MMA9551_GPIO_POL_LSB 0x09
44
45/* Sleep/Wake application */
46#define MMA9551_SLEEP_CFG 0x06
47#define MMA9551_SLEEP_CFG_SNCEN BIT(0)
48#define MMA9551_SLEEP_CFG_FLEEN BIT(1)
49#define MMA9551_SLEEP_CFG_SCHEN BIT(2)
50
51/* AFE application */
52#define MMA9551_AFE_X_ACCEL_REG 0x00
53#define MMA9551_AFE_Y_ACCEL_REG 0x02
54#define MMA9551_AFE_Z_ACCEL_REG 0x04
55
56/* Reset/Suspend/Clear application */
57#define MMA9551_RSC_RESET 0x00
58#define MMA9551_RSC_OFFSET(mask) (3 - (ffs(mask) - 1) / 8)
59#define MMA9551_RSC_VAL(mask) (mask >> (((ffs(mask) - 1) / 8) * 8))
60
61/*
62 * A response is composed of:
63 * - control registers: MB0-3
64 * - data registers: MB4-31
65 *
66 * A request is composed of:
67 * - mbox to write to (always 0)
68 * - control registers: MB1-4
69 * - data registers: MB5-31
70 */
71#define MMA9551_MAILBOX_CTRL_REGS 4
72#define MMA9551_MAX_MAILBOX_DATA_REGS 28
73#define MMA9551_MAILBOX_REGS 32
74
75#define MMA9551_I2C_READ_RETRIES 5
76#define MMA9551_I2C_READ_DELAY 50 /* us */
77
78struct mma9551_mbox_request {
79 u8 start_mbox; /* Always 0. */
80 u8 app_id;
81 /*
82 * See Section 5.3.1 of the MMA955xL Software Reference Manual.
83 *
84 * Bit 7: reserved, always 0
85 * Bits 6-4: command
86 * Bits 3-0: upper bits of register offset
87 */
88 u8 cmd_off;
89 u8 lower_off;
90 u8 nbytes;
91 u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1];
92} __packed;
93
94struct mma9551_mbox_response {
95 u8 app_id;
96 /*
97 * See Section 5.3.3 of the MMA955xL Software Reference Manual.
98 *
99 * Bit 7: COCO
100 * Bits 6-0: Error code.
101 */
102 u8 coco_err;
103 u8 nbytes;
104 u8 req_bytes;
105 u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS];
106} __packed;
107
108struct mma9551_version_info {
109 __be32 device_id;
110 u8 rom_version[2];
111 u8 fw_version[2];
112 u8 hw_version[2];
113 u8 fw_build[2];
114};
115
116static int mma9551_transfer(struct i2c_client *client,
117 u8 app_id, u8 command, u16 offset,
118 u8 *inbytes, int num_inbytes,
119 u8 *outbytes, int num_outbytes)
120{
121 struct mma9551_mbox_request req;
122 struct mma9551_mbox_response rsp;
123 struct i2c_msg in, out;
124 u8 req_len, err_code;
125 int ret, retries;
126
127 if (offset >= 1 << 12) {
128 dev_err(&client->dev, "register offset too large\n");
129 return -EINVAL;
130 }
131
132 req_len = 1 + MMA9551_MAILBOX_CTRL_REGS + num_inbytes;
133 req.start_mbox = 0;
134 req.app_id = app_id;
135 req.cmd_off = command | (offset >> 8);
136 req.lower_off = offset;
137
138 if (command == MMA9551_CMD_WRITE_CONFIG)
139 req.nbytes = num_inbytes;
140 else
141 req.nbytes = num_outbytes;
142 if (num_inbytes)
143 memcpy(req.buf, inbytes, num_inbytes);
144
145 out.addr = client->addr;
146 out.flags = 0;
147 out.len = req_len;
148 out.buf = (u8 *)&req;
149
150 ret = i2c_transfer(client->adapter, &out, 1);
151 if (ret < 0) {
152 dev_err(&client->dev, "i2c write failed\n");
153 return ret;
154 }
155
156 retries = MMA9551_I2C_READ_RETRIES;
157 do {
158 udelay(MMA9551_I2C_READ_DELAY);
159
160 in.addr = client->addr;
161 in.flags = I2C_M_RD;
162 in.len = sizeof(rsp);
163 in.buf = (u8 *)&rsp;
164
165 ret = i2c_transfer(client->adapter, &in, 1);
166 if (ret < 0) {
167 dev_err(&client->dev, "i2c read failed\n");
168 return ret;
169 }
170
171 if (rsp.coco_err & MMA9551_RESPONSE_COCO)
172 break;
173 } while (--retries > 0);
174
175 if (retries == 0) {
176 dev_err(&client->dev,
177 "timed out while waiting for command response\n");
178 return -ETIMEDOUT;
179 }
180
181 if (rsp.app_id != app_id) {
182 dev_err(&client->dev,
183 "app_id mismatch in response got %02x expected %02x\n",
184 rsp.app_id, app_id);
185 return -EINVAL;
186 }
187
188 err_code = rsp.coco_err & ~MMA9551_RESPONSE_COCO;
189 if (err_code != MMA9551_MCI_ERROR_NONE) {
190 dev_err(&client->dev, "read returned error %x\n", err_code);
191 return -EINVAL;
192 }
193
194 if (rsp.nbytes != rsp.req_bytes) {
195 dev_err(&client->dev,
196 "output length mismatch got %d expected %d\n",
197 rsp.nbytes, rsp.req_bytes);
198 return -EINVAL;
199 }
200
201 if (num_outbytes)
202 memcpy(outbytes, rsp.buf, num_outbytes);
203
204 return 0;
205}
206
207/**
208 * mma9551_read_config_byte() - read 1 configuration byte
209 * @client: I2C client
210 * @app_id: Application ID
211 * @reg: Application register
212 * @val: Pointer to store value read
213 *
214 * Read one configuration byte from the device using MMA955xL command format.
215 * Commands to the MMA955xL platform consist of a write followed
216 * by one or more reads.
217 *
218 * Locking note: This function must be called with the device lock held.
219 * Locking is not handled inside the function. Callers should ensure they
220 * serialize access to the HW.
221 *
222 * Returns: 0 on success, negative value on failure.
223 */
224int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
225 u16 reg, u8 *val)
226{
227 return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
228 reg, NULL, 0, val, 1);
229}
230EXPORT_SYMBOL(mma9551_read_config_byte);
231
232/**
233 * mma9551_write_config_byte() - write 1 configuration byte
234 * @client: I2C client
235 * @app_id: Application ID
236 * @reg: Application register
237 * @val: Value to write
238 *
239 * Write one configuration byte from the device using MMA955xL command format.
240 * Commands to the MMA955xL platform consist of a write followed by one or
241 * more reads.
242 *
243 * Locking note: This function must be called with the device lock held.
244 * Locking is not handled inside the function. Callers should ensure they
245 * serialize access to the HW.
246 *
247 * Returns: 0 on success, negative value on failure.
248 */
249int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
250 u16 reg, u8 val)
251{
252 return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
253 &val, 1, NULL, 0);
254}
255EXPORT_SYMBOL(mma9551_write_config_byte);
256
257/**
258 * mma9551_read_status_byte() - read 1 status byte
259 * @client: I2C client
260 * @app_id: Application ID
261 * @reg: Application register
262 * @val: Pointer to store value read
263 *
264 * Read one status byte from the device using MMA955xL command format.
265 * Commands to the MMA955xL platform consist of a write followed by one or
266 * more reads.
267 *
268 * Locking note: This function must be called with the device lock held.
269 * Locking is not handled inside the function. Callers should ensure they
270 * serialize access to the HW.
271 *
272 * Returns: 0 on success, negative value on failure.
273 */
274int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
275 u16 reg, u8 *val)
276{
277 return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
278 reg, NULL, 0, val, 1);
279}
280EXPORT_SYMBOL(mma9551_read_status_byte);
281
282/**
283 * mma9551_read_config_word() - read 1 config word
284 * @client: I2C client
285 * @app_id: Application ID
286 * @reg: Application register
287 * @val: Pointer to store value read
288 *
289 * Read one configuration word from the device using MMA955xL command format.
290 * Commands to the MMA955xL platform consist of a write followed by one or
291 * more reads.
292 *
293 * Locking note: This function must be called with the device lock held.
294 * Locking is not handled inside the function. Callers should ensure they
295 * serialize access to the HW.
296 *
297 * Returns: 0 on success, negative value on failure.
298 */
299int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
300 u16 reg, u16 *val)
301{
302 int ret;
303 __be16 v;
304
305 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
306 reg, NULL, 0, (u8 *)&v, 2);
307 *val = be16_to_cpu(v);
308
309 return ret;
310}
311EXPORT_SYMBOL(mma9551_read_config_word);
312
313/**
314 * mma9551_write_config_word() - write 1 config word
315 * @client: I2C client
316 * @app_id: Application ID
317 * @reg: Application register
318 * @val: Value to write
319 *
320 * Write one configuration word from the device using MMA955xL command format.
321 * Commands to the MMA955xL platform consist of a write followed by one or
322 * more reads.
323 *
324 * Locking note: This function must be called with the device lock held.
325 * Locking is not handled inside the function. Callers should ensure they
326 * serialize access to the HW.
327 *
328 * Returns: 0 on success, negative value on failure.
329 */
330int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
331 u16 reg, u16 val)
332{
333 __be16 v = cpu_to_be16(val);
334
335 return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
336 (u8 *) &v, 2, NULL, 0);
337}
338EXPORT_SYMBOL(mma9551_write_config_word);
339
340/**
341 * mma9551_read_status_word() - read 1 status word
342 * @client: I2C client
343 * @app_id: Application ID
344 * @reg: Application register
345 * @val: Pointer to store value read
346 *
347 * Read one status word from the device using MMA955xL command format.
348 * Commands to the MMA955xL platform consist of a write followed by one or
349 * more reads.
350 *
351 * Locking note: This function must be called with the device lock held.
352 * Locking is not handled inside the function. Callers should ensure they
353 * serialize access to the HW.
354 *
355 * Returns: 0 on success, negative value on failure.
356 */
357int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
358 u16 reg, u16 *val)
359{
360 int ret;
361 __be16 v;
362
363 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
364 reg, NULL, 0, (u8 *)&v, 2);
365 *val = be16_to_cpu(v);
366
367 return ret;
368}
369EXPORT_SYMBOL(mma9551_read_status_word);
370
371/**
372 * mma9551_read_config_words() - read multiple config words
373 * @client: I2C client
374 * @app_id: Application ID
375 * @reg: Application register
376 * @len: Length of array to read in bytes
377 * @val: Array of words to read
378 *
379 * Read multiple configuration registers (word-sized registers).
380 *
381 * Locking note: This function must be called with the device lock held.
382 * Locking is not handled inside the function. Callers should ensure they
383 * serialize access to the HW.
384 *
385 * Returns: 0 on success, negative value on failure.
386 */
387int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
388 u16 reg, u8 len, u16 *buf)
389{
390 int ret, i;
391 int len_words = len / sizeof(u16);
392 __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
393
394 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
395 reg, NULL, 0, (u8 *) be_buf, len);
396 if (ret < 0)
397 return ret;
398
399 for (i = 0; i < len_words; i++)
400 buf[i] = be16_to_cpu(be_buf[i]);
401
402 return 0;
403}
404EXPORT_SYMBOL(mma9551_read_config_words);
405
406/**
407 * mma9551_read_status_words() - read multiple status words
408 * @client: I2C client
409 * @app_id: Application ID
410 * @reg: Application register
411 * @len: Length of array to read in bytes
412 * @val: Array of words to read
413 *
414 * Read multiple status registers (word-sized registers).
415 *
416 * Locking note: This function must be called with the device lock held.
417 * Locking is not handled inside the function. Callers should ensure they
418 * serialize access to the HW.
419 *
420 * Returns: 0 on success, negative value on failure.
421 */
422int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
423 u16 reg, u8 len, u16 *buf)
424{
425 int ret, i;
426 int len_words = len / sizeof(u16);
427 __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
428
429 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
430 reg, NULL, 0, (u8 *) be_buf, len);
431 if (ret < 0)
432 return ret;
433
434 for (i = 0; i < len_words; i++)
435 buf[i] = be16_to_cpu(be_buf[i]);
436
437 return 0;
438}
439EXPORT_SYMBOL(mma9551_read_status_words);
440
441/**
442 * mma9551_write_config_words() - write multiple config words
443 * @client: I2C client
444 * @app_id: Application ID
445 * @reg: Application register
446 * @len: Length of array to write in bytes
447 * @val: Array of words to write
448 *
449 * Write multiple configuration registers (word-sized registers).
450 *
451 * Locking note: This function must be called with the device lock held.
452 * Locking is not handled inside the function. Callers should ensure they
453 * serialize access to the HW.
454 *
455 * Returns: 0 on success, negative value on failure.
456 */
457int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
458 u16 reg, u8 len, u16 *buf)
459{
460 int i;
461 int len_words = len / sizeof(u16);
462 __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
463
464 for (i = 0; i < len_words; i++)
465 be_buf[i] = cpu_to_be16(buf[i]);
466
467 return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
468 reg, (u8 *) be_buf, len, NULL, 0);
469}
470EXPORT_SYMBOL(mma9551_write_config_words);
471
472/**
473 * mma9551_update_config_bits() - update bits in register
474 * @client: I2C client
475 * @app_id: Application ID
476 * @reg: Application register
477 * @mask: Mask for the bits to update
478 * @val: Value of the bits to update
479 *
480 * Update bits in the given register using a bit mask.
481 *
482 * Locking note: This function must be called with the device lock held.
483 * Locking is not handled inside the function. Callers should ensure they
484 * serialize access to the HW.
485 *
486 * Returns: 0 on success, negative value on failure.
487 */
488int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
489 u16 reg, u8 mask, u8 val)
490{
491 int ret;
492 u8 tmp, orig;
493
494 ret = mma9551_read_config_byte(client, app_id, reg, &orig);
495 if (ret < 0)
496 return ret;
497
498 tmp = orig & ~mask;
499 tmp |= val & mask;
500
501 if (tmp == orig)
502 return 0;
503
504 return mma9551_write_config_byte(client, app_id, reg, tmp);
505}
506EXPORT_SYMBOL(mma9551_update_config_bits);
507
508/**
509 * mma9551_gpio_config() - configure gpio
510 * @client: I2C client
511 * @pin: GPIO pin to configure
512 * @app_id: Application ID
513 * @bitnum: Bit number of status register being assigned to the GPIO pin.
514 * @polarity: The polarity parameter is described in section 6.2.2, page 66,
515 * of the Software Reference Manual. Basically, polarity=0 means
516 * the interrupt line has the same value as the selected bit,
517 * while polarity=1 means the line is inverted.
518 *
519 * Assign a bit from an application’s status register to a specific GPIO pin.
520 *
521 * Locking note: This function must be called with the device lock held.
522 * Locking is not handled inside the function. Callers should ensure they
523 * serialize access to the HW.
524 *
525 * Returns: 0 on success, negative value on failure.
526 */
527int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
528 u8 app_id, u8 bitnum, int polarity)
529{
530 u8 reg, pol_mask, pol_val;
531 int ret;
532
533 if (pin > mma9551_gpio_max) {
534 dev_err(&client->dev, "bad GPIO pin\n");
535 return -EINVAL;
536 }
537
538 /*
539 * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and
540 * 0x03, and so on.
541 */
542 reg = pin * 2;
543
544 ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
545 reg, app_id);
546 if (ret < 0) {
547 dev_err(&client->dev, "error setting GPIO app_id\n");
548 return ret;
549 }
550
551 ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
552 reg + 1, bitnum);
553 if (ret < 0) {
554 dev_err(&client->dev, "error setting GPIO bit number\n");
555 return ret;
556 }
557
558 switch (pin) {
559 case mma9551_gpio6:
560 reg = MMA9551_GPIO_POL_LSB;
561 pol_mask = 1 << 6;
562 break;
563 case mma9551_gpio7:
564 reg = MMA9551_GPIO_POL_LSB;
565 pol_mask = 1 << 7;
566 break;
567 case mma9551_gpio8:
568 reg = MMA9551_GPIO_POL_MSB;
569 pol_mask = 1 << 0;
570 break;
571 case mma9551_gpio9:
572 reg = MMA9551_GPIO_POL_MSB;
573 pol_mask = 1 << 1;
574 break;
575 }
576 pol_val = polarity ? pol_mask : 0;
577
578 ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,
579 pol_mask, pol_val);
580 if (ret < 0)
581 dev_err(&client->dev, "error setting GPIO polarity\n");
582
583 return ret;
584}
585EXPORT_SYMBOL(mma9551_gpio_config);
586
587/**
588 * mma9551_read_version() - read device version information
589 * @client: I2C client
590 *
591 * Read version information and print device id and firmware version.
592 *
593 * Locking note: This function must be called with the device lock held.
594 * Locking is not handled inside the function. Callers should ensure they
595 * serialize access to the HW.
596 *
597 * Returns: 0 on success, negative value on failure.
598 */
599int mma9551_read_version(struct i2c_client *client)
600{
601 struct mma9551_version_info info;
602 int ret;
603
604 ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,
605 NULL, 0, (u8 *)&info, sizeof(info));
606 if (ret < 0)
607 return ret;
608
609 dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",
610 be32_to_cpu(info.device_id), info.fw_version[0],
611 info.fw_version[1]);
612
613 return 0;
614}
615EXPORT_SYMBOL(mma9551_read_version);
616
617/**
618 * mma9551_set_device_state() - sets HW power mode
619 * @client: I2C client
620 * @enable: Use true to power on device, false to cause the device
621 * to enter sleep.
622 *
623 * Set power on/off for device using the Sleep/Wake Application.
624 * When enable is true, power on chip and enable doze mode.
625 * When enable is false, enter sleep mode (device remains in the
626 * lowest-power mode).
627 *
628 * Locking note: This function must be called with the device lock held.
629 * Locking is not handled inside the function. Callers should ensure they
630 * serialize access to the HW.
631 *
632 * Returns: 0 on success, negative value on failure.
633 */
634int mma9551_set_device_state(struct i2c_client *client, bool enable)
635{
636 return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,
637 MMA9551_SLEEP_CFG,
638 MMA9551_SLEEP_CFG_SNCEN |
639 MMA9551_SLEEP_CFG_FLEEN |
640 MMA9551_SLEEP_CFG_SCHEN,
641 enable ? MMA9551_SLEEP_CFG_SCHEN |
642 MMA9551_SLEEP_CFG_FLEEN :
643 MMA9551_SLEEP_CFG_SNCEN);
644}
645EXPORT_SYMBOL(mma9551_set_device_state);
646
647/**
648 * mma9551_set_power_state() - sets runtime PM state
649 * @client: I2C client
650 * @on: Use true to power on device, false to power off
651 *
652 * Resume or suspend the device using Runtime PM.
653 * The device will suspend after the autosuspend delay.
654 *
655 * Returns: 0 on success, negative value on failure.
656 */
657int mma9551_set_power_state(struct i2c_client *client, bool on)
658{
659#ifdef CONFIG_PM
660 int ret;
661
662 if (on)
663 ret = pm_runtime_get_sync(&client->dev);
664 else {
665 pm_runtime_mark_last_busy(&client->dev);
666 ret = pm_runtime_put_autosuspend(&client->dev);
667 }
668
669 if (ret < 0) {
670 dev_err(&client->dev,
671 "failed to change power state to %d\n", on);
672 if (on)
673 pm_runtime_put_noidle(&client->dev);
674
675 return ret;
676 }
677#endif
678
679 return 0;
680}
681EXPORT_SYMBOL(mma9551_set_power_state);
682
683/**
684 * mma9551_sleep() - sleep
685 * @freq: Application frequency
686 *
687 * Firmware applications run at a certain frequency on the
688 * device. Sleep for one application cycle to make sure the
689 * application had time to run once and initialize set values.
690 */
691void mma9551_sleep(int freq)
692{
693 int sleep_val = 1000 / freq;
694
695 if (sleep_val < 20)
696 usleep_range(sleep_val * 1000, 20000);
697 else
698 msleep_interruptible(sleep_val);
699}
700EXPORT_SYMBOL(mma9551_sleep);
701
702/**
703 * mma9551_read_accel_chan() - read accelerometer channel
704 * @client: I2C client
705 * @chan: IIO channel
706 * @val: Pointer to the accelerometer value read
707 * @val2: Unused
708 *
709 * Read accelerometer value for the specified channel.
710 *
711 * Locking note: This function must be called with the device lock held.
712 * Locking is not handled inside the function. Callers should ensure they
713 * serialize access to the HW.
714 *
715 * Returns: IIO_VAL_INT on success, negative value on failure.
716 */
717int mma9551_read_accel_chan(struct i2c_client *client,
718 const struct iio_chan_spec *chan,
719 int *val, int *val2)
720{
721 u16 reg_addr;
722 s16 raw_accel;
723 int ret;
724
725 switch (chan->channel2) {
726 case IIO_MOD_X:
727 reg_addr = MMA9551_AFE_X_ACCEL_REG;
728 break;
729 case IIO_MOD_Y:
730 reg_addr = MMA9551_AFE_Y_ACCEL_REG;
731 break;
732 case IIO_MOD_Z:
733 reg_addr = MMA9551_AFE_Z_ACCEL_REG;
734 break;
735 default:
736 return -EINVAL;
737 }
738
739 ret = mma9551_set_power_state(client, true);
740 if (ret < 0)
741 return ret;
742
743 ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
744 reg_addr, &raw_accel);
745 if (ret < 0)
746 goto out_poweroff;
747
748 *val = raw_accel;
749
750 ret = IIO_VAL_INT;
751
752out_poweroff:
753 mma9551_set_power_state(client, false);
754 return ret;
755}
756EXPORT_SYMBOL(mma9551_read_accel_chan);
757
758/**
759 * mma9551_read_accel_scale() - read accelerometer scale
760 * @val: Pointer to the accelerometer scale (int value)
761 * @val2: Pointer to the accelerometer scale (micro value)
762 *
763 * Read accelerometer scale.
764 *
765 * Returns: IIO_VAL_INT_PLUS_MICRO.
766 */
767int mma9551_read_accel_scale(int *val, int *val2)
768{
769 *val = 0;
770 *val2 = 2440;
771
772 return IIO_VAL_INT_PLUS_MICRO;
773}
774EXPORT_SYMBOL(mma9551_read_accel_scale);
775
776/**
777 * mma9551_app_reset() - reset application
778 * @client: I2C client
779 * @app_mask: Application to reset
780 *
781 * Reset the given application (using the Reset/Suspend/Clear
782 * Control Application)
783 *
784 * Returns: 0 on success, negative value on failure.
785 */
786int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
787{
788 return mma9551_write_config_byte(client, MMA9551_APPID_RCS,
789 MMA9551_RSC_RESET +
790 MMA9551_RSC_OFFSET(app_mask),
791 MMA9551_RSC_VAL(app_mask));
792}
793EXPORT_SYMBOL(mma9551_app_reset);
794
795MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
796MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
797MODULE_LICENSE("GPL v2");
798MODULE_DESCRIPTION("MMA955xL sensors core");
diff --git a/drivers/iio/accel/mma9551_core.h b/drivers/iio/accel/mma9551_core.h
new file mode 100644
index 000000000000..edaa56b1078e
--- /dev/null
+++ b/drivers/iio/accel/mma9551_core.h
@@ -0,0 +1,81 @@
1/*
2 * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef _MMA9551_CORE_H_
16#define _MMA9551_CORE_H_
17
18/* Applications IDs */
19#define MMA9551_APPID_VERSION 0x00
20#define MMA9551_APPID_GPIO 0x03
21#define MMA9551_APPID_AFE 0x06
22#define MMA9551_APPID_TILT 0x0B
23#define MMA9551_APPID_SLEEP_WAKE 0x12
24#define MMA9551_APPID_PEDOMETER 0x15
25#define MMA9551_APPID_RCS 0x17
26#define MMA9551_APPID_NONE 0xff
27
28/* Reset/Suspend/Clear application app masks */
29#define MMA9551_RSC_PED BIT(21)
30
31#define MMA9551_AUTO_SUSPEND_DELAY_MS 2000
32
33enum mma9551_gpio_pin {
34 mma9551_gpio6 = 0,
35 mma9551_gpio7,
36 mma9551_gpio8,
37 mma9551_gpio9,
38 mma9551_gpio_max = mma9551_gpio9,
39};
40
41#define MMA9551_ACCEL_CHANNEL(axis) { \
42 .type = IIO_ACCEL, \
43 .modified = 1, \
44 .channel2 = axis, \
45 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
46 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
47}
48
49int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
50 u16 reg, u8 *val);
51int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
52 u16 reg, u8 val);
53int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
54 u16 reg, u8 *val);
55int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
56 u16 reg, u16 *val);
57int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
58 u16 reg, u16 val);
59int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
60 u16 reg, u16 *val);
61int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
62 u16 reg, u8 len, u16 *buf);
63int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
64 u16 reg, u8 len, u16 *buf);
65int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
66 u16 reg, u8 len, u16 *buf);
67int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
68 u16 reg, u8 mask, u8 val);
69int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
70 u8 app_id, u8 bitnum, int polarity);
71int mma9551_read_version(struct i2c_client *client);
72int mma9551_set_device_state(struct i2c_client *client, bool enable);
73int mma9551_set_power_state(struct i2c_client *client, bool on);
74void mma9551_sleep(int freq);
75int mma9551_read_accel_chan(struct i2c_client *client,
76 const struct iio_chan_spec *chan,
77 int *val, int *val2);
78int mma9551_read_accel_scale(int *val, int *val2);
79int mma9551_app_reset(struct i2c_client *client, u32 app_mask);
80
81#endif /* _MMA9551_CORE_H_ */
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
new file mode 100644
index 000000000000..d23ebf192f63
--- /dev/null
+++ b/drivers/iio/accel/mma9553.c
@@ -0,0 +1,1334 @@
1/*
2 * Freescale MMA9553L Intelligent Pedometer driver
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/module.h>
16#include <linux/i2c.h>
17#include <linux/interrupt.h>
18#include <linux/slab.h>
19#include <linux/acpi.h>
20#include <linux/gpio/consumer.h>
21#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h>
23#include <linux/iio/events.h>
24#include <linux/pm_runtime.h>
25#include "mma9551_core.h"
26
27#define MMA9553_DRV_NAME "mma9553"
28#define MMA9553_IRQ_NAME "mma9553_event"
29#define MMA9553_GPIO_NAME "mma9553_int"
30
31/* Pedometer configuration registers (R/W) */
32#define MMA9553_REG_CONF_SLEEPMIN 0x00
33#define MMA9553_REG_CONF_SLEEPMAX 0x02
34#define MMA9553_REG_CONF_SLEEPTHD 0x04
35#define MMA9553_MASK_CONF_WORD GENMASK(15, 0)
36
37#define MMA9553_REG_CONF_CONF_STEPLEN 0x06
38#define MMA9553_MASK_CONF_CONFIG BIT(15)
39#define MMA9553_MASK_CONF_ACT_DBCNTM BIT(14)
40#define MMA9553_MASK_CONF_SLP_DBCNTM BIT(13)
41#define MMA9553_MASK_CONF_STEPLEN GENMASK(7, 0)
42
43#define MMA9553_REG_CONF_HEIGHT_WEIGHT 0x08
44#define MMA9553_MASK_CONF_HEIGHT GENMASK(15, 8)
45#define MMA9553_MASK_CONF_WEIGHT GENMASK(7, 0)
46
47#define MMA9553_REG_CONF_FILTER 0x0A
48#define MMA9553_MASK_CONF_FILTSTEP GENMASK(15, 8)
49#define MMA9553_MASK_CONF_MALE BIT(7)
50#define MMA9553_MASK_CONF_FILTTIME GENMASK(6, 0)
51
52#define MMA9553_REG_CONF_SPEED_STEP 0x0C
53#define MMA9553_MASK_CONF_SPDPRD GENMASK(15, 8)
54#define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0)
55
56#define MMA9553_REG_CONF_ACTTHD 0x0E
57
58/* Pedometer status registers (R-only) */
59#define MMA9553_REG_STATUS 0x00
60#define MMA9553_MASK_STATUS_MRGFL BIT(15)
61#define MMA9553_MASK_STATUS_SUSPCHG BIT(14)
62#define MMA9553_MASK_STATUS_STEPCHG BIT(13)
63#define MMA9553_MASK_STATUS_ACTCHG BIT(12)
64#define MMA9553_MASK_STATUS_SUSP BIT(11)
65#define MMA9553_MASK_STATUS_ACTIVITY (BIT(10) | BIT(9) | BIT(8))
66#define MMA9553_MASK_STATUS_VERSION 0x00FF
67
68#define MMA9553_REG_STEPCNT 0x02
69#define MMA9553_REG_DISTANCE 0x04
70#define MMA9553_REG_SPEED 0x06
71#define MMA9553_REG_CALORIES 0x08
72#define MMA9553_REG_SLEEPCNT 0x0A
73
74/* Pedometer events are always mapped to this pin. */
75#define MMA9553_DEFAULT_GPIO_PIN mma9551_gpio6
76#define MMA9553_DEFAULT_GPIO_POLARITY 0
77
78/* Bitnum used for gpio configuration = bit number in high status byte */
79#define STATUS_TO_BITNUM(bit) (ffs(bit) - 9)
80
81#define MMA9553_DEFAULT_SAMPLE_RATE 30 /* Hz */
82
83/*
84 * The internal activity level must be stable for ACTTHD samples before
85 * ACTIVITY is updated.The ACTIVITY variable contains the current activity
86 * level and is updated every time a step is detected or once a second
87 * if there are no steps.
88 */
89#define MMA9553_ACTIVITY_THD_TO_SEC(thd) ((thd) / MMA9553_DEFAULT_SAMPLE_RATE)
90#define MMA9553_ACTIVITY_SEC_TO_THD(sec) ((sec) * MMA9553_DEFAULT_SAMPLE_RATE)
91
92/*
93 * Autonomously suspend pedometer if acceleration vector magnitude
94 * is near 1g (4096 at 0.244 mg/LSB resolution) for 30 seconds.
95 */
96#define MMA9553_DEFAULT_SLEEPMIN 3688 /* 0,9 g */
97#define MMA9553_DEFAULT_SLEEPMAX 4508 /* 1,1 g */
98#define MMA9553_DEFAULT_SLEEPTHD (MMA9553_DEFAULT_SAMPLE_RATE * 30)
99
100#define MMA9553_CONFIG_RETRIES 2
101
102/* Status register - activity field */
103enum activity_level {
104 ACTIVITY_UNKNOWN,
105 ACTIVITY_REST,
106 ACTIVITY_WALKING,
107 ACTIVITY_JOGGING,
108 ACTIVITY_RUNNING,
109};
110
111static struct mma9553_event_info {
112 enum iio_chan_type type;
113 enum iio_modifier mod;
114 enum iio_event_direction dir;
115} mma9553_events_info[] = {
116 {
117 .type = IIO_STEPS,
118 .mod = IIO_NO_MOD,
119 .dir = IIO_EV_DIR_NONE,
120 },
121 {
122 .type = IIO_ACTIVITY,
123 .mod = IIO_MOD_STILL,
124 .dir = IIO_EV_DIR_RISING,
125 },
126 {
127 .type = IIO_ACTIVITY,
128 .mod = IIO_MOD_STILL,
129 .dir = IIO_EV_DIR_FALLING,
130 },
131 {
132 .type = IIO_ACTIVITY,
133 .mod = IIO_MOD_WALKING,
134 .dir = IIO_EV_DIR_RISING,
135 },
136 {
137 .type = IIO_ACTIVITY,
138 .mod = IIO_MOD_WALKING,
139 .dir = IIO_EV_DIR_FALLING,
140 },
141 {
142 .type = IIO_ACTIVITY,
143 .mod = IIO_MOD_JOGGING,
144 .dir = IIO_EV_DIR_RISING,
145 },
146 {
147 .type = IIO_ACTIVITY,
148 .mod = IIO_MOD_JOGGING,
149 .dir = IIO_EV_DIR_FALLING,
150 },
151 {
152 .type = IIO_ACTIVITY,
153 .mod = IIO_MOD_RUNNING,
154 .dir = IIO_EV_DIR_RISING,
155 },
156 {
157 .type = IIO_ACTIVITY,
158 .mod = IIO_MOD_RUNNING,
159 .dir = IIO_EV_DIR_FALLING,
160 },
161};
162
163#define MMA9553_EVENTS_INFO_SIZE ARRAY_SIZE(mma9553_events_info)
164
165struct mma9553_event {
166 struct mma9553_event_info *info;
167 bool enabled;
168};
169
170struct mma9553_conf_regs {
171 u16 sleepmin;
172 u16 sleepmax;
173 u16 sleepthd;
174 u16 config;
175 u16 height_weight;
176 u16 filter;
177 u16 speed_step;
178 u16 actthd;
179} __packed;
180
181struct mma9553_data {
182 struct i2c_client *client;
183 struct mutex mutex;
184 struct mma9553_conf_regs conf;
185 struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];
186 int num_events;
187 u8 gpio_bitnum;
188 /*
189 * This is used for all features that depend on step count:
190 * step count, distance, speed, calories.
191 */
192 bool stepcnt_enabled;
193 u16 stepcnt;
194 u8 activity;
195 s64 timestamp;
196};
197
198static u8 mma9553_get_bits(u16 val, u16 mask)
199{
200 return (val & mask) >> (ffs(mask) - 1);
201}
202
203static u16 mma9553_set_bits(u16 current_val, u16 val, u16 mask)
204{
205 return (current_val & ~mask) | (val << (ffs(mask) - 1));
206}
207
208static enum iio_modifier mma9553_activity_to_mod(enum activity_level activity)
209{
210 switch (activity) {
211 case ACTIVITY_RUNNING:
212 return IIO_MOD_RUNNING;
213 case ACTIVITY_JOGGING:
214 return IIO_MOD_JOGGING;
215 case ACTIVITY_WALKING:
216 return IIO_MOD_WALKING;
217 case ACTIVITY_REST:
218 return IIO_MOD_STILL;
219 case ACTIVITY_UNKNOWN:
220 default:
221 return IIO_NO_MOD;
222 }
223}
224
225static void mma9553_init_events(struct mma9553_data *data)
226{
227 int i;
228
229 data->num_events = MMA9553_EVENTS_INFO_SIZE;
230 for (i = 0; i < data->num_events; i++) {
231 data->events[i].info = &mma9553_events_info[i];
232 data->events[i].enabled = false;
233 }
234}
235
236static struct mma9553_event *mma9553_get_event(struct mma9553_data *data,
237 enum iio_chan_type type,
238 enum iio_modifier mod,
239 enum iio_event_direction dir)
240{
241 int i;
242
243 for (i = 0; i < data->num_events; i++)
244 if (data->events[i].info->type == type &&
245 data->events[i].info->mod == mod &&
246 data->events[i].info->dir == dir)
247 return &data->events[i];
248
249 return NULL;
250}
251
252static bool mma9553_is_any_event_enabled(struct mma9553_data *data,
253 bool check_type,
254 enum iio_chan_type type)
255{
256 int i;
257
258 for (i = 0; i < data->num_events; i++)
259 if ((check_type && data->events[i].info->type == type &&
260 data->events[i].enabled) ||
261 (!check_type && data->events[i].enabled))
262 return true;
263
264 return false;
265}
266
267static int mma9553_set_config(struct mma9553_data *data, u16 reg,
268 u16 *p_reg_val, u16 val, u16 mask)
269{
270 int ret, retries;
271 u16 reg_val, config;
272
273 reg_val = *p_reg_val;
274 if (val == mma9553_get_bits(reg_val, mask))
275 return 0;
276
277 reg_val = mma9553_set_bits(reg_val, val, mask);
278 ret = mma9551_write_config_word(data->client, MMA9551_APPID_PEDOMETER,
279 reg, reg_val);
280 if (ret < 0) {
281 dev_err(&data->client->dev,
282 "error writing config register 0x%x\n", reg);
283 return ret;
284 }
285
286 *p_reg_val = reg_val;
287
288 /* Reinitializes the pedometer with current configuration values */
289 config = mma9553_set_bits(data->conf.config, 1,
290 MMA9553_MASK_CONF_CONFIG);
291
292 ret = mma9551_write_config_word(data->client, MMA9551_APPID_PEDOMETER,
293 MMA9553_REG_CONF_CONF_STEPLEN, config);
294 if (ret < 0) {
295 dev_err(&data->client->dev,
296 "error writing config register 0x%x\n",
297 MMA9553_REG_CONF_CONF_STEPLEN);
298 return ret;
299 }
300
301 retries = MMA9553_CONFIG_RETRIES;
302 do {
303 mma9551_sleep(MMA9553_DEFAULT_SAMPLE_RATE);
304 ret = mma9551_read_config_word(data->client,
305 MMA9551_APPID_PEDOMETER,
306 MMA9553_REG_CONF_CONF_STEPLEN,
307 &config);
308 if (ret < 0)
309 return ret;
310 } while (mma9553_get_bits(config, MMA9553_MASK_CONF_CONFIG) &&
311 --retries > 0);
312
313 return 0;
314}
315
316static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
317 u8 *activity, u16 *stepcnt)
318{
319 u32 status_stepcnt;
320 u16 status;
321 int ret;
322
323 ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
324 MMA9553_REG_STATUS, sizeof(u32),
325 (u16 *) &status_stepcnt);
326 if (ret < 0) {
327 dev_err(&data->client->dev,
328 "error reading status and stepcnt\n");
329 return ret;
330 }
331
332 status = status_stepcnt & MMA9553_MASK_CONF_WORD;
333 *activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY);
334 *stepcnt = status_stepcnt >> 16;
335
336 return 0;
337}
338
339static int mma9553_conf_gpio(struct mma9553_data *data)
340{
341 u8 bitnum = 0, appid = MMA9551_APPID_PEDOMETER;
342 int ret;
343 struct mma9553_event *ev_step_detect;
344 bool activity_enabled;
345
346 activity_enabled =
347 mma9553_is_any_event_enabled(data, true, IIO_ACTIVITY);
348 ev_step_detect =
349 mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
350
351 /*
352 * If both step detector and activity are enabled, use the MRGFL bit.
353 * This bit is the logical OR of the SUSPCHG, STEPCHG, and ACTCHG flags.
354 */
355 if (activity_enabled && ev_step_detect->enabled)
356 bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_MRGFL);
357 else if (ev_step_detect->enabled)
358 bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_STEPCHG);
359 else if (activity_enabled)
360 bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_ACTCHG);
361 else /* Reset */
362 appid = MMA9551_APPID_NONE;
363
364 if (data->gpio_bitnum == bitnum)
365 return 0;
366
367 /* Save initial values for activity and stepcnt */
368 if (activity_enabled || ev_step_detect->enabled)
369 mma9553_read_activity_stepcnt(data, &data->activity,
370 &data->stepcnt);
371
372 ret = mma9551_gpio_config(data->client,
373 MMA9553_DEFAULT_GPIO_PIN,
374 appid, bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
375 if (ret < 0)
376 return ret;
377 data->gpio_bitnum = bitnum;
378
379 return 0;
380}
381
382static int mma9553_init(struct mma9553_data *data)
383{
384 int ret;
385
386 ret = mma9551_read_version(data->client);
387 if (ret)
388 return ret;
389
390 /*
391 * Read all the pedometer configuration registers. This is used as
392 * a device identification command to differentiate the MMA9553L
393 * from the MMA9550L.
394 */
395 ret =
396 mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
397 MMA9553_REG_CONF_SLEEPMIN,
398 sizeof(data->conf), (u16 *) &data->conf);
399 if (ret < 0) {
400 dev_err(&data->client->dev,
401 "device is not MMA9553L: failed to read cfg regs\n");
402 return ret;
403 }
404
405
406 /* Reset gpio */
407 data->gpio_bitnum = -1;
408 ret = mma9553_conf_gpio(data);
409 if (ret < 0)
410 return ret;
411
412 ret = mma9551_app_reset(data->client, MMA9551_RSC_PED);
413 if (ret < 0)
414 return ret;
415
416 /* Init config registers */
417 data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;
418 data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;
419 data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;
420 data->conf.config =
421 mma9553_set_bits(data->conf.config, 1, MMA9553_MASK_CONF_CONFIG);
422 /*
423 * Clear the activity debounce counter when the activity level changes,
424 * so that the confidence level applies for any activity level.
425 */
426 data->conf.config = mma9553_set_bits(data->conf.config, 1,
427 MMA9553_MASK_CONF_ACT_DBCNTM);
428 ret =
429 mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
430 MMA9553_REG_CONF_SLEEPMIN,
431 sizeof(data->conf), (u16 *) &data->conf);
432 if (ret < 0) {
433 dev_err(&data->client->dev,
434 "failed to write configuration registers\n");
435 return ret;
436 }
437
438 return mma9551_set_device_state(data->client, true);
439}
440
441static int mma9553_read_raw(struct iio_dev *indio_dev,
442 struct iio_chan_spec const *chan,
443 int *val, int *val2, long mask)
444{
445 struct mma9553_data *data = iio_priv(indio_dev);
446 int ret;
447 u16 tmp;
448 u8 activity;
449 bool powered_on;
450
451 switch (mask) {
452 case IIO_CHAN_INFO_PROCESSED:
453 switch (chan->type) {
454 case IIO_STEPS:
455 /*
456 * The HW only counts steps and other dependent
457 * parameters (speed, distance, calories, activity)
458 * if power is on (from enabling an event or the
459 * step counter */
460 powered_on =
461 mma9553_is_any_event_enabled(data, false, 0) ||
462 data->stepcnt_enabled;
463 if (!powered_on) {
464 dev_err(&data->client->dev,
465 "No channels enabled\n");
466 return -EINVAL;
467 }
468 mutex_lock(&data->mutex);
469 ret = mma9551_read_status_word(data->client,
470 MMA9551_APPID_PEDOMETER,
471 MMA9553_REG_STEPCNT,
472 &tmp);
473 mutex_unlock(&data->mutex);
474 if (ret < 0)
475 return ret;
476 *val = tmp;
477 return IIO_VAL_INT;
478 case IIO_DISTANCE:
479 powered_on =
480 mma9553_is_any_event_enabled(data, false, 0) ||
481 data->stepcnt_enabled;
482 if (!powered_on) {
483 dev_err(&data->client->dev,
484 "No channels enabled\n");
485 return -EINVAL;
486 }
487 mutex_lock(&data->mutex);
488 ret = mma9551_read_status_word(data->client,
489 MMA9551_APPID_PEDOMETER,
490 MMA9553_REG_DISTANCE,
491 &tmp);
492 mutex_unlock(&data->mutex);
493 if (ret < 0)
494 return ret;
495 *val = tmp;
496 return IIO_VAL_INT;
497 case IIO_ACTIVITY:
498 powered_on =
499 mma9553_is_any_event_enabled(data, false, 0) ||
500 data->stepcnt_enabled;
501 if (!powered_on) {
502 dev_err(&data->client->dev,
503 "No channels enabled\n");
504 return -EINVAL;
505 }
506 mutex_lock(&data->mutex);
507 ret = mma9551_read_status_word(data->client,
508 MMA9551_APPID_PEDOMETER,
509 MMA9553_REG_STATUS,
510 &tmp);
511 mutex_unlock(&data->mutex);
512 if (ret < 0)
513 return ret;
514
515 activity =
516 mma9553_get_bits(tmp, MMA9553_MASK_STATUS_ACTIVITY);
517
518 /*
519 * The device does not support confidence value levels,
520 * so we will always have 100% for current activity and
521 * 0% for the others.
522 */
523 if (chan->channel2 == mma9553_activity_to_mod(activity))
524 *val = 100;
525 else
526 *val = 0;
527 return IIO_VAL_INT;
528 default:
529 return -EINVAL;
530 }
531 case IIO_CHAN_INFO_RAW:
532 switch (chan->type) {
533 case IIO_VELOCITY: /* m/h */
534 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
535 return -EINVAL;
536 powered_on =
537 mma9553_is_any_event_enabled(data, false, 0) ||
538 data->stepcnt_enabled;
539 if (!powered_on) {
540 dev_err(&data->client->dev,
541 "No channels enabled\n");
542 return -EINVAL;
543 }
544 mutex_lock(&data->mutex);
545 ret = mma9551_read_status_word(data->client,
546 MMA9551_APPID_PEDOMETER,
547 MMA9553_REG_SPEED, &tmp);
548 mutex_unlock(&data->mutex);
549 if (ret < 0)
550 return ret;
551 *val = tmp;
552 return IIO_VAL_INT;
553 case IIO_ENERGY: /* Cal or kcal */
554 powered_on =
555 mma9553_is_any_event_enabled(data, false, 0) ||
556 data->stepcnt_enabled;
557 if (!powered_on) {
558 dev_err(&data->client->dev,
559 "No channels enabled\n");
560 return -EINVAL;
561 }
562 mutex_lock(&data->mutex);
563 ret = mma9551_read_status_word(data->client,
564 MMA9551_APPID_PEDOMETER,
565 MMA9553_REG_CALORIES,
566 &tmp);
567 mutex_unlock(&data->mutex);
568 if (ret < 0)
569 return ret;
570 *val = tmp;
571 return IIO_VAL_INT;
572 case IIO_ACCEL:
573 mutex_lock(&data->mutex);
574 ret = mma9551_read_accel_chan(data->client,
575 chan, val, val2);
576 mutex_unlock(&data->mutex);
577 return ret;
578 default:
579 return -EINVAL;
580 }
581 case IIO_CHAN_INFO_SCALE:
582 switch (chan->type) {
583 case IIO_VELOCITY: /* m/h to m/s */
584 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
585 return -EINVAL;
586 *val = 0;
587 *val2 = 277; /* 0.000277 */
588 return IIO_VAL_INT_PLUS_MICRO;
589 case IIO_ENERGY: /* Cal or kcal to J */
590 *val = 4184;
591 return IIO_VAL_INT;
592 case IIO_ACCEL:
593 return mma9551_read_accel_scale(val, val2);
594 default:
595 return -EINVAL;
596 }
597 case IIO_CHAN_INFO_ENABLE:
598 *val = data->stepcnt_enabled;
599 return IIO_VAL_INT;
600 case IIO_CHAN_INFO_CALIBHEIGHT:
601 tmp = mma9553_get_bits(data->conf.height_weight,
602 MMA9553_MASK_CONF_HEIGHT);
603 *val = tmp / 100; /* cm to m */
604 *val2 = (tmp % 100) * 10000;
605 return IIO_VAL_INT_PLUS_MICRO;
606 case IIO_CHAN_INFO_CALIBWEIGHT:
607 *val = mma9553_get_bits(data->conf.height_weight,
608 MMA9553_MASK_CONF_WEIGHT);
609 return IIO_VAL_INT;
610 case IIO_CHAN_INFO_DEBOUNCE_COUNT:
611 switch (chan->type) {
612 case IIO_STEPS:
613 *val = mma9553_get_bits(data->conf.filter,
614 MMA9553_MASK_CONF_FILTSTEP);
615 return IIO_VAL_INT;
616 default:
617 return -EINVAL;
618 }
619 case IIO_CHAN_INFO_DEBOUNCE_TIME:
620 switch (chan->type) {
621 case IIO_STEPS:
622 *val = mma9553_get_bits(data->conf.filter,
623 MMA9553_MASK_CONF_FILTTIME);
624 return IIO_VAL_INT;
625 default:
626 return -EINVAL;
627 }
628 case IIO_CHAN_INFO_INT_TIME:
629 switch (chan->type) {
630 case IIO_VELOCITY:
631 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
632 return -EINVAL;
633 *val = mma9553_get_bits(data->conf.speed_step,
634 MMA9553_MASK_CONF_SPDPRD);
635 return IIO_VAL_INT;
636 default:
637 return -EINVAL;
638 }
639 default:
640 return -EINVAL;
641 }
642}
643
644static int mma9553_write_raw(struct iio_dev *indio_dev,
645 struct iio_chan_spec const *chan,
646 int val, int val2, long mask)
647{
648 struct mma9553_data *data = iio_priv(indio_dev);
649 int ret, tmp;
650
651 switch (mask) {
652 case IIO_CHAN_INFO_ENABLE:
653 if (data->stepcnt_enabled == !!val)
654 return 0;
655 mutex_lock(&data->mutex);
656 ret = mma9551_set_power_state(data->client, val);
657 if (ret < 0) {
658 mutex_unlock(&data->mutex);
659 return ret;
660 }
661 data->stepcnt_enabled = val;
662 mutex_unlock(&data->mutex);
663 return 0;
664 case IIO_CHAN_INFO_CALIBHEIGHT:
665 /* m to cm */
666 tmp = val * 100 + val2 / 10000;
667 if (tmp < 0 || tmp > 255)
668 return -EINVAL;
669 mutex_lock(&data->mutex);
670 ret = mma9553_set_config(data,
671 MMA9553_REG_CONF_HEIGHT_WEIGHT,
672 &data->conf.height_weight,
673 tmp, MMA9553_MASK_CONF_HEIGHT);
674 mutex_unlock(&data->mutex);
675 return ret;
676 case IIO_CHAN_INFO_CALIBWEIGHT:
677 if (val < 0 || val > 255)
678 return -EINVAL;
679 mutex_lock(&data->mutex);
680 ret = mma9553_set_config(data,
681 MMA9553_REG_CONF_HEIGHT_WEIGHT,
682 &data->conf.height_weight,
683 val, MMA9553_MASK_CONF_WEIGHT);
684 mutex_unlock(&data->mutex);
685 return ret;
686 case IIO_CHAN_INFO_DEBOUNCE_COUNT:
687 switch (chan->type) {
688 case IIO_STEPS:
689 /*
690 * Set to 0 to disable step filtering. If the value
691 * specified is greater than 6, then 6 will be used.
692 */
693 if (val < 0)
694 return -EINVAL;
695 if (val > 6)
696 val = 6;
697 mutex_lock(&data->mutex);
698 ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,
699 &data->conf.filter, val,
700 MMA9553_MASK_CONF_FILTSTEP);
701 mutex_unlock(&data->mutex);
702 return ret;
703 default:
704 return -EINVAL;
705 }
706 case IIO_CHAN_INFO_DEBOUNCE_TIME:
707 switch (chan->type) {
708 case IIO_STEPS:
709 if (val < 0 || val > 127)
710 return -EINVAL;
711 mutex_lock(&data->mutex);
712 ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,
713 &data->conf.filter, val,
714 MMA9553_MASK_CONF_FILTTIME);
715 mutex_unlock(&data->mutex);
716 return ret;
717 default:
718 return -EINVAL;
719 }
720 case IIO_CHAN_INFO_INT_TIME:
721 switch (chan->type) {
722 case IIO_VELOCITY:
723 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
724 return -EINVAL;
725 /*
726 * If set to a value greater than 5, then 5 will be
727 * used. Warning: Do not set SPDPRD to 0 or 1 as
728 * this may cause undesirable behavior.
729 */
730 if (val < 2)
731 return -EINVAL;
732 if (val > 5)
733 val = 5;
734 mutex_lock(&data->mutex);
735 ret = mma9553_set_config(data,
736 MMA9553_REG_CONF_SPEED_STEP,
737 &data->conf.speed_step, val,
738 MMA9553_MASK_CONF_SPDPRD);
739 mutex_unlock(&data->mutex);
740 return ret;
741 default:
742 return -EINVAL;
743 }
744 default:
745 return -EINVAL;
746 }
747}
748
749static int mma9553_read_event_config(struct iio_dev *indio_dev,
750 const struct iio_chan_spec *chan,
751 enum iio_event_type type,
752 enum iio_event_direction dir)
753{
754
755 struct mma9553_data *data = iio_priv(indio_dev);
756 struct mma9553_event *event;
757
758 event = mma9553_get_event(data, chan->type, chan->channel2, dir);
759 if (!event)
760 return -EINVAL;
761
762 return event->enabled;
763}
764
765static int mma9553_write_event_config(struct iio_dev *indio_dev,
766 const struct iio_chan_spec *chan,
767 enum iio_event_type type,
768 enum iio_event_direction dir, int state)
769{
770 struct mma9553_data *data = iio_priv(indio_dev);
771 struct mma9553_event *event;
772 int ret;
773
774 event = mma9553_get_event(data, chan->type, chan->channel2, dir);
775 if (!event)
776 return -EINVAL;
777
778 if (event->enabled == state)
779 return 0;
780
781 mutex_lock(&data->mutex);
782
783 ret = mma9551_set_power_state(data->client, state);
784 if (ret < 0)
785 goto err_out;
786 event->enabled = state;
787
788 ret = mma9553_conf_gpio(data);
789 if (ret < 0)
790 goto err_conf_gpio;
791
792 mutex_unlock(&data->mutex);
793
794 return ret;
795
796err_conf_gpio:
797 if (state) {
798 event->enabled = false;
799 mma9551_set_power_state(data->client, false);
800 }
801err_out:
802 mutex_unlock(&data->mutex);
803 return ret;
804}
805
806static int mma9553_read_event_value(struct iio_dev *indio_dev,
807 const struct iio_chan_spec *chan,
808 enum iio_event_type type,
809 enum iio_event_direction dir,
810 enum iio_event_info info,
811 int *val, int *val2)
812{
813 struct mma9553_data *data = iio_priv(indio_dev);
814
815 *val2 = 0;
816 switch (info) {
817 case IIO_EV_INFO_VALUE:
818 switch (chan->type) {
819 case IIO_STEPS:
820 *val = mma9553_get_bits(data->conf.speed_step,
821 MMA9553_MASK_CONF_STEPCOALESCE);
822 return IIO_VAL_INT;
823 case IIO_ACTIVITY:
824 /*
825 * The device does not support confidence value levels.
826 * We set an average of 50%.
827 */
828 *val = 50;
829 return IIO_VAL_INT;
830 default:
831 return -EINVAL;
832 }
833 case IIO_EV_INFO_PERIOD:
834 switch (chan->type) {
835 case IIO_ACTIVITY:
836 *val = MMA9553_ACTIVITY_THD_TO_SEC(data->conf.actthd);
837 return IIO_VAL_INT;
838 default:
839 return -EINVAL;
840 }
841 default:
842 return -EINVAL;
843 }
844}
845
846static int mma9553_write_event_value(struct iio_dev *indio_dev,
847 const struct iio_chan_spec *chan,
848 enum iio_event_type type,
849 enum iio_event_direction dir,
850 enum iio_event_info info,
851 int val, int val2)
852{
853 struct mma9553_data *data = iio_priv(indio_dev);
854 int ret;
855
856 switch (info) {
857 case IIO_EV_INFO_VALUE:
858 switch (chan->type) {
859 case IIO_STEPS:
860 if (val < 0 || val > 255)
861 return -EINVAL;
862 mutex_lock(&data->mutex);
863 ret = mma9553_set_config(data,
864 MMA9553_REG_CONF_SPEED_STEP,
865 &data->conf.speed_step, val,
866 MMA9553_MASK_CONF_STEPCOALESCE);
867 mutex_unlock(&data->mutex);
868 return ret;
869 default:
870 return -EINVAL;
871 }
872 case IIO_EV_INFO_PERIOD:
873 switch (chan->type) {
874 case IIO_ACTIVITY:
875 mutex_lock(&data->mutex);
876 ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD,
877 &data->conf.actthd,
878 MMA9553_ACTIVITY_SEC_TO_THD
879 (val), MMA9553_MASK_CONF_WORD);
880 mutex_unlock(&data->mutex);
881 return ret;
882 default:
883 return -EINVAL;
884 }
885 default:
886 return -EINVAL;
887 }
888}
889
890static int mma9553_get_calibgender_mode(struct iio_dev *indio_dev,
891 const struct iio_chan_spec *chan)
892{
893 struct mma9553_data *data = iio_priv(indio_dev);
894 u8 gender;
895
896 gender = mma9553_get_bits(data->conf.filter, MMA9553_MASK_CONF_MALE);
897 /*
898 * HW expects 0 for female and 1 for male,
899 * while iio index is 0 for male and 1 for female
900 */
901 return !gender;
902}
903
904static int mma9553_set_calibgender_mode(struct iio_dev *indio_dev,
905 const struct iio_chan_spec *chan,
906 unsigned int mode)
907{
908 struct mma9553_data *data = iio_priv(indio_dev);
909 u8 gender = !mode;
910 int ret;
911
912 if ((mode != 0) && (mode != 1))
913 return -EINVAL;
914 mutex_lock(&data->mutex);
915 ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,
916 &data->conf.filter, gender,
917 MMA9553_MASK_CONF_MALE);
918 mutex_unlock(&data->mutex);
919
920 return ret;
921}
922
923static const struct iio_event_spec mma9553_step_event = {
924 .type = IIO_EV_TYPE_CHANGE,
925 .dir = IIO_EV_DIR_NONE,
926 .mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_VALUE),
927};
928
929static const struct iio_event_spec mma9553_activity_events[] = {
930 {
931 .type = IIO_EV_TYPE_THRESH,
932 .dir = IIO_EV_DIR_RISING,
933 .mask_separate = BIT(IIO_EV_INFO_ENABLE) |
934 BIT(IIO_EV_INFO_VALUE) |
935 BIT(IIO_EV_INFO_PERIOD),
936 },
937 {
938 .type = IIO_EV_TYPE_THRESH,
939 .dir = IIO_EV_DIR_FALLING,
940 .mask_separate = BIT(IIO_EV_INFO_ENABLE) |
941 BIT(IIO_EV_INFO_VALUE) |
942 BIT(IIO_EV_INFO_PERIOD),
943 },
944};
945
946static const char * const calibgender_modes[] = { "male", "female" };
947
948static const struct iio_enum mma9553_calibgender_enum = {
949 .items = calibgender_modes,
950 .num_items = ARRAY_SIZE(calibgender_modes),
951 .get = mma9553_get_calibgender_mode,
952 .set = mma9553_set_calibgender_mode,
953};
954
955static const struct iio_chan_spec_ext_info mma9553_ext_info[] = {
956 IIO_ENUM("calibgender", IIO_SHARED_BY_TYPE, &mma9553_calibgender_enum),
957 IIO_ENUM_AVAILABLE("calibgender", &mma9553_calibgender_enum),
958 {},
959};
960
961#define MMA9553_PEDOMETER_CHANNEL(_type, _mask) { \
962 .type = _type, \
963 .info_mask_separate = BIT(IIO_CHAN_INFO_ENABLE) | \
964 BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \
965 _mask, \
966 .ext_info = mma9553_ext_info, \
967}
968
969#define MMA9553_ACTIVITY_CHANNEL(_chan2) { \
970 .type = IIO_ACTIVITY, \
971 .modified = 1, \
972 .channel2 = _chan2, \
973 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
974 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT), \
975 .event_spec = mma9553_activity_events, \
976 .num_event_specs = ARRAY_SIZE(mma9553_activity_events), \
977 .ext_info = mma9553_ext_info, \
978}
979
980static const struct iio_chan_spec mma9553_channels[] = {
981 MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
982 MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
983 MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
984
985 {
986 .type = IIO_STEPS,
987 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
988 BIT(IIO_CHAN_INFO_ENABLE) |
989 BIT(IIO_CHAN_INFO_DEBOUNCE_COUNT) |
990 BIT(IIO_CHAN_INFO_DEBOUNCE_TIME),
991 .event_spec = &mma9553_step_event,
992 .num_event_specs = 1,
993 },
994
995 MMA9553_PEDOMETER_CHANNEL(IIO_DISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)),
996 {
997 .type = IIO_VELOCITY,
998 .modified = 1,
999 .channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,
1000 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1001 BIT(IIO_CHAN_INFO_SCALE) |
1002 BIT(IIO_CHAN_INFO_INT_TIME) |
1003 BIT(IIO_CHAN_INFO_ENABLE),
1004 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT),
1005 .ext_info = mma9553_ext_info,
1006 },
1007 MMA9553_PEDOMETER_CHANNEL(IIO_ENERGY, BIT(IIO_CHAN_INFO_RAW) |
1008 BIT(IIO_CHAN_INFO_SCALE) |
1009 BIT(IIO_CHAN_INFO_CALIBWEIGHT)),
1010
1011 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_RUNNING),
1012 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_JOGGING),
1013 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_WALKING),
1014 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_STILL),
1015};
1016
1017static const struct iio_info mma9553_info = {
1018 .driver_module = THIS_MODULE,
1019 .read_raw = mma9553_read_raw,
1020 .write_raw = mma9553_write_raw,
1021 .read_event_config = mma9553_read_event_config,
1022 .write_event_config = mma9553_write_event_config,
1023 .read_event_value = mma9553_read_event_value,
1024 .write_event_value = mma9553_write_event_value,
1025};
1026
1027static irqreturn_t mma9553_irq_handler(int irq, void *private)
1028{
1029 struct iio_dev *indio_dev = private;
1030 struct mma9553_data *data = iio_priv(indio_dev);
1031
1032 data->timestamp = iio_get_time_ns();
1033 /*
1034 * Since we only configure the interrupt pin when an
1035 * event is enabled, we are sure we have at least
1036 * one event enabled at this point.
1037 */
1038 return IRQ_WAKE_THREAD;
1039}
1040
1041static irqreturn_t mma9553_event_handler(int irq, void *private)
1042{
1043 struct iio_dev *indio_dev = private;
1044 struct mma9553_data *data = iio_priv(indio_dev);
1045 u16 stepcnt;
1046 u8 activity;
1047 struct mma9553_event *ev_activity, *ev_prev_activity, *ev_step_detect;
1048 int ret;
1049
1050 mutex_lock(&data->mutex);
1051 ret = mma9553_read_activity_stepcnt(data, &activity, &stepcnt);
1052 if (ret < 0) {
1053 mutex_unlock(&data->mutex);
1054 return IRQ_HANDLED;
1055 }
1056
1057 ev_prev_activity =
1058 mma9553_get_event(data, IIO_ACTIVITY,
1059 mma9553_activity_to_mod(data->activity),
1060 IIO_EV_DIR_FALLING);
1061 ev_activity =
1062 mma9553_get_event(data, IIO_ACTIVITY,
1063 mma9553_activity_to_mod(activity),
1064 IIO_EV_DIR_RISING);
1065 ev_step_detect =
1066 mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
1067
1068 if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {
1069 data->stepcnt = stepcnt;
1070 iio_push_event(indio_dev,
1071 IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
1072 IIO_EV_DIR_NONE, IIO_EV_TYPE_CHANGE, 0, 0, 0),
1073 data->timestamp);
1074 }
1075
1076 if (activity != data->activity) {
1077 data->activity = activity;
1078 /* ev_activity can be NULL if activity == ACTIVITY_UNKNOWN */
1079 if (ev_prev_activity && ev_prev_activity->enabled)
1080 iio_push_event(indio_dev,
1081 IIO_EVENT_CODE(IIO_ACTIVITY, 0,
1082 ev_prev_activity->info->mod,
1083 IIO_EV_DIR_FALLING,
1084 IIO_EV_TYPE_THRESH, 0, 0, 0),
1085 data->timestamp);
1086
1087 if (ev_activity && ev_activity->enabled)
1088 iio_push_event(indio_dev,
1089 IIO_EVENT_CODE(IIO_ACTIVITY, 0,
1090 ev_activity->info->mod,
1091 IIO_EV_DIR_RISING,
1092 IIO_EV_TYPE_THRESH, 0, 0, 0),
1093 data->timestamp);
1094 }
1095 mutex_unlock(&data->mutex);
1096
1097 return IRQ_HANDLED;
1098}
1099
1100static int mma9553_gpio_probe(struct i2c_client *client)
1101{
1102 struct device *dev;
1103 struct gpio_desc *gpio;
1104 int ret;
1105
1106 if (!client)
1107 return -EINVAL;
1108
1109 dev = &client->dev;
1110
1111 /* data ready gpio interrupt pin */
1112 gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0);
1113 if (IS_ERR(gpio)) {
1114 dev_err(dev, "acpi gpio get index failed\n");
1115 return PTR_ERR(gpio);
1116 }
1117
1118 ret = gpiod_direction_input(gpio);
1119 if (ret)
1120 return ret;
1121
1122 ret = gpiod_to_irq(gpio);
1123
1124 dev_dbg(dev, "gpio resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
1125
1126 return ret;
1127}
1128
1129static const char *mma9553_match_acpi_device(struct device *dev)
1130{
1131 const struct acpi_device_id *id;
1132
1133 id = acpi_match_device(dev->driver->acpi_match_table, dev);
1134 if (!id)
1135 return NULL;
1136
1137 return dev_name(dev);
1138}
1139
1140static int mma9553_probe(struct i2c_client *client,
1141 const struct i2c_device_id *id)
1142{
1143 struct mma9553_data *data;
1144 struct iio_dev *indio_dev;
1145 const char *name = NULL;
1146 int ret;
1147
1148 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1149 if (!indio_dev)
1150 return -ENOMEM;
1151
1152 data = iio_priv(indio_dev);
1153 i2c_set_clientdata(client, indio_dev);
1154 data->client = client;
1155
1156 if (id)
1157 name = id->name;
1158 else if (ACPI_HANDLE(&client->dev))
1159 name = mma9553_match_acpi_device(&client->dev);
1160 else
1161 return -ENOSYS;
1162
1163 mutex_init(&data->mutex);
1164 mma9553_init_events(data);
1165
1166 ret = mma9553_init(data);
1167 if (ret < 0)
1168 return ret;
1169
1170 indio_dev->dev.parent = &client->dev;
1171 indio_dev->channels = mma9553_channels;
1172 indio_dev->num_channels = ARRAY_SIZE(mma9553_channels);
1173 indio_dev->name = name;
1174 indio_dev->modes = INDIO_DIRECT_MODE;
1175 indio_dev->info = &mma9553_info;
1176
1177 if (client->irq < 0)
1178 client->irq = mma9553_gpio_probe(client);
1179
1180 if (client->irq >= 0) {
1181 ret = devm_request_threaded_irq(&client->dev, client->irq,
1182 mma9553_irq_handler,
1183 mma9553_event_handler,
1184 IRQF_TRIGGER_RISING,
1185 MMA9553_IRQ_NAME, indio_dev);
1186 if (ret < 0) {
1187 dev_err(&client->dev, "request irq %d failed\n",
1188 client->irq);
1189 goto out_poweroff;
1190 }
1191
1192 }
1193
1194 ret = iio_device_register(indio_dev);
1195 if (ret < 0) {
1196 dev_err(&client->dev, "unable to register iio device\n");
1197 goto out_poweroff;
1198 }
1199
1200 ret = pm_runtime_set_active(&client->dev);
1201 if (ret < 0)
1202 goto out_iio_unregister;
1203
1204 pm_runtime_enable(&client->dev);
1205 pm_runtime_set_autosuspend_delay(&client->dev,
1206 MMA9551_AUTO_SUSPEND_DELAY_MS);
1207 pm_runtime_use_autosuspend(&client->dev);
1208
1209 dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
1210
1211 return 0;
1212
1213out_iio_unregister:
1214 iio_device_unregister(indio_dev);
1215out_poweroff:
1216 mma9551_set_device_state(client, false);
1217 return ret;
1218}
1219
1220static int mma9553_remove(struct i2c_client *client)
1221{
1222 struct iio_dev *indio_dev = i2c_get_clientdata(client);
1223 struct mma9553_data *data = iio_priv(indio_dev);
1224
1225 pm_runtime_disable(&client->dev);
1226 pm_runtime_set_suspended(&client->dev);
1227 pm_runtime_put_noidle(&client->dev);
1228
1229 iio_device_unregister(indio_dev);
1230 mutex_lock(&data->mutex);
1231 mma9551_set_device_state(data->client, false);
1232 mutex_unlock(&data->mutex);
1233
1234 return 0;
1235}
1236
1237#ifdef CONFIG_PM
1238static int mma9553_runtime_suspend(struct device *dev)
1239{
1240 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1241 struct mma9553_data *data = iio_priv(indio_dev);
1242 int ret;
1243
1244 mutex_lock(&data->mutex);
1245 ret = mma9551_set_device_state(data->client, false);
1246 mutex_unlock(&data->mutex);
1247 if (ret < 0) {
1248 dev_err(&data->client->dev, "powering off device failed\n");
1249 return -EAGAIN;
1250 }
1251
1252 return 0;
1253}
1254
1255static int mma9553_runtime_resume(struct device *dev)
1256{
1257 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1258 struct mma9553_data *data = iio_priv(indio_dev);
1259 int ret;
1260
1261 ret = mma9551_set_device_state(data->client, true);
1262 if (ret < 0)
1263 return ret;
1264
1265 mma9551_sleep(MMA9553_DEFAULT_SAMPLE_RATE);
1266
1267 return 0;
1268}
1269#endif
1270
1271#ifdef CONFIG_PM_SLEEP
1272static int mma9553_suspend(struct device *dev)
1273{
1274 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1275 struct mma9553_data *data = iio_priv(indio_dev);
1276 int ret;
1277
1278 mutex_lock(&data->mutex);
1279 ret = mma9551_set_device_state(data->client, false);
1280 mutex_unlock(&data->mutex);
1281
1282 return ret;
1283}
1284
1285static int mma9553_resume(struct device *dev)
1286{
1287 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1288 struct mma9553_data *data = iio_priv(indio_dev);
1289 int ret;
1290
1291 mutex_lock(&data->mutex);
1292 ret = mma9551_set_device_state(data->client, true);
1293 mutex_unlock(&data->mutex);
1294
1295 return ret;
1296}
1297#endif
1298
1299static const struct dev_pm_ops mma9553_pm_ops = {
1300 SET_SYSTEM_SLEEP_PM_OPS(mma9553_suspend, mma9553_resume)
1301 SET_RUNTIME_PM_OPS(mma9553_runtime_suspend,
1302 mma9553_runtime_resume, NULL)
1303};
1304
1305static const struct acpi_device_id mma9553_acpi_match[] = {
1306 {"MMA9553", 0},
1307 {},
1308};
1309
1310MODULE_DEVICE_TABLE(acpi, mma9553_acpi_match);
1311
1312static const struct i2c_device_id mma9553_id[] = {
1313 {"mma9553", 0},
1314 {},
1315};
1316
1317MODULE_DEVICE_TABLE(i2c, mma9553_id);
1318
1319static struct i2c_driver mma9553_driver = {
1320 .driver = {
1321 .name = MMA9553_DRV_NAME,
1322 .acpi_match_table = ACPI_PTR(mma9553_acpi_match),
1323 .pm = &mma9553_pm_ops,
1324 },
1325 .probe = mma9553_probe,
1326 .remove = mma9553_remove,
1327 .id_table = mma9553_id,
1328};
1329
1330module_i2c_driver(mma9553_driver);
1331
1332MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
1333MODULE_LICENSE("GPL v2");
1334MODULE_DESCRIPTION("MMA9553L pedometer platform driver");
diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c
new file mode 100644
index 000000000000..4ae05fce9f24
--- /dev/null
+++ b/drivers/iio/accel/ssp_accel_sensor.c
@@ -0,0 +1,169 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/iio/common/ssp_sensors.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/kfifo_buf.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include "../common/ssp_sensors/ssp_iio_sensor.h"
23
24#define SSP_CHANNEL_COUNT 3
25
26#define SSP_ACCEL_NAME "ssp-accelerometer"
27static const char ssp_accel_device_name[] = SSP_ACCEL_NAME;
28
29enum ssp_accel_3d_channel {
30 SSP_CHANNEL_SCAN_INDEX_X,
31 SSP_CHANNEL_SCAN_INDEX_Y,
32 SSP_CHANNEL_SCAN_INDEX_Z,
33 SSP_CHANNEL_SCAN_INDEX_TIME,
34};
35
36static int ssp_accel_read_raw(struct iio_dev *indio_dev,
37 struct iio_chan_spec const *chan, int *val,
38 int *val2, long mask)
39{
40 u32 t;
41 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
42
43 switch (mask) {
44 case IIO_CHAN_INFO_SAMP_FREQ:
45 t = ssp_get_sensor_delay(data, SSP_ACCELEROMETER_SENSOR);
46 ssp_convert_to_freq(t, val, val2);
47 return IIO_VAL_INT_PLUS_MICRO;
48 default:
49 break;
50 }
51
52 return -EINVAL;
53}
54
55static int ssp_accel_write_raw(struct iio_dev *indio_dev,
56 struct iio_chan_spec const *chan, int val,
57 int val2, long mask)
58{
59 int ret;
60 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
61
62 switch (mask) {
63 case IIO_CHAN_INFO_SAMP_FREQ:
64 ret = ssp_convert_to_time(val, val2);
65 ret = ssp_change_delay(data, SSP_ACCELEROMETER_SENSOR, ret);
66 if (ret < 0)
67 dev_err(&indio_dev->dev, "accel sensor enable fail\n");
68
69 return ret;
70 default:
71 break;
72 }
73
74 return -EINVAL;
75}
76
77static struct iio_info ssp_accel_iio_info = {
78 .read_raw = &ssp_accel_read_raw,
79 .write_raw = &ssp_accel_write_raw,
80};
81
82static const unsigned long ssp_accel_scan_mask[] = { 0x7, 0, };
83
84static const struct iio_chan_spec ssp_acc_channels[] = {
85 SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
86 SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
87 SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
88 SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
89};
90
91static int ssp_process_accel_data(struct iio_dev *indio_dev, void *buf,
92 int64_t timestamp)
93{
94 return ssp_common_process_data(indio_dev, buf, SSP_ACCELEROMETER_SIZE,
95 timestamp);
96}
97
98static const struct iio_buffer_setup_ops ssp_accel_buffer_ops = {
99 .postenable = &ssp_common_buffer_postenable,
100 .postdisable = &ssp_common_buffer_postdisable,
101};
102
103static int ssp_accel_probe(struct platform_device *pdev)
104{
105 int ret;
106 struct iio_dev *indio_dev;
107 struct ssp_sensor_data *spd;
108 struct iio_buffer *buffer;
109
110 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));
111 if (!indio_dev)
112 return -ENOMEM;
113
114 spd = iio_priv(indio_dev);
115
116 spd->process_data = ssp_process_accel_data;
117 spd->type = SSP_ACCELEROMETER_SENSOR;
118
119 indio_dev->name = ssp_accel_device_name;
120 indio_dev->dev.parent = &pdev->dev;
121 indio_dev->dev.of_node = pdev->dev.of_node;
122 indio_dev->info = &ssp_accel_iio_info;
123 indio_dev->modes = INDIO_BUFFER_SOFTWARE;
124 indio_dev->channels = ssp_acc_channels;
125 indio_dev->num_channels = ARRAY_SIZE(ssp_acc_channels);
126 indio_dev->available_scan_masks = ssp_accel_scan_mask;
127
128 buffer = devm_iio_kfifo_allocate(&pdev->dev);
129 if (!buffer)
130 return -ENOMEM;
131
132 iio_device_attach_buffer(indio_dev, buffer);
133
134 indio_dev->setup_ops = &ssp_accel_buffer_ops;
135
136 platform_set_drvdata(pdev, indio_dev);
137
138 ret = iio_device_register(indio_dev);
139 if (ret < 0)
140 return ret;
141
142 /* ssp registering should be done after all iio setup */
143 ssp_register_consumer(indio_dev, SSP_ACCELEROMETER_SENSOR);
144
145 return 0;
146}
147
148static int ssp_accel_remove(struct platform_device *pdev)
149{
150 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
151
152 iio_device_unregister(indio_dev);
153
154 return 0;
155}
156
157static struct platform_driver ssp_accel_driver = {
158 .driver = {
159 .name = SSP_ACCEL_NAME,
160 },
161 .probe = ssp_accel_probe,
162 .remove = ssp_accel_remove,
163};
164
165module_platform_driver(ssp_accel_driver);
166
167MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
168MODULE_DESCRIPTION("Samsung sensorhub accelerometers driver");
169MODULE_LICENSE("GPL");
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 0f79e4725763..202daf889be2 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -135,6 +135,17 @@ config AXP288_ADC
135 device. Depending on platform configuration, this general purpose ADC can 135 device. Depending on platform configuration, this general purpose ADC can
136 be used for sampling sensors such as thermal resistors. 136 be used for sampling sensors such as thermal resistors.
137 137
138config CC10001_ADC
139 tristate "Cosmic Circuits 10001 ADC driver"
140 depends on HAS_IOMEM || HAVE_CLK || REGULATOR
141 select IIO_BUFFER
142 select IIO_TRIGGERED_BUFFER
143 help
144 Say yes here to build support for Cosmic Circuits 10001 ADC.
145
146 This driver can also be built as a module. If so, the module will be
147 called cc10001_adc.
148
138config EXYNOS_ADC 149config EXYNOS_ADC
139 tristate "Exynos ADC driver support" 150 tristate "Exynos ADC driver support"
140 depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST) 151 depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
@@ -228,6 +239,20 @@ config QCOM_SPMI_IADC
228 To compile this driver as a module, choose M here: the module will 239 To compile this driver as a module, choose M here: the module will
229 be called qcom-spmi-iadc. 240 be called qcom-spmi-iadc.
230 241
242config QCOM_SPMI_VADC
243 tristate "Qualcomm SPMI PMIC voltage ADC"
244 depends on SPMI
245 select REGMAP_SPMI
246 help
247 This is the IIO Voltage ADC driver for Qualcomm QPNP VADC Chip.
248
249 The driver supports multiple channels read. The VADC is a 15-bit
250 sigma-delta ADC. Some of the channels are internally used for
251 calibration.
252
253 To compile this driver as a module, choose M here: the module will
254 be called qcom-spmi-vadc.
255
231config ROCKCHIP_SARADC 256config ROCKCHIP_SARADC
232 tristate "Rockchip SARADC driver" 257 tristate "Rockchip SARADC driver"
233 depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) 258 depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 701fdb7c96aa..0315af640866 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
15obj-$(CONFIG_AD799X) += ad799x.o 15obj-$(CONFIG_AD799X) += ad799x.o
16obj-$(CONFIG_AT91_ADC) += at91_adc.o 16obj-$(CONFIG_AT91_ADC) += at91_adc.o
17obj-$(CONFIG_AXP288_ADC) += axp288_adc.o 17obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
18obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
18obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o 19obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
19obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o 20obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
20obj-$(CONFIG_MAX1027) += max1027.o 21obj-$(CONFIG_MAX1027) += max1027.o
@@ -24,6 +25,7 @@ obj-$(CONFIG_MCP3422) += mcp3422.o
24obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o 25obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
25obj-$(CONFIG_NAU7802) += nau7802.o 26obj-$(CONFIG_NAU7802) += nau7802.o
26obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o 27obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
28obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
27obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o 29obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
28obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o 30obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
29obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o 31obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
new file mode 100644
index 000000000000..51e2a83c9404
--- /dev/null
+++ b/drivers/iio/adc/cc10001_adc.c
@@ -0,0 +1,423 @@
1/*
2 * Copyright (c) 2014-2015 Imagination Technologies Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 */
9
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/err.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/of_device.h>
17#include <linux/platform_device.h>
18#include <linux/regulator/consumer.h>
19#include <linux/slab.h>
20
21#include <linux/iio/buffer.h>
22#include <linux/iio/iio.h>
23#include <linux/iio/sysfs.h>
24#include <linux/iio/trigger.h>
25#include <linux/iio/trigger_consumer.h>
26#include <linux/iio/triggered_buffer.h>
27
28/* Registers */
29#define CC10001_ADC_CONFIG 0x00
30#define CC10001_ADC_START_CONV BIT(4)
31#define CC10001_ADC_MODE_SINGLE_CONV BIT(5)
32
33#define CC10001_ADC_DDATA_OUT 0x04
34#define CC10001_ADC_EOC 0x08
35#define CC10001_ADC_EOC_SET BIT(0)
36
37#define CC10001_ADC_CHSEL_SAMPLED 0x0c
38#define CC10001_ADC_POWER_UP 0x10
39#define CC10001_ADC_POWER_UP_SET BIT(0)
40#define CC10001_ADC_DEBUG 0x14
41#define CC10001_ADC_DATA_COUNT 0x20
42
43#define CC10001_ADC_DATA_MASK GENMASK(9, 0)
44#define CC10001_ADC_NUM_CHANNELS 8
45#define CC10001_ADC_CH_MASK GENMASK(2, 0)
46
47#define CC10001_INVALID_SAMPLED 0xffff
48#define CC10001_MAX_POLL_COUNT 20
49
50/*
51 * As per device specification, wait six clock cycles after power-up to
52 * activate START. Since adding two more clock cycles delay does not
53 * impact the performance too much, we are adding two additional cycles delay
54 * intentionally here.
55 */
56#define CC10001_WAIT_CYCLES 8
57
58struct cc10001_adc_device {
59 void __iomem *reg_base;
60 struct clk *adc_clk;
61 struct regulator *reg;
62 u16 *buf;
63
64 struct mutex lock;
65 unsigned long channel_map;
66 unsigned int start_delay_ns;
67 unsigned int eoc_delay_ns;
68};
69
70static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
71 u32 reg, u32 val)
72{
73 writel(val, adc_dev->reg_base + reg);
74}
75
76static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
77 u32 reg)
78{
79 return readl(adc_dev->reg_base + reg);
80}
81
82static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
83 unsigned int channel)
84{
85 u32 val;
86
87 /* Channel selection and mode of operation */
88 val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
89 cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
90
91 val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
92 val = val | CC10001_ADC_START_CONV;
93 cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
94}
95
96static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
97 unsigned int channel,
98 unsigned int delay)
99{
100 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
101 unsigned int poll_count = 0;
102
103 while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
104 CC10001_ADC_EOC_SET)) {
105
106 ndelay(delay);
107 if (poll_count++ == CC10001_MAX_POLL_COUNT)
108 return CC10001_INVALID_SAMPLED;
109 }
110
111 poll_count = 0;
112 while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
113 CC10001_ADC_CH_MASK) != channel) {
114
115 ndelay(delay);
116 if (poll_count++ == CC10001_MAX_POLL_COUNT)
117 return CC10001_INVALID_SAMPLED;
118 }
119
120 /* Read the 10 bit output register */
121 return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
122 CC10001_ADC_DATA_MASK;
123}
124
125static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
126{
127 struct cc10001_adc_device *adc_dev;
128 struct iio_poll_func *pf = p;
129 struct iio_dev *indio_dev;
130 unsigned int delay_ns;
131 unsigned int channel;
132 bool sample_invalid;
133 u16 *data;
134 int i;
135
136 indio_dev = pf->indio_dev;
137 adc_dev = iio_priv(indio_dev);
138 data = adc_dev->buf;
139
140 mutex_lock(&adc_dev->lock);
141
142 cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
143 CC10001_ADC_POWER_UP_SET);
144
145 /* Wait for 8 (6+2) clock cycles before activating START */
146 ndelay(adc_dev->start_delay_ns);
147
148 /* Calculate delay step for eoc and sampled data */
149 delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
150
151 i = 0;
152 sample_invalid = false;
153 for_each_set_bit(channel, indio_dev->active_scan_mask,
154 indio_dev->masklength) {
155
156 cc10001_adc_start(adc_dev, channel);
157
158 data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
159 if (data[i] == CC10001_INVALID_SAMPLED) {
160 dev_warn(&indio_dev->dev,
161 "invalid sample on channel %d\n", channel);
162 sample_invalid = true;
163 goto done;
164 }
165 i++;
166 }
167
168done:
169 cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
170
171 mutex_unlock(&adc_dev->lock);
172
173 if (!sample_invalid)
174 iio_push_to_buffers_with_timestamp(indio_dev, data,
175 iio_get_time_ns());
176 iio_trigger_notify_done(indio_dev->trig);
177
178 return IRQ_HANDLED;
179}
180
181static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
182 struct iio_chan_spec const *chan)
183{
184 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
185 unsigned int delay_ns;
186 u16 val;
187
188 cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
189 CC10001_ADC_POWER_UP_SET);
190
191 /* Wait for 8 (6+2) clock cycles before activating START */
192 ndelay(adc_dev->start_delay_ns);
193
194 /* Calculate delay step for eoc and sampled data */
195 delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
196
197 cc10001_adc_start(adc_dev, chan->channel);
198
199 val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
200
201 cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
202
203 return val;
204}
205
206static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
207 struct iio_chan_spec const *chan,
208 int *val, int *val2, long mask)
209{
210 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
211 int ret;
212
213 switch (mask) {
214 case IIO_CHAN_INFO_RAW:
215 if (iio_buffer_enabled(indio_dev))
216 return -EBUSY;
217 mutex_lock(&adc_dev->lock);
218 *val = cc10001_adc_read_raw_voltage(indio_dev, chan);
219 mutex_unlock(&adc_dev->lock);
220
221 if (*val == CC10001_INVALID_SAMPLED)
222 return -EIO;
223 return IIO_VAL_INT;
224
225 case IIO_CHAN_INFO_SCALE:
226 ret = regulator_get_voltage(adc_dev->reg);
227 if (ret)
228 return ret;
229
230 *val = ret / 1000;
231 *val2 = chan->scan_type.realbits;
232 return IIO_VAL_FRACTIONAL_LOG2;
233
234 default:
235 return -EINVAL;
236 }
237}
238
239static int cc10001_update_scan_mode(struct iio_dev *indio_dev,
240 const unsigned long *scan_mask)
241{
242 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
243
244 kfree(adc_dev->buf);
245 adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
246 if (!adc_dev->buf)
247 return -ENOMEM;
248
249 return 0;
250}
251
252static const struct iio_info cc10001_adc_info = {
253 .driver_module = THIS_MODULE,
254 .read_raw = &cc10001_adc_read_raw,
255 .update_scan_mode = &cc10001_update_scan_mode,
256};
257
258static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
259{
260 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
261 struct iio_chan_spec *chan_array, *timestamp;
262 unsigned int bit, idx = 0;
263
264 indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
265 CC10001_ADC_NUM_CHANNELS);
266
267 chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
268 sizeof(struct iio_chan_spec),
269 GFP_KERNEL);
270 if (!chan_array)
271 return -ENOMEM;
272
273 for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
274 struct iio_chan_spec *chan = &chan_array[idx];
275
276 chan->type = IIO_VOLTAGE;
277 chan->indexed = 1;
278 chan->channel = bit;
279 chan->scan_index = idx;
280 chan->scan_type.sign = 'u';
281 chan->scan_type.realbits = 10;
282 chan->scan_type.storagebits = 16;
283 chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
284 chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
285 idx++;
286 }
287
288 timestamp = &chan_array[idx];
289 timestamp->type = IIO_TIMESTAMP;
290 timestamp->channel = -1;
291 timestamp->scan_index = idx;
292 timestamp->scan_type.sign = 's';
293 timestamp->scan_type.realbits = 64;
294 timestamp->scan_type.storagebits = 64;
295
296 indio_dev->channels = chan_array;
297
298 return 0;
299}
300
301static int cc10001_adc_probe(struct platform_device *pdev)
302{
303 struct device_node *node = pdev->dev.of_node;
304 struct cc10001_adc_device *adc_dev;
305 unsigned long adc_clk_rate;
306 struct resource *res;
307 struct iio_dev *indio_dev;
308 int ret;
309
310 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
311 if (indio_dev == NULL)
312 return -ENOMEM;
313
314 adc_dev = iio_priv(indio_dev);
315
316 adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
317 if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
318 adc_dev->channel_map &= ~ret;
319
320 adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
321 if (IS_ERR(adc_dev->reg))
322 return PTR_ERR(adc_dev->reg);
323
324 ret = regulator_enable(adc_dev->reg);
325 if (ret)
326 return ret;
327
328 indio_dev->dev.parent = &pdev->dev;
329 indio_dev->name = dev_name(&pdev->dev);
330 indio_dev->info = &cc10001_adc_info;
331 indio_dev->modes = INDIO_DIRECT_MODE;
332
333 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
334 adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
335 if (IS_ERR(adc_dev->reg_base)) {
336 ret = PTR_ERR(adc_dev->reg_base);
337 goto err_disable_reg;
338 }
339
340 adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
341 if (IS_ERR(adc_dev->adc_clk)) {
342 dev_err(&pdev->dev, "failed to get the clock\n");
343 ret = PTR_ERR(adc_dev->adc_clk);
344 goto err_disable_reg;
345 }
346
347 ret = clk_prepare_enable(adc_dev->adc_clk);
348 if (ret) {
349 dev_err(&pdev->dev, "failed to enable the clock\n");
350 goto err_disable_reg;
351 }
352
353 adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
354 if (!adc_clk_rate) {
355 ret = -EINVAL;
356 dev_err(&pdev->dev, "null clock rate!\n");
357 goto err_disable_clk;
358 }
359
360 adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
361 adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
362
363 /* Setup the ADC channels available on the device */
364 ret = cc10001_adc_channel_init(indio_dev);
365 if (ret < 0)
366 goto err_disable_clk;
367
368 mutex_init(&adc_dev->lock);
369
370 ret = iio_triggered_buffer_setup(indio_dev, NULL,
371 &cc10001_adc_trigger_h, NULL);
372 if (ret < 0)
373 goto err_disable_clk;
374
375 ret = iio_device_register(indio_dev);
376 if (ret < 0)
377 goto err_cleanup_buffer;
378
379 platform_set_drvdata(pdev, indio_dev);
380
381 return 0;
382
383err_cleanup_buffer:
384 iio_triggered_buffer_cleanup(indio_dev);
385err_disable_clk:
386 clk_disable_unprepare(adc_dev->adc_clk);
387err_disable_reg:
388 regulator_disable(adc_dev->reg);
389 return ret;
390}
391
392static int cc10001_adc_remove(struct platform_device *pdev)
393{
394 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
395 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
396
397 iio_device_unregister(indio_dev);
398 iio_triggered_buffer_cleanup(indio_dev);
399 clk_disable_unprepare(adc_dev->adc_clk);
400 regulator_disable(adc_dev->reg);
401
402 return 0;
403}
404
405static const struct of_device_id cc10001_adc_dt_ids[] = {
406 { .compatible = "cosmic,10001-adc", },
407 { }
408};
409MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids);
410
411static struct platform_driver cc10001_adc_driver = {
412 .driver = {
413 .name = "cc10001-adc",
414 .of_match_table = cc10001_adc_dt_ids,
415 },
416 .probe = cc10001_adc_probe,
417 .remove = cc10001_adc_remove,
418};
419module_platform_driver(cc10001_adc_driver);
420
421MODULE_AUTHOR("Phani Movva <Phani.Movva@imgtec.com>");
422MODULE_DESCRIPTION("Cosmic Circuits ADC driver");
423MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c
new file mode 100644
index 000000000000..3211729bcb0b
--- /dev/null
+++ b/drivers/iio/adc/qcom-spmi-vadc.c
@@ -0,0 +1,1016 @@
1/*
2 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/bitops.h>
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18#include <linux/iio/iio.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/platform_device.h>
24#include <linux/regmap.h>
25#include <linux/slab.h>
26#include <linux/log2.h>
27
28#include <dt-bindings/iio/qcom,spmi-vadc.h>
29
30/* VADC register and bit definitions */
31#define VADC_REVISION2 0x1
32#define VADC_REVISION2_SUPPORTED_VADC 1
33
34#define VADC_PERPH_TYPE 0x4
35#define VADC_PERPH_TYPE_ADC 8
36
37#define VADC_PERPH_SUBTYPE 0x5
38#define VADC_PERPH_SUBTYPE_VADC 1
39
40#define VADC_STATUS1 0x8
41#define VADC_STATUS1_OP_MODE 4
42#define VADC_STATUS1_REQ_STS BIT(1)
43#define VADC_STATUS1_EOC BIT(0)
44#define VADC_STATUS1_REQ_STS_EOC_MASK 0x3
45
46#define VADC_MODE_CTL 0x40
47#define VADC_OP_MODE_SHIFT 3
48#define VADC_OP_MODE_NORMAL 0
49#define VADC_AMUX_TRIM_EN BIT(1)
50#define VADC_ADC_TRIM_EN BIT(0)
51
52#define VADC_EN_CTL1 0x46
53#define VADC_EN_CTL1_SET BIT(7)
54
55#define VADC_ADC_CH_SEL_CTL 0x48
56
57#define VADC_ADC_DIG_PARAM 0x50
58#define VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT 2
59
60#define VADC_HW_SETTLE_DELAY 0x51
61
62#define VADC_CONV_REQ 0x52
63#define VADC_CONV_REQ_SET BIT(7)
64
65#define VADC_FAST_AVG_CTL 0x5a
66#define VADC_FAST_AVG_EN 0x5b
67#define VADC_FAST_AVG_EN_SET BIT(7)
68
69#define VADC_ACCESS 0xd0
70#define VADC_ACCESS_DATA 0xa5
71
72#define VADC_PERH_RESET_CTL3 0xda
73#define VADC_FOLLOW_WARM_RB BIT(2)
74
75#define VADC_DATA 0x60 /* 16 bits */
76
77#define VADC_CONV_TIME_MIN_US 2000
78#define VADC_CONV_TIME_MAX_US 2100
79
80/* Min ADC code represents 0V */
81#define VADC_MIN_ADC_CODE 0x6000
82/* Max ADC code represents full-scale range of 1.8V */
83#define VADC_MAX_ADC_CODE 0xa800
84
85#define VADC_ABSOLUTE_RANGE_UV 625000
86#define VADC_RATIOMETRIC_RANGE_UV 1800000
87
88#define VADC_DEF_PRESCALING 0 /* 1:1 */
89#define VADC_DEF_DECIMATION 0 /* 512 */
90#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */
91#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */
92#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE
93
94#define VADC_DECIMATION_MIN 512
95#define VADC_DECIMATION_MAX 4096
96
97#define VADC_HW_SETTLE_DELAY_MAX 10000
98#define VADC_AVG_SAMPLES_MAX 512
99
100#define KELVINMIL_CELSIUSMIL 273150
101
102#define VADC_CHAN_MIN VADC_USBIN
103#define VADC_CHAN_MAX VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM
104
105/*
106 * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels.
107 * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for
108 * calibration.
109 */
110enum vadc_calibration {
111 VADC_CALIB_ABSOLUTE = 0,
112 VADC_CALIB_RATIOMETRIC
113};
114
115/**
116 * struct vadc_linear_graph - Represent ADC characteristics.
117 * @dy: numerator slope to calculate the gain.
118 * @dx: denominator slope to calculate the gain.
119 * @gnd: A/D word of the ground reference used for the channel.
120 *
121 * Each ADC device has different offset and gain parameters which are
122 * computed to calibrate the device.
123 */
124struct vadc_linear_graph {
125 s32 dy;
126 s32 dx;
127 s32 gnd;
128};
129
130/**
131 * struct vadc_prescale_ratio - Represent scaling ratio for ADC input.
132 * @num: the inverse numerator of the gain applied to the input channel.
133 * @den: the inverse denominator of the gain applied to the input channel.
134 */
135struct vadc_prescale_ratio {
136 u32 num;
137 u32 den;
138};
139
140/**
141 * struct vadc_channel_prop - VADC channel property.
142 * @channel: channel number, refer to the channel list.
143 * @calibration: calibration type.
144 * @decimation: sampling rate supported for the channel.
145 * @prescale: channel scaling performed on the input signal.
146 * @hw_settle_time: the time between AMUX being configured and the
147 * start of conversion.
148 * @avg_samples: ability to provide single result from the ADC
149 * that is an average of multiple measurements.
150 */
151struct vadc_channel_prop {
152 unsigned int channel;
153 enum vadc_calibration calibration;
154 unsigned int decimation;
155 unsigned int prescale;
156 unsigned int hw_settle_time;
157 unsigned int avg_samples;
158};
159
160/**
161 * struct vadc_priv - VADC private structure.
162 * @regmap: pointer to struct regmap.
163 * @dev: pointer to struct device.
164 * @base: base address for the ADC peripheral.
165 * @nchannels: number of VADC channels.
166 * @chan_props: array of VADC channel properties.
167 * @iio_chans: array of IIO channels specification.
168 * @are_ref_measured: are reference points measured.
169 * @poll_eoc: use polling instead of interrupt.
170 * @complete: VADC result notification after interrupt is received.
171 * @graph: store parameters for calibration.
172 * @lock: ADC lock for access to the peripheral.
173 */
174struct vadc_priv {
175 struct regmap *regmap;
176 struct device *dev;
177 u16 base;
178 unsigned int nchannels;
179 struct vadc_channel_prop *chan_props;
180 struct iio_chan_spec *iio_chans;
181 bool are_ref_measured;
182 bool poll_eoc;
183 struct completion complete;
184 struct vadc_linear_graph graph[2];
185 struct mutex lock;
186};
187
188static const struct vadc_prescale_ratio vadc_prescale_ratios[] = {
189 {.num = 1, .den = 1},
190 {.num = 1, .den = 3},
191 {.num = 1, .den = 4},
192 {.num = 1, .den = 6},
193 {.num = 1, .den = 20},
194 {.num = 1, .den = 8},
195 {.num = 10, .den = 81},
196 {.num = 1, .den = 10}
197};
198
199static int vadc_read(struct vadc_priv *vadc, u16 offset, u8 *data)
200{
201 return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1);
202}
203
204static int vadc_write(struct vadc_priv *vadc, u16 offset, u8 data)
205{
206 return regmap_write(vadc->regmap, vadc->base + offset, data);
207}
208
209static int vadc_reset(struct vadc_priv *vadc)
210{
211 u8 data;
212 int ret;
213
214 ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA);
215 if (ret)
216 return ret;
217
218 ret = vadc_read(vadc, VADC_PERH_RESET_CTL3, &data);
219 if (ret)
220 return ret;
221
222 ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA);
223 if (ret)
224 return ret;
225
226 data |= VADC_FOLLOW_WARM_RB;
227
228 return vadc_write(vadc, VADC_PERH_RESET_CTL3, data);
229}
230
231static int vadc_set_state(struct vadc_priv *vadc, bool state)
232{
233 return vadc_write(vadc, VADC_EN_CTL1, state ? VADC_EN_CTL1_SET : 0);
234}
235
236static void vadc_show_status(struct vadc_priv *vadc)
237{
238 u8 mode, sta1, chan, dig, en, req;
239 int ret;
240
241 ret = vadc_read(vadc, VADC_MODE_CTL, &mode);
242 if (ret)
243 return;
244
245 ret = vadc_read(vadc, VADC_ADC_DIG_PARAM, &dig);
246 if (ret)
247 return;
248
249 ret = vadc_read(vadc, VADC_ADC_CH_SEL_CTL, &chan);
250 if (ret)
251 return;
252
253 ret = vadc_read(vadc, VADC_CONV_REQ, &req);
254 if (ret)
255 return;
256
257 ret = vadc_read(vadc, VADC_STATUS1, &sta1);
258 if (ret)
259 return;
260
261 ret = vadc_read(vadc, VADC_EN_CTL1, &en);
262 if (ret)
263 return;
264
265 dev_err(vadc->dev,
266 "mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n",
267 mode, en, chan, dig, req, sta1);
268}
269
270static int vadc_configure(struct vadc_priv *vadc,
271 struct vadc_channel_prop *prop)
272{
273 u8 decimation, mode_ctrl;
274 int ret;
275
276 /* Mode selection */
277 mode_ctrl = (VADC_OP_MODE_NORMAL << VADC_OP_MODE_SHIFT) |
278 VADC_ADC_TRIM_EN | VADC_AMUX_TRIM_EN;
279 ret = vadc_write(vadc, VADC_MODE_CTL, mode_ctrl);
280 if (ret)
281 return ret;
282
283 /* Channel selection */
284 ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, prop->channel);
285 if (ret)
286 return ret;
287
288 /* Digital parameter setup */
289 decimation = prop->decimation << VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT;
290 ret = vadc_write(vadc, VADC_ADC_DIG_PARAM, decimation);
291 if (ret)
292 return ret;
293
294 /* HW settle time delay */
295 ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, prop->hw_settle_time);
296 if (ret)
297 return ret;
298
299 ret = vadc_write(vadc, VADC_FAST_AVG_CTL, prop->avg_samples);
300 if (ret)
301 return ret;
302
303 if (prop->avg_samples)
304 ret = vadc_write(vadc, VADC_FAST_AVG_EN, VADC_FAST_AVG_EN_SET);
305 else
306 ret = vadc_write(vadc, VADC_FAST_AVG_EN, 0);
307
308 return ret;
309}
310
311static int vadc_poll_wait_eoc(struct vadc_priv *vadc, unsigned int interval_us)
312{
313 unsigned int count, retry;
314 u8 sta1;
315 int ret;
316
317 retry = interval_us / VADC_CONV_TIME_MIN_US;
318
319 for (count = 0; count < retry; count++) {
320 ret = vadc_read(vadc, VADC_STATUS1, &sta1);
321 if (ret)
322 return ret;
323
324 sta1 &= VADC_STATUS1_REQ_STS_EOC_MASK;
325 if (sta1 == VADC_STATUS1_EOC)
326 return 0;
327
328 usleep_range(VADC_CONV_TIME_MIN_US, VADC_CONV_TIME_MAX_US);
329 }
330
331 vadc_show_status(vadc);
332
333 return -ETIMEDOUT;
334}
335
336static int vadc_read_result(struct vadc_priv *vadc, u16 *data)
337{
338 int ret;
339
340 ret = regmap_bulk_read(vadc->regmap, vadc->base + VADC_DATA, data, 2);
341 if (ret)
342 return ret;
343
344 *data = clamp_t(u16, *data, VADC_MIN_ADC_CODE, VADC_MAX_ADC_CODE);
345
346 return 0;
347}
348
349static struct vadc_channel_prop *vadc_get_channel(struct vadc_priv *vadc,
350 unsigned int num)
351{
352 unsigned int i;
353
354 for (i = 0; i < vadc->nchannels; i++)
355 if (vadc->chan_props[i].channel == num)
356 return &vadc->chan_props[i];
357
358 dev_dbg(vadc->dev, "no such channel %02x\n", num);
359
360 return NULL;
361}
362
363static int vadc_do_conversion(struct vadc_priv *vadc,
364 struct vadc_channel_prop *prop, u16 *data)
365{
366 unsigned int timeout;
367 int ret;
368
369 mutex_lock(&vadc->lock);
370
371 ret = vadc_configure(vadc, prop);
372 if (ret)
373 goto unlock;
374
375 if (!vadc->poll_eoc)
376 reinit_completion(&vadc->complete);
377
378 ret = vadc_set_state(vadc, true);
379 if (ret)
380 goto unlock;
381
382 ret = vadc_write(vadc, VADC_CONV_REQ, VADC_CONV_REQ_SET);
383 if (ret)
384 goto err_disable;
385
386 timeout = BIT(prop->avg_samples) * VADC_CONV_TIME_MIN_US * 2;
387
388 if (vadc->poll_eoc) {
389 ret = vadc_poll_wait_eoc(vadc, timeout);
390 } else {
391 ret = wait_for_completion_timeout(&vadc->complete, timeout);
392 if (!ret) {
393 ret = -ETIMEDOUT;
394 goto err_disable;
395 }
396
397 /* Double check conversion status */
398 ret = vadc_poll_wait_eoc(vadc, VADC_CONV_TIME_MIN_US);
399 if (ret)
400 goto err_disable;
401 }
402
403 ret = vadc_read_result(vadc, data);
404
405err_disable:
406 vadc_set_state(vadc, false);
407 if (ret)
408 dev_err(vadc->dev, "conversion failed\n");
409unlock:
410 mutex_unlock(&vadc->lock);
411 return ret;
412}
413
414static int vadc_measure_ref_points(struct vadc_priv *vadc)
415{
416 struct vadc_channel_prop *prop;
417 u16 read_1, read_2;
418 int ret;
419
420 vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE_UV;
421 vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV;
422
423 prop = vadc_get_channel(vadc, VADC_REF_1250MV);
424 ret = vadc_do_conversion(vadc, prop, &read_1);
425 if (ret)
426 goto err;
427
428 /* Try with buffered 625mV channel first */
429 prop = vadc_get_channel(vadc, VADC_SPARE1);
430 if (!prop)
431 prop = vadc_get_channel(vadc, VADC_REF_625MV);
432
433 ret = vadc_do_conversion(vadc, prop, &read_2);
434 if (ret)
435 goto err;
436
437 if (read_1 == read_2) {
438 ret = -EINVAL;
439 goto err;
440 }
441
442 vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2;
443 vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2;
444
445 /* Ratiometric calibration */
446 prop = vadc_get_channel(vadc, VADC_VDD_VADC);
447 ret = vadc_do_conversion(vadc, prop, &read_1);
448 if (ret)
449 goto err;
450
451 prop = vadc_get_channel(vadc, VADC_GND_REF);
452 ret = vadc_do_conversion(vadc, prop, &read_2);
453 if (ret)
454 goto err;
455
456 if (read_1 == read_2) {
457 ret = -EINVAL;
458 goto err;
459 }
460
461 vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2;
462 vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2;
463err:
464 if (ret)
465 dev_err(vadc->dev, "measure reference points failed\n");
466
467 return ret;
468}
469
470static s32 vadc_calibrate(struct vadc_priv *vadc,
471 const struct vadc_channel_prop *prop, u16 adc_code)
472{
473 const struct vadc_prescale_ratio *prescale;
474 s32 voltage;
475
476 voltage = adc_code - vadc->graph[prop->calibration].gnd;
477 voltage *= vadc->graph[prop->calibration].dx;
478 voltage = voltage / vadc->graph[prop->calibration].dy;
479
480 if (prop->calibration == VADC_CALIB_ABSOLUTE)
481 voltage += vadc->graph[prop->calibration].dx;
482
483 if (voltage < 0)
484 voltage = 0;
485
486 prescale = &vadc_prescale_ratios[prop->prescale];
487
488 voltage = voltage * prescale->den;
489
490 return voltage / prescale->num;
491}
492
493static int vadc_decimation_from_dt(u32 value)
494{
495 if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||
496 value > VADC_DECIMATION_MAX)
497 return -EINVAL;
498
499 return __ffs64(value / VADC_DECIMATION_MIN);
500}
501
502static int vadc_prescaling_from_dt(u32 num, u32 den)
503{
504 unsigned int pre;
505
506 for (pre = 0; pre < ARRAY_SIZE(vadc_prescale_ratios); pre++)
507 if (vadc_prescale_ratios[pre].num == num &&
508 vadc_prescale_ratios[pre].den == den)
509 break;
510
511 if (pre == ARRAY_SIZE(vadc_prescale_ratios))
512 return -EINVAL;
513
514 return pre;
515}
516
517static int vadc_hw_settle_time_from_dt(u32 value)
518{
519 if ((value <= 1000 && value % 100) || (value > 1000 && value % 2000))
520 return -EINVAL;
521
522 if (value <= 1000)
523 value /= 100;
524 else
525 value = value / 2000 + 10;
526
527 return value;
528}
529
530static int vadc_avg_samples_from_dt(u32 value)
531{
532 if (!is_power_of_2(value) || value > VADC_AVG_SAMPLES_MAX)
533 return -EINVAL;
534
535 return __ffs64(value);
536}
537
538static int vadc_read_raw(struct iio_dev *indio_dev,
539 struct iio_chan_spec const *chan, int *val, int *val2,
540 long mask)
541{
542 struct vadc_priv *vadc = iio_priv(indio_dev);
543 struct vadc_channel_prop *prop;
544 u16 adc_code;
545 int ret;
546
547 switch (mask) {
548 case IIO_CHAN_INFO_PROCESSED:
549 prop = &vadc->chan_props[chan->address];
550 ret = vadc_do_conversion(vadc, prop, &adc_code);
551 if (ret)
552 break;
553
554 *val = vadc_calibrate(vadc, prop, adc_code);
555
556 /* 2mV/K, return milli Celsius */
557 *val /= 2;
558 *val -= KELVINMIL_CELSIUSMIL;
559 return IIO_VAL_INT;
560 case IIO_CHAN_INFO_RAW:
561 prop = &vadc->chan_props[chan->address];
562 ret = vadc_do_conversion(vadc, prop, &adc_code);
563 if (ret)
564 break;
565
566 *val = vadc_calibrate(vadc, prop, adc_code);
567 return IIO_VAL_INT;
568 case IIO_CHAN_INFO_SCALE:
569 *val = 0;
570 *val2 = 1000;
571 return IIO_VAL_INT_PLUS_MICRO;
572 default:
573 ret = -EINVAL;
574 break;
575 }
576
577 return ret;
578}
579
580static int vadc_of_xlate(struct iio_dev *indio_dev,
581 const struct of_phandle_args *iiospec)
582{
583 struct vadc_priv *vadc = iio_priv(indio_dev);
584 unsigned int i;
585
586 for (i = 0; i < vadc->nchannels; i++)
587 if (vadc->iio_chans[i].channel == iiospec->args[0])
588 return i;
589
590 return -EINVAL;
591}
592
593static const struct iio_info vadc_info = {
594 .read_raw = vadc_read_raw,
595 .of_xlate = vadc_of_xlate,
596 .driver_module = THIS_MODULE,
597};
598
599struct vadc_channels {
600 const char *datasheet_name;
601 unsigned int prescale_index;
602 enum iio_chan_type type;
603 long info_mask;
604};
605
606#define VADC_CHAN(_dname, _type, _mask, _pre) \
607 [VADC_##_dname] = { \
608 .datasheet_name = __stringify(_dname), \
609 .prescale_index = _pre, \
610 .type = _type, \
611 .info_mask = _mask \
612 }, \
613
614#define VADC_CHAN_TEMP(_dname, _pre) \
615 VADC_CHAN(_dname, IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre) \
616
617#define VADC_CHAN_VOLT(_dname, _pre) \
618 VADC_CHAN(_dname, IIO_VOLTAGE, \
619 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
620 _pre) \
621
622/*
623 * The array represents all possible ADC channels found in the supported PMICs.
624 * Every index in the array is equal to the channel number per datasheet. The
625 * gaps in the array should be treated as reserved channels.
626 */
627static const struct vadc_channels vadc_chans[] = {
628 VADC_CHAN_VOLT(USBIN, 4)
629 VADC_CHAN_VOLT(DCIN, 4)
630 VADC_CHAN_VOLT(VCHG_SNS, 3)
631 VADC_CHAN_VOLT(SPARE1_03, 1)
632 VADC_CHAN_VOLT(USB_ID_MV, 1)
633 VADC_CHAN_VOLT(VCOIN, 1)
634 VADC_CHAN_VOLT(VBAT_SNS, 1)
635 VADC_CHAN_VOLT(VSYS, 1)
636 VADC_CHAN_TEMP(DIE_TEMP, 0)
637 VADC_CHAN_VOLT(REF_625MV, 0)
638 VADC_CHAN_VOLT(REF_1250MV, 0)
639 VADC_CHAN_VOLT(CHG_TEMP, 0)
640 VADC_CHAN_VOLT(SPARE1, 0)
641 VADC_CHAN_VOLT(SPARE2, 0)
642 VADC_CHAN_VOLT(GND_REF, 0)
643 VADC_CHAN_VOLT(VDD_VADC, 0)
644
645 VADC_CHAN_VOLT(P_MUX1_1_1, 0)
646 VADC_CHAN_VOLT(P_MUX2_1_1, 0)
647 VADC_CHAN_VOLT(P_MUX3_1_1, 0)
648 VADC_CHAN_VOLT(P_MUX4_1_1, 0)
649 VADC_CHAN_VOLT(P_MUX5_1_1, 0)
650 VADC_CHAN_VOLT(P_MUX6_1_1, 0)
651 VADC_CHAN_VOLT(P_MUX7_1_1, 0)
652 VADC_CHAN_VOLT(P_MUX8_1_1, 0)
653 VADC_CHAN_VOLT(P_MUX9_1_1, 0)
654 VADC_CHAN_VOLT(P_MUX10_1_1, 0)
655 VADC_CHAN_VOLT(P_MUX11_1_1, 0)
656 VADC_CHAN_VOLT(P_MUX12_1_1, 0)
657 VADC_CHAN_VOLT(P_MUX13_1_1, 0)
658 VADC_CHAN_VOLT(P_MUX14_1_1, 0)
659 VADC_CHAN_VOLT(P_MUX15_1_1, 0)
660 VADC_CHAN_VOLT(P_MUX16_1_1, 0)
661
662 VADC_CHAN_VOLT(P_MUX1_1_3, 1)
663 VADC_CHAN_VOLT(P_MUX2_1_3, 1)
664 VADC_CHAN_VOLT(P_MUX3_1_3, 1)
665 VADC_CHAN_VOLT(P_MUX4_1_3, 1)
666 VADC_CHAN_VOLT(P_MUX5_1_3, 1)
667 VADC_CHAN_VOLT(P_MUX6_1_3, 1)
668 VADC_CHAN_VOLT(P_MUX7_1_3, 1)
669 VADC_CHAN_VOLT(P_MUX8_1_3, 1)
670 VADC_CHAN_VOLT(P_MUX9_1_3, 1)
671 VADC_CHAN_VOLT(P_MUX10_1_3, 1)
672 VADC_CHAN_VOLT(P_MUX11_1_3, 1)
673 VADC_CHAN_VOLT(P_MUX12_1_3, 1)
674 VADC_CHAN_VOLT(P_MUX13_1_3, 1)
675 VADC_CHAN_VOLT(P_MUX14_1_3, 1)
676 VADC_CHAN_VOLT(P_MUX15_1_3, 1)
677 VADC_CHAN_VOLT(P_MUX16_1_3, 1)
678
679 VADC_CHAN_VOLT(LR_MUX1_BAT_THERM, 0)
680 VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0)
681 VADC_CHAN_VOLT(LR_MUX3_XO_THERM, 0)
682 VADC_CHAN_VOLT(LR_MUX4_AMUX_THM1, 0)
683 VADC_CHAN_VOLT(LR_MUX5_AMUX_THM2, 0)
684 VADC_CHAN_VOLT(LR_MUX6_AMUX_THM3, 0)
685 VADC_CHAN_VOLT(LR_MUX7_HW_ID, 0)
686 VADC_CHAN_VOLT(LR_MUX8_AMUX_THM4, 0)
687 VADC_CHAN_VOLT(LR_MUX9_AMUX_THM5, 0)
688 VADC_CHAN_VOLT(LR_MUX10_USB_ID, 0)
689 VADC_CHAN_VOLT(AMUX_PU1, 0)
690 VADC_CHAN_VOLT(AMUX_PU2, 0)
691 VADC_CHAN_VOLT(LR_MUX3_BUF_XO_THERM, 0)
692
693 VADC_CHAN_VOLT(LR_MUX1_PU1_BAT_THERM, 0)
694 VADC_CHAN_VOLT(LR_MUX2_PU1_BAT_ID, 0)
695 VADC_CHAN_VOLT(LR_MUX3_PU1_XO_THERM, 0)
696 VADC_CHAN_VOLT(LR_MUX4_PU1_AMUX_THM1, 0)
697 VADC_CHAN_VOLT(LR_MUX5_PU1_AMUX_THM2, 0)
698 VADC_CHAN_VOLT(LR_MUX6_PU1_AMUX_THM3, 0)
699 VADC_CHAN_VOLT(LR_MUX7_PU1_AMUX_HW_ID, 0)
700 VADC_CHAN_VOLT(LR_MUX8_PU1_AMUX_THM4, 0)
701 VADC_CHAN_VOLT(LR_MUX9_PU1_AMUX_THM5, 0)
702 VADC_CHAN_VOLT(LR_MUX10_PU1_AMUX_USB_ID, 0)
703 VADC_CHAN_VOLT(LR_MUX3_BUF_PU1_XO_THERM, 0)
704
705 VADC_CHAN_VOLT(LR_MUX1_PU2_BAT_THERM, 0)
706 VADC_CHAN_VOLT(LR_MUX2_PU2_BAT_ID, 0)
707 VADC_CHAN_VOLT(LR_MUX3_PU2_XO_THERM, 0)
708 VADC_CHAN_VOLT(LR_MUX4_PU2_AMUX_THM1, 0)
709 VADC_CHAN_VOLT(LR_MUX5_PU2_AMUX_THM2, 0)
710 VADC_CHAN_VOLT(LR_MUX6_PU2_AMUX_THM3, 0)
711 VADC_CHAN_VOLT(LR_MUX7_PU2_AMUX_HW_ID, 0)
712 VADC_CHAN_VOLT(LR_MUX8_PU2_AMUX_THM4, 0)
713 VADC_CHAN_VOLT(LR_MUX9_PU2_AMUX_THM5, 0)
714 VADC_CHAN_VOLT(LR_MUX10_PU2_AMUX_USB_ID, 0)
715 VADC_CHAN_VOLT(LR_MUX3_BUF_PU2_XO_THERM, 0)
716
717 VADC_CHAN_VOLT(LR_MUX1_PU1_PU2_BAT_THERM, 0)
718 VADC_CHAN_VOLT(LR_MUX2_PU1_PU2_BAT_ID, 0)
719 VADC_CHAN_VOLT(LR_MUX3_PU1_PU2_XO_THERM, 0)
720 VADC_CHAN_VOLT(LR_MUX4_PU1_PU2_AMUX_THM1, 0)
721 VADC_CHAN_VOLT(LR_MUX5_PU1_PU2_AMUX_THM2, 0)
722 VADC_CHAN_VOLT(LR_MUX6_PU1_PU2_AMUX_THM3, 0)
723 VADC_CHAN_VOLT(LR_MUX7_PU1_PU2_AMUX_HW_ID, 0)
724 VADC_CHAN_VOLT(LR_MUX8_PU1_PU2_AMUX_THM4, 0)
725 VADC_CHAN_VOLT(LR_MUX9_PU1_PU2_AMUX_THM5, 0)
726 VADC_CHAN_VOLT(LR_MUX10_PU1_PU2_AMUX_USB_ID, 0)
727 VADC_CHAN_VOLT(LR_MUX3_BUF_PU1_PU2_XO_THERM, 0)
728};
729
730static int vadc_get_dt_channel_data(struct device *dev,
731 struct vadc_channel_prop *prop,
732 struct device_node *node)
733{
734 const char *name = node->name;
735 u32 chan, value, varr[2];
736 int ret;
737
738 ret = of_property_read_u32(node, "reg", &chan);
739 if (ret) {
740 dev_err(dev, "invalid channel number %s\n", name);
741 return ret;
742 }
743
744 if (chan > VADC_CHAN_MAX || chan < VADC_CHAN_MIN) {
745 dev_err(dev, "%s invalid channel number %d\n", name, chan);
746 return -EINVAL;
747 }
748
749 /* the channel has DT description */
750 prop->channel = chan;
751
752 ret = of_property_read_u32(node, "qcom,decimation", &value);
753 if (!ret) {
754 ret = vadc_decimation_from_dt(value);
755 if (ret < 0) {
756 dev_err(dev, "%02x invalid decimation %d\n",
757 chan, value);
758 return ret;
759 }
760 prop->decimation = ret;
761 } else {
762 prop->decimation = VADC_DEF_DECIMATION;
763 }
764
765 ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2);
766 if (!ret) {
767 ret = vadc_prescaling_from_dt(varr[0], varr[1]);
768 if (ret < 0) {
769 dev_err(dev, "%02x invalid pre-scaling <%d %d>\n",
770 chan, varr[0], varr[1]);
771 return ret;
772 }
773 prop->prescale = ret;
774 } else {
775 prop->prescale = vadc_chans[prop->channel].prescale_index;
776 }
777
778 ret = of_property_read_u32(node, "qcom,hw-settle-time", &value);
779 if (!ret) {
780 ret = vadc_hw_settle_time_from_dt(value);
781 if (ret < 0) {
782 dev_err(dev, "%02x invalid hw-settle-time %d us\n",
783 chan, value);
784 return ret;
785 }
786 prop->hw_settle_time = ret;
787 } else {
788 prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME;
789 }
790
791 ret = of_property_read_u32(node, "qcom,avg-samples", &value);
792 if (!ret) {
793 ret = vadc_avg_samples_from_dt(value);
794 if (ret < 0) {
795 dev_err(dev, "%02x invalid avg-samples %d\n",
796 chan, value);
797 return ret;
798 }
799 prop->avg_samples = ret;
800 } else {
801 prop->avg_samples = VADC_DEF_AVG_SAMPLES;
802 }
803
804 if (of_property_read_bool(node, "qcom,ratiometric"))
805 prop->calibration = VADC_CALIB_RATIOMETRIC;
806 else
807 prop->calibration = VADC_CALIB_ABSOLUTE;
808
809 dev_dbg(dev, "%02x name %s\n", chan, name);
810
811 return 0;
812}
813
814static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node)
815{
816 const struct vadc_channels *vadc_chan;
817 struct iio_chan_spec *iio_chan;
818 struct vadc_channel_prop prop;
819 struct device_node *child;
820 unsigned int index = 0;
821 int ret;
822
823 vadc->nchannels = of_get_available_child_count(node);
824 if (!vadc->nchannels)
825 return -EINVAL;
826
827 vadc->iio_chans = devm_kcalloc(vadc->dev, vadc->nchannels,
828 sizeof(*vadc->iio_chans), GFP_KERNEL);
829 if (!vadc->iio_chans)
830 return -ENOMEM;
831
832 vadc->chan_props = devm_kcalloc(vadc->dev, vadc->nchannels,
833 sizeof(*vadc->chan_props), GFP_KERNEL);
834 if (!vadc->chan_props)
835 return -ENOMEM;
836
837 iio_chan = vadc->iio_chans;
838
839 for_each_available_child_of_node(node, child) {
840 ret = vadc_get_dt_channel_data(vadc->dev, &prop, child);
841 if (ret)
842 return ret;
843
844 vadc->chan_props[index] = prop;
845
846 vadc_chan = &vadc_chans[prop.channel];
847
848 iio_chan->channel = prop.channel;
849 iio_chan->datasheet_name = vadc_chan->datasheet_name;
850 iio_chan->info_mask_separate = vadc_chan->info_mask;
851 iio_chan->type = vadc_chan->type;
852 iio_chan->indexed = 1;
853 iio_chan->address = index++;
854
855 iio_chan++;
856 }
857
858 /* These channels are mandatory, they are used as reference points */
859 if (!vadc_get_channel(vadc, VADC_REF_1250MV)) {
860 dev_err(vadc->dev, "Please define 1.25V channel\n");
861 return -ENODEV;
862 }
863
864 if (!vadc_get_channel(vadc, VADC_REF_625MV)) {
865 dev_err(vadc->dev, "Please define 0.625V channel\n");
866 return -ENODEV;
867 }
868
869 if (!vadc_get_channel(vadc, VADC_VDD_VADC)) {
870 dev_err(vadc->dev, "Please define VDD channel\n");
871 return -ENODEV;
872 }
873
874 if (!vadc_get_channel(vadc, VADC_GND_REF)) {
875 dev_err(vadc->dev, "Please define GND channel\n");
876 return -ENODEV;
877 }
878
879 return 0;
880}
881
882static irqreturn_t vadc_isr(int irq, void *dev_id)
883{
884 struct vadc_priv *vadc = dev_id;
885
886 complete(&vadc->complete);
887
888 return IRQ_HANDLED;
889}
890
891static int vadc_check_revision(struct vadc_priv *vadc)
892{
893 u8 val;
894 int ret;
895
896 ret = vadc_read(vadc, VADC_PERPH_TYPE, &val);
897 if (ret)
898 return ret;
899
900 if (val < VADC_PERPH_TYPE_ADC) {
901 dev_err(vadc->dev, "%d is not ADC\n", val);
902 return -ENODEV;
903 }
904
905 ret = vadc_read(vadc, VADC_PERPH_SUBTYPE, &val);
906 if (ret)
907 return ret;
908
909 if (val < VADC_PERPH_SUBTYPE_VADC) {
910 dev_err(vadc->dev, "%d is not VADC\n", val);
911 return -ENODEV;
912 }
913
914 ret = vadc_read(vadc, VADC_REVISION2, &val);
915 if (ret)
916 return ret;
917
918 if (val < VADC_REVISION2_SUPPORTED_VADC) {
919 dev_err(vadc->dev, "revision %d not supported\n", val);
920 return -ENODEV;
921 }
922
923 return 0;
924}
925
926static int vadc_probe(struct platform_device *pdev)
927{
928 struct device_node *node = pdev->dev.of_node;
929 struct device *dev = &pdev->dev;
930 struct iio_dev *indio_dev;
931 struct vadc_priv *vadc;
932 struct regmap *regmap;
933 int ret, irq_eoc;
934 u32 reg;
935
936 regmap = dev_get_regmap(dev->parent, NULL);
937 if (!regmap)
938 return -ENODEV;
939
940 ret = of_property_read_u32(node, "reg", &reg);
941 if (ret < 0)
942 return ret;
943
944 indio_dev = devm_iio_device_alloc(dev, sizeof(*vadc));
945 if (!indio_dev)
946 return -ENOMEM;
947
948 vadc = iio_priv(indio_dev);
949 vadc->regmap = regmap;
950 vadc->dev = dev;
951 vadc->base = reg;
952 vadc->are_ref_measured = false;
953 init_completion(&vadc->complete);
954 mutex_init(&vadc->lock);
955
956 ret = vadc_check_revision(vadc);
957 if (ret)
958 return ret;
959
960 ret = vadc_get_dt_data(vadc, node);
961 if (ret)
962 return ret;
963
964 irq_eoc = platform_get_irq(pdev, 0);
965 if (irq_eoc < 0) {
966 if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL)
967 return irq_eoc;
968 vadc->poll_eoc = true;
969 } else {
970 ret = devm_request_irq(dev, irq_eoc, vadc_isr, 0,
971 "spmi-vadc", vadc);
972 if (ret)
973 return ret;
974 }
975
976 ret = vadc_reset(vadc);
977 if (ret) {
978 dev_err(dev, "reset failed\n");
979 return ret;
980 }
981
982 ret = vadc_measure_ref_points(vadc);
983 if (ret)
984 return ret;
985
986 indio_dev->dev.parent = dev;
987 indio_dev->dev.of_node = node;
988 indio_dev->name = pdev->name;
989 indio_dev->modes = INDIO_DIRECT_MODE;
990 indio_dev->info = &vadc_info;
991 indio_dev->channels = vadc->iio_chans;
992 indio_dev->num_channels = vadc->nchannels;
993
994 return devm_iio_device_register(dev, indio_dev);
995}
996
997static const struct of_device_id vadc_match_table[] = {
998 { .compatible = "qcom,spmi-vadc" },
999 { }
1000};
1001MODULE_DEVICE_TABLE(of, vadc_match_table);
1002
1003static struct platform_driver vadc_driver = {
1004 .driver = {
1005 .name = "qcom-spmi-vadc",
1006 .of_match_table = vadc_match_table,
1007 },
1008 .probe = vadc_probe,
1009};
1010module_platform_driver(vadc_driver);
1011
1012MODULE_ALIAS("platform:qcom-spmi-vadc");
1013MODULE_DESCRIPTION("Qualcomm SPMI PMIC voltage ADC driver");
1014MODULE_LICENSE("GPL v2");
1015MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
1016MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index adba23246474..2e5cc4409f78 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -249,7 +249,7 @@ static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
249 struct iio_buffer *buffer; 249 struct iio_buffer *buffer;
250 int ret; 250 int ret;
251 251
252 buffer = iio_kfifo_allocate(indio_dev); 252 buffer = iio_kfifo_allocate();
253 if (!buffer) 253 if (!buffer)
254 return -ENOMEM; 254 return -ENOMEM;
255 255
@@ -263,16 +263,8 @@ static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
263 indio_dev->setup_ops = setup_ops; 263 indio_dev->setup_ops = setup_ops;
264 indio_dev->modes |= INDIO_BUFFER_HARDWARE; 264 indio_dev->modes |= INDIO_BUFFER_HARDWARE;
265 265
266 ret = iio_buffer_register(indio_dev,
267 indio_dev->channels,
268 indio_dev->num_channels);
269 if (ret)
270 goto error_free_irq;
271
272 return 0; 266 return 0;
273 267
274error_free_irq:
275 free_irq(irq, indio_dev);
276error_kfifo_free: 268error_kfifo_free:
277 iio_kfifo_free(indio_dev->buffer); 269 iio_kfifo_free(indio_dev->buffer);
278 return ret; 270 return ret;
@@ -284,7 +276,6 @@ static void tiadc_iio_buffered_hardware_remove(struct iio_dev *indio_dev)
284 276
285 free_irq(adc_dev->mfd_tscadc->irq, indio_dev); 277 free_irq(adc_dev->mfd_tscadc->irq, indio_dev);
286 iio_kfifo_free(indio_dev->buffer); 278 iio_kfifo_free(indio_dev->buffer);
287 iio_buffer_unregister(indio_dev);
288} 279}
289 280
290 281
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c
index ba6f6a91dfff..c0d364ebaea8 100644
--- a/drivers/iio/amplifiers/ad8366.c
+++ b/drivers/iio/amplifiers/ad8366.c
@@ -31,7 +31,7 @@ struct ad8366_state {
31}; 31};
32 32
33static int ad8366_write(struct iio_dev *indio_dev, 33static int ad8366_write(struct iio_dev *indio_dev,
34 unsigned char ch_a, char unsigned ch_b) 34 unsigned char ch_a, unsigned char ch_b)
35{ 35{
36 struct ad8366_state *st = iio_priv(indio_dev); 36 struct ad8366_state *st = iio_priv(indio_dev);
37 int ret; 37 int ret;
@@ -166,7 +166,7 @@ static int ad8366_probe(struct spi_device *spi)
166 if (ret) 166 if (ret)
167 goto error_disable_reg; 167 goto error_disable_reg;
168 168
169 ad8366_write(indio_dev, 0 , 0); 169 ad8366_write(indio_dev, 0, 0);
170 170
171 return 0; 171 return 0;
172 172
diff --git a/drivers/iio/common/Kconfig b/drivers/iio/common/Kconfig
index 0b6e97d18fa0..790f106d719c 100644
--- a/drivers/iio/common/Kconfig
+++ b/drivers/iio/common/Kconfig
@@ -3,4 +3,5 @@
3# 3#
4 4
5source "drivers/iio/common/hid-sensors/Kconfig" 5source "drivers/iio/common/hid-sensors/Kconfig"
6source "drivers/iio/common/ssp_sensors/Kconfig"
6source "drivers/iio/common/st_sensors/Kconfig" 7source "drivers/iio/common/st_sensors/Kconfig"
diff --git a/drivers/iio/common/Makefile b/drivers/iio/common/Makefile
index 3112df0060e9..b1e4d9c9591c 100644
--- a/drivers/iio/common/Makefile
+++ b/drivers/iio/common/Makefile
@@ -8,4 +8,5 @@
8 8
9# When adding new entries keep the list in alphabetical order 9# When adding new entries keep the list in alphabetical order
10obj-y += hid-sensors/ 10obj-y += hid-sensors/
11obj-y += ssp_sensors/
11obj-y += st_sensors/ 12obj-y += st_sensors/
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 92068cdbf8c7..2f1d535b94c4 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -22,16 +22,18 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/delay.h>
25#include <linux/hid-sensor-hub.h> 26#include <linux/hid-sensor-hub.h>
26#include <linux/iio/iio.h> 27#include <linux/iio/iio.h>
27#include <linux/iio/trigger.h> 28#include <linux/iio/trigger.h>
28#include <linux/iio/sysfs.h> 29#include <linux/iio/sysfs.h>
29#include "hid-sensor-trigger.h" 30#include "hid-sensor-trigger.h"
30 31
31int hid_sensor_power_state(struct hid_sensor_common *st, bool state) 32static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
32{ 33{
33 int state_val; 34 int state_val;
34 int report_val; 35 int report_val;
36 s32 poll_value = 0;
35 37
36 if (state) { 38 if (state) {
37 if (sensor_hub_device_open(st->hsdev)) 39 if (sensor_hub_device_open(st->hsdev))
@@ -47,6 +49,8 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
47 st->report_state.report_id, 49 st->report_state.report_id,
48 st->report_state.index, 50 st->report_state.index,
49 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM); 51 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
52
53 poll_value = hid_sensor_read_poll_value(st);
50 } else { 54 } else {
51 if (!atomic_dec_and_test(&st->data_ready)) 55 if (!atomic_dec_and_test(&st->data_ready))
52 return 0; 56 return 0;
@@ -78,10 +82,36 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
78 sensor_hub_get_feature(st->hsdev, st->power_state.report_id, 82 sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
79 st->power_state.index, 83 st->power_state.index,
80 &state_val); 84 &state_val);
85 if (state && poll_value)
86 msleep_interruptible(poll_value * 2);
87
81 return 0; 88 return 0;
82} 89}
83EXPORT_SYMBOL(hid_sensor_power_state); 90EXPORT_SYMBOL(hid_sensor_power_state);
84 91
92int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
93{
94#ifdef CONFIG_PM
95 int ret;
96
97 if (state)
98 ret = pm_runtime_get_sync(&st->pdev->dev);
99 else {
100 pm_runtime_mark_last_busy(&st->pdev->dev);
101 ret = pm_runtime_put_autosuspend(&st->pdev->dev);
102 }
103 if (ret < 0) {
104 if (state)
105 pm_runtime_put_noidle(&st->pdev->dev);
106 return ret;
107 }
108
109 return 0;
110#else
111 return _hid_sensor_power_state(st, state);
112#endif
113}
114
85static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, 115static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
86 bool state) 116 bool state)
87{ 117{
@@ -125,8 +155,21 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
125 attrb->trigger = trig; 155 attrb->trigger = trig;
126 indio_dev->trig = iio_trigger_get(trig); 156 indio_dev->trig = iio_trigger_get(trig);
127 157
128 return ret; 158 ret = pm_runtime_set_active(&indio_dev->dev);
159 if (ret)
160 goto error_unreg_trigger;
129 161
162 iio_device_set_drvdata(indio_dev, attrb);
163 pm_suspend_ignore_children(&attrb->pdev->dev, true);
164 pm_runtime_enable(&attrb->pdev->dev);
165 /* Default to 3 seconds, but can be changed from sysfs */
166 pm_runtime_set_autosuspend_delay(&attrb->pdev->dev,
167 3000);
168 pm_runtime_use_autosuspend(&attrb->pdev->dev);
169
170 return ret;
171error_unreg_trigger:
172 iio_trigger_unregister(trig);
130error_free_trig: 173error_free_trig:
131 iio_trigger_free(trig); 174 iio_trigger_free(trig);
132error_ret: 175error_ret:
@@ -134,6 +177,34 @@ error_ret:
134} 177}
135EXPORT_SYMBOL(hid_sensor_setup_trigger); 178EXPORT_SYMBOL(hid_sensor_setup_trigger);
136 179
180#ifdef CONFIG_PM
181static int hid_sensor_suspend(struct device *dev)
182{
183 struct platform_device *pdev = to_platform_device(dev);
184 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
185 struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
186
187 return _hid_sensor_power_state(attrb, false);
188}
189
190static int hid_sensor_resume(struct device *dev)
191{
192 struct platform_device *pdev = to_platform_device(dev);
193 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
194 struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
195
196 return _hid_sensor_power_state(attrb, true);
197}
198
199#endif
200
201const struct dev_pm_ops hid_sensor_pm_ops = {
202 SET_SYSTEM_SLEEP_PM_OPS(hid_sensor_suspend, hid_sensor_resume)
203 SET_RUNTIME_PM_OPS(hid_sensor_suspend,
204 hid_sensor_resume, NULL)
205};
206EXPORT_SYMBOL(hid_sensor_pm_ops);
207
137MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); 208MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
138MODULE_DESCRIPTION("HID Sensor trigger processing"); 209MODULE_DESCRIPTION("HID Sensor trigger processing");
139MODULE_LICENSE("GPL"); 210MODULE_LICENSE("GPL");
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
index 0f8e78c249d3..9f4713f42ecb 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
@@ -19,6 +19,11 @@
19#ifndef _HID_SENSOR_TRIGGER_H 19#ifndef _HID_SENSOR_TRIGGER_H
20#define _HID_SENSOR_TRIGGER_H 20#define _HID_SENSOR_TRIGGER_H
21 21
22#include <linux/pm.h>
23#include <linux/pm_runtime.h>
24
25extern const struct dev_pm_ops hid_sensor_pm_ops;
26
22int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, 27int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
23 struct hid_sensor_common *attrb); 28 struct hid_sensor_common *attrb);
24void hid_sensor_remove_trigger(struct hid_sensor_common *attrb); 29void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
diff --git a/drivers/iio/common/ssp_sensors/Kconfig b/drivers/iio/common/ssp_sensors/Kconfig
new file mode 100644
index 000000000000..0ea4faf016d8
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/Kconfig
@@ -0,0 +1,26 @@
1#
2# SSP sensor drivers and commons configuration
3#
4menu "SSP Sensor Common"
5
6config IIO_SSP_SENSORS_COMMONS
7 tristate "Commons for all SSP Sensor IIO drivers"
8 depends on IIO_SSP_SENSORHUB
9 select IIO_BUFFER
10 select IIO_KFIFO_BUF
11 help
12 Say yes here to build commons for SSP sensors.
13 To compile this as a module, choose M here: the module
14 will be called ssp_iio.
15
16config IIO_SSP_SENSORHUB
17 tristate "Samsung Sensorhub driver"
18 depends on SPI
19 select MFD_CORE
20 help
21 SSP driver for sensorhub.
22 If you say yes here you get ssp support for sensorhub.
23 To compile this driver as a module, choose M here: the
24 module will be called sensorhub.
25
26endmenu
diff --git a/drivers/iio/common/ssp_sensors/Makefile b/drivers/iio/common/ssp_sensors/Makefile
new file mode 100644
index 000000000000..1e0389eb0905
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for SSP sensor drivers and commons.
3#
4
5sensorhub-objs := ssp_dev.o ssp_spi.o
6obj-$(CONFIG_IIO_SSP_SENSORHUB) += sensorhub.o
7
8obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_iio.o
diff --git a/drivers/iio/common/ssp_sensors/ssp.h b/drivers/iio/common/ssp_sensors/ssp.h
new file mode 100644
index 000000000000..b910e91d7c0d
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp.h
@@ -0,0 +1,257 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __SSP_SENSORHUB_H__
17#define __SSP_SENSORHUB_H__
18
19#include <linux/delay.h>
20#include <linux/gpio.h>
21#include <linux/iio/common/ssp_sensors.h>
22#include <linux/iio/iio.h>
23#include <linux/spi/spi.h>
24
25#define SSP_DEVICE_ID 0x55
26
27#ifdef SSP_DBG
28#define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__)
29#else
30#define ssp_dbg(format, ...)
31#endif
32
33#define SSP_SW_RESET_TIME 3000
34/* Sensor polling in ms */
35#define SSP_DEFAULT_POLLING_DELAY 200
36#define SSP_DEFAULT_RETRIES 3
37#define SSP_DATA_PACKET_SIZE 960
38#define SSP_HEADER_BUFFER_SIZE 4
39
40enum {
41 SSP_KERNEL_BINARY = 0,
42 SSP_KERNEL_CRASHED_BINARY,
43};
44
45enum {
46 SSP_INITIALIZATION_STATE = 0,
47 SSP_NO_SENSOR_STATE,
48 SSP_ADD_SENSOR_STATE,
49 SSP_RUNNING_SENSOR_STATE,
50};
51
52/* Firmware download STATE */
53enum {
54 SSP_FW_DL_STATE_FAIL = -1,
55 SSP_FW_DL_STATE_NONE = 0,
56 SSP_FW_DL_STATE_NEED_TO_SCHEDULE,
57 SSP_FW_DL_STATE_SCHEDULED,
58 SSP_FW_DL_STATE_DOWNLOADING,
59 SSP_FW_DL_STATE_SYNC,
60 SSP_FW_DL_STATE_DONE,
61};
62
63#define SSP_INVALID_REVISION 99999
64#define SSP_INVALID_REVISION2 0xffffff
65
66/* AP -> SSP Instruction */
67#define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD 0xa1
68#define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM 0xa2
69#define SSP_MSG2SSP_INST_REMOVE_ALL 0xa3
70#define SSP_MSG2SSP_INST_CHANGE_DELAY 0xa4
71#define SSP_MSG2SSP_INST_LIBRARY_ADD 0xb1
72#define SSP_MSG2SSP_INST_LIBRARY_REMOVE 0xb2
73#define SSP_MSG2SSP_INST_LIB_NOTI 0xb4
74#define SSP_MSG2SSP_INST_LIB_DATA 0xc1
75
76#define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL 0xcd
77#define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL 0xce
78#define SSP_MSG2SSP_AP_STATUS_SHUTDOWN 0xd0
79#define SSP_MSG2SSP_AP_STATUS_WAKEUP 0xd1
80#define SSP_MSG2SSP_AP_STATUS_SLEEP 0xd2
81#define SSP_MSG2SSP_AP_STATUS_RESUME 0xd3
82#define SSP_MSG2SSP_AP_STATUS_SUSPEND 0xd4
83#define SSP_MSG2SSP_AP_STATUS_RESET 0xd5
84#define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED 0xd6
85#define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED 0xd7
86#define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE 0xda
87#define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE 0xdb
88#define SSP_MSG2SSP_AP_MCU_DUMP_CHECK 0xdc
89#define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH 0xdd
90#define SSP_MSG2SSP_AP_MCU_BATCH_COUNT 0xdf
91
92#define SSP_MSG2SSP_AP_WHOAMI 0x0f
93#define SSP_MSG2SSP_AP_FIRMWARE_REV 0xf0
94#define SSP_MSG2SSP_AP_SENSOR_FORMATION 0xf1
95#define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD 0xf2
96#define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL 0xf3
97#define SSP_MSG2SSP_AP_SENSOR_SCANNING 0xf4
98#define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET 0xf5
99#define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET 0xf6
100#define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT 0xf7
101#define SSP_MSG2SSP_AP_GET_THERM 0xf8
102#define SSP_MSG2SSP_AP_GET_BIG_DATA 0xf9
103#define SSP_MSG2SSP_AP_SET_BIG_DATA 0xfa
104#define SSP_MSG2SSP_AP_START_BIG_DATA 0xfb
105#define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX 0xfd
106#define SSP_MSG2SSP_AP_SENSOR_TILT 0xea
107#define SSP_MSG2SSP_AP_MCU_SET_TIME 0xfe
108#define SSP_MSG2SSP_AP_MCU_GET_TIME 0xff
109
110#define SSP_MSG2SSP_AP_FUSEROM 0x01
111
112/* voice data */
113#define SSP_TYPE_WAKE_UP_VOICE_SERVICE 0x01
114#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM 0x01
115#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER 0x02
116
117/* Factory Test */
118#define SSP_ACCELEROMETER_FACTORY 0x80
119#define SSP_GYROSCOPE_FACTORY 0x81
120#define SSP_GEOMAGNETIC_FACTORY 0x82
121#define SSP_PRESSURE_FACTORY 0x85
122#define SSP_GESTURE_FACTORY 0x86
123#define SSP_TEMPHUMIDITY_CRC_FACTORY 0x88
124#define SSP_GYROSCOPE_TEMP_FACTORY 0x8a
125#define SSP_GYROSCOPE_DPS_FACTORY 0x8b
126#define SSP_MCU_FACTORY 0x8c
127#define SSP_MCU_SLEEP_FACTORY 0x8d
128
129/* SSP -> AP ACK about write CMD */
130#define SSP_MSG_ACK 0x80 /* ACK from SSP to AP */
131#define SSP_MSG_NAK 0x70 /* NAK from SSP to AP */
132
133struct ssp_sensorhub_info {
134 char *fw_name;
135 char *fw_crashed_name;
136 unsigned int fw_rev;
137 const u8 * const mag_table;
138 const unsigned int mag_length;
139};
140
141/* ssp_msg options bit */
142#define SSP_RW 0
143#define SSP_INDEX 3
144
145#define SSP_AP2HUB_READ 0
146#define SSP_AP2HUB_WRITE 1
147#define SSP_HUB2AP_WRITE 2
148#define SSP_AP2HUB_READY 3
149#define SSP_AP2HUB_RETURN 4
150
151/**
152 * struct ssp_data - ssp platformdata structure
153 * @spi: spi device
154 * @sensorhub_info: info about sensorhub board specific features
155 * @wdt_timer: watchdog timer
156 * @work_wdt: watchdog work
157 * @work_firmware: firmware upgrade work queue
158 * @work_refresh: refresh work queue for reset request from MCU
159 * @shut_down: shut down flag
160 * @mcu_dump_mode: mcu dump mode for debug
161 * @time_syncing: time syncing indication flag
162 * @timestamp: previous time in ns calculated for time syncing
163 * @check_status: status table for each sensor
164 * @com_fail_cnt: communication fail count
165 * @reset_cnt: reset count
166 * @timeout_cnt: timeout count
167 * @available_sensors: available sensors seen by sensorhub (bit array)
168 * @cur_firm_rev: cached current firmware revision
169 * @last_resume_state: last AP resume/suspend state used to handle the PM
170 * state of ssp
171 * @last_ap_state: (obsolete) sleep notification for MCU
172 * @sensor_enable: sensor enable mask
173 * @delay_buf: data acquisition intervals table
174 * @batch_latency_buf: yet unknown but existing in communication protocol
175 * @batch_opt_buf: yet unknown but existing in communication protocol
176 * @accel_position: yet unknown but existing in communication protocol
177 * @mag_position: yet unknown but existing in communication protocol
178 * @fw_dl_state: firmware download state
179 * @comm_lock: lock protecting the handshake
180 * @pending_lock: lock protecting pending list and completion
181 * @mcu_reset_gpio: mcu reset line
182 * @ap_mcu_gpio: ap to mcu gpio line
183 * @mcu_ap_gpio: mcu to ap gpio line
184 * @pending_list: pending list for messages queued to be sent/read
185 * @sensor_devs: registered IIO devices table
186 * @enable_refcount: enable reference count for wdt (watchdog timer)
187 * @header_buffer: cache aligned buffer for packet header
188 */
189struct ssp_data {
190 struct spi_device *spi;
191 struct ssp_sensorhub_info *sensorhub_info;
192 struct timer_list wdt_timer;
193 struct work_struct work_wdt;
194 struct delayed_work work_refresh;
195
196 bool shut_down;
197 bool mcu_dump_mode;
198 bool time_syncing;
199 int64_t timestamp;
200
201 int check_status[SSP_SENSOR_MAX];
202
203 unsigned int com_fail_cnt;
204 unsigned int reset_cnt;
205 unsigned int timeout_cnt;
206
207 unsigned int available_sensors;
208 unsigned int cur_firm_rev;
209
210 char last_resume_state;
211 char last_ap_state;
212
213 unsigned int sensor_enable;
214 u32 delay_buf[SSP_SENSOR_MAX];
215 s32 batch_latency_buf[SSP_SENSOR_MAX];
216 s8 batch_opt_buf[SSP_SENSOR_MAX];
217
218 int accel_position;
219 int mag_position;
220 int fw_dl_state;
221
222 struct mutex comm_lock;
223 struct mutex pending_lock;
224
225 int mcu_reset_gpio;
226 int ap_mcu_gpio;
227 int mcu_ap_gpio;
228
229 struct list_head pending_list;
230
231 struct iio_dev *sensor_devs[SSP_SENSOR_MAX];
232 atomic_t enable_refcount;
233
234 __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)]
235 ____cacheline_aligned;
236};
237
238void ssp_clean_pending_list(struct ssp_data *data);
239
240int ssp_command(struct ssp_data *data, char command, int arg);
241
242int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type,
243 u8 *send_buf, u8 length);
244
245int ssp_irq_msg(struct ssp_data *data);
246
247int ssp_get_chipid(struct ssp_data *data);
248
249int ssp_set_magnetic_matrix(struct ssp_data *data);
250
251unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data);
252
253unsigned int ssp_get_firmware_rev(struct ssp_data *data);
254
255int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay);
256
257#endif /* __SSP_SENSORHUB_H__ */
diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c
new file mode 100644
index 000000000000..52d70435f5a1
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_dev.c
@@ -0,0 +1,712 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/iio/iio.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/mfd/core.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_gpio.h>
23#include <linux/of_platform.h>
24#include "ssp.h"
25
26#define SSP_WDT_TIME 10000
27#define SSP_LIMIT_RESET_CNT 20
28#define SSP_LIMIT_TIMEOUT_CNT 3
29
30/* It is possible that it is max clk rate for version 1.0 of bootcode */
31#define SSP_BOOT_SPI_HZ 400000
32
33/*
34 * These fields can look enigmatic but this structure is used mainly to flat
35 * some values and depends on command type.
36 */
37struct ssp_instruction {
38 __le32 a;
39 __le32 b;
40 u8 c;
41} __attribute__((__packed__));
42
43static const u8 ssp_magnitude_table[] = {110, 85, 171, 71, 203, 195, 0, 67,
44 208, 56, 175, 244, 206, 213, 0, 92, 250, 0, 55, 48, 189, 252, 171,
45 243, 13, 45, 250};
46
47static const struct ssp_sensorhub_info ssp_rinato_info = {
48 .fw_name = "ssp_B2.fw",
49 .fw_crashed_name = "ssp_crashed.fw",
50 .fw_rev = 14052300,
51 .mag_table = ssp_magnitude_table,
52 .mag_length = ARRAY_SIZE(ssp_magnitude_table),
53};
54
55static const struct ssp_sensorhub_info ssp_thermostat_info = {
56 .fw_name = "thermostat_B2.fw",
57 .fw_crashed_name = "ssp_crashed.fw",
58 .fw_rev = 14080600,
59 .mag_table = ssp_magnitude_table,
60 .mag_length = ARRAY_SIZE(ssp_magnitude_table),
61};
62
63static const struct mfd_cell sensorhub_sensor_devs[] = {
64 {
65 .name = "ssp-accelerometer",
66 },
67 {
68 .name = "ssp-gyroscope",
69 },
70};
71
72static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
73{
74 gpio_set_value(data->mcu_reset_gpio, 0);
75 usleep_range(1000, 1200);
76 gpio_set_value(data->mcu_reset_gpio, 1);
77 msleep(50);
78}
79
80static void ssp_sync_available_sensors(struct ssp_data *data)
81{
82 int i, ret;
83
84 for (i = 0; i < SSP_SENSOR_MAX; ++i) {
85 if (data->available_sensors & BIT(i)) {
86 ret = ssp_enable_sensor(data, i, data->delay_buf[i]);
87 if (ret < 0) {
88 dev_err(&data->spi->dev,
89 "Sync sensor nr: %d fail\n", i);
90 continue;
91 }
92 }
93 }
94
95 ret = ssp_command(data, SSP_MSG2SSP_AP_MCU_SET_DUMPMODE,
96 data->mcu_dump_mode);
97 if (ret < 0)
98 dev_err(&data->spi->dev,
99 "SSP_MSG2SSP_AP_MCU_SET_DUMPMODE failed\n");
100}
101
102static void ssp_enable_mcu(struct ssp_data *data, bool enable)
103{
104 dev_info(&data->spi->dev, "current shutdown = %d, old = %d\n", enable,
105 data->shut_down);
106
107 if (enable && data->shut_down) {
108 data->shut_down = false;
109 enable_irq(data->spi->irq);
110 enable_irq_wake(data->spi->irq);
111 } else if (!enable && !data->shut_down) {
112 data->shut_down = true;
113 disable_irq(data->spi->irq);
114 disable_irq_wake(data->spi->irq);
115 } else {
116 dev_warn(&data->spi->dev, "current shutdown = %d, old = %d\n",
117 enable, data->shut_down);
118 }
119}
120
121/*
122 * This function is the first one which communicates with the mcu so it is
123 * possible that the first attempt will fail
124 */
125static int ssp_check_fwbl(struct ssp_data *data)
126{
127 int retries = 0;
128
129 while (retries++ < 5) {
130 data->cur_firm_rev = ssp_get_firmware_rev(data);
131 if (data->cur_firm_rev == SSP_INVALID_REVISION ||
132 data->cur_firm_rev == SSP_INVALID_REVISION2) {
133 dev_warn(&data->spi->dev,
134 "Invalid revision, trying %d time\n", retries);
135 } else {
136 break;
137 }
138 }
139
140 if (data->cur_firm_rev == SSP_INVALID_REVISION ||
141 data->cur_firm_rev == SSP_INVALID_REVISION2) {
142 dev_err(&data->spi->dev, "SSP_INVALID_REVISION\n");
143 return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
144 }
145
146 dev_info(&data->spi->dev,
147 "MCU Firm Rev : Old = %8u, New = %8u\n",
148 data->cur_firm_rev,
149 data->sensorhub_info->fw_rev);
150
151 if (data->cur_firm_rev != data->sensorhub_info->fw_rev)
152 return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
153
154 return SSP_FW_DL_STATE_NONE;
155}
156
157static void ssp_reset_mcu(struct ssp_data *data)
158{
159 ssp_enable_mcu(data, false);
160 ssp_clean_pending_list(data);
161 ssp_toggle_mcu_reset_gpio(data);
162 ssp_enable_mcu(data, true);
163}
164
165static void ssp_wdt_work_func(struct work_struct *work)
166{
167 struct ssp_data *data = container_of(work, struct ssp_data, work_wdt);
168
169 dev_err(&data->spi->dev, "%s - Sensor state: 0x%x, RC: %u, CC: %u\n",
170 __func__, data->available_sensors, data->reset_cnt,
171 data->com_fail_cnt);
172
173 ssp_reset_mcu(data);
174 data->com_fail_cnt = 0;
175 data->timeout_cnt = 0;
176}
177
178static void ssp_wdt_timer_func(unsigned long ptr)
179{
180 struct ssp_data *data = (struct ssp_data *)ptr;
181
182 switch (data->fw_dl_state) {
183 case SSP_FW_DL_STATE_FAIL:
184 case SSP_FW_DL_STATE_DOWNLOADING:
185 case SSP_FW_DL_STATE_SYNC:
186 goto _mod;
187 }
188
189 if (data->timeout_cnt > SSP_LIMIT_TIMEOUT_CNT ||
190 data->com_fail_cnt > SSP_LIMIT_RESET_CNT)
191 queue_work(system_power_efficient_wq, &data->work_wdt);
192_mod:
193 mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
194}
195
196static void ssp_enable_wdt_timer(struct ssp_data *data)
197{
198 mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
199}
200
201static void ssp_disable_wdt_timer(struct ssp_data *data)
202{
203 del_timer_sync(&data->wdt_timer);
204 cancel_work_sync(&data->work_wdt);
205}
206
207/**
208 * ssp_get_sensor_delay() - gets sensor data acquisition period
209 * @data: sensorhub structure
210 * @type: SSP sensor type
211 *
212 * Returns acquisition period in ms
213 */
214u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type)
215{
216 return data->delay_buf[type];
217}
218EXPORT_SYMBOL(ssp_get_sensor_delay);
219
220/**
221 * ssp_enable_sensor() - enables data acquisition for sensor
222 * @data: sensorhub structure
223 * @type: SSP sensor type
224 * @delay: delay in ms
225 *
226 * Returns 0 or negative value in case of error
227 */
228int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
229 u32 delay)
230{
231 int ret;
232 struct ssp_instruction to_send;
233
234 to_send.a = cpu_to_le32(delay);
235 to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
236 to_send.c = data->batch_opt_buf[type];
237
238 switch (data->check_status[type]) {
239 case SSP_INITIALIZATION_STATE:
240 /* do calibration step, now just enable */
241 case SSP_ADD_SENSOR_STATE:
242 ret = ssp_send_instruction(data,
243 SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD,
244 type,
245 (u8 *)&to_send, sizeof(to_send));
246 if (ret < 0) {
247 dev_err(&data->spi->dev, "Enabling sensor failed\n");
248 data->check_status[type] = SSP_NO_SENSOR_STATE;
249 goto derror;
250 }
251
252 data->sensor_enable |= BIT(type);
253 data->check_status[type] = SSP_RUNNING_SENSOR_STATE;
254 break;
255 case SSP_RUNNING_SENSOR_STATE:
256 ret = ssp_send_instruction(data,
257 SSP_MSG2SSP_INST_CHANGE_DELAY, type,
258 (u8 *)&to_send, sizeof(to_send));
259 if (ret < 0) {
260 dev_err(&data->spi->dev,
261 "Changing sensor delay failed\n");
262 goto derror;
263 }
264 break;
265 default:
266 data->check_status[type] = SSP_ADD_SENSOR_STATE;
267 break;
268 }
269
270 data->delay_buf[type] = delay;
271
272 if (atomic_inc_return(&data->enable_refcount) == 1)
273 ssp_enable_wdt_timer(data);
274
275 return 0;
276
277derror:
278 return ret;
279}
280EXPORT_SYMBOL(ssp_enable_sensor);
281
282/**
283 * ssp_change_delay() - changes data acquisition for sensor
284 * @data: sensorhub structure
285 * @type: SSP sensor type
286 * @delay: delay in ms
287 *
288 * Returns 0 or negative value in case of error
289 */
290int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
291 u32 delay)
292{
293 int ret;
294 struct ssp_instruction to_send;
295
296 to_send.a = cpu_to_le32(delay);
297 to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
298 to_send.c = data->batch_opt_buf[type];
299
300 ret = ssp_send_instruction(data, SSP_MSG2SSP_INST_CHANGE_DELAY, type,
301 (u8 *)&to_send, sizeof(to_send));
302 if (ret < 0) {
303 dev_err(&data->spi->dev, "Changing sensor delay failed\n");
304 return ret;
305 }
306
307 data->delay_buf[type] = delay;
308
309 return 0;
310}
311EXPORT_SYMBOL(ssp_change_delay);
312
313/**
314 * ssp_disable_sensor() - disables sensor
315 *
316 * @data: sensorhub structure
317 * @type: SSP sensor type
318 *
319 * Returns 0 or negative value in case of error
320 */
321int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type)
322{
323 int ret;
324 __le32 command;
325
326 if (data->sensor_enable & BIT(type)) {
327 command = cpu_to_le32(data->delay_buf[type]);
328
329 ret = ssp_send_instruction(data,
330 SSP_MSG2SSP_INST_BYPASS_SENSOR_RM,
331 type, (u8 *)&command,
332 sizeof(command));
333 if (ret < 0) {
334 dev_err(&data->spi->dev, "Remove sensor fail\n");
335 return ret;
336 }
337
338 data->sensor_enable &= ~BIT(type);
339 }
340
341 data->check_status[type] = SSP_ADD_SENSOR_STATE;
342
343 if (atomic_dec_and_test(&data->enable_refcount))
344 ssp_disable_wdt_timer(data);
345
346 return 0;
347}
348EXPORT_SYMBOL(ssp_disable_sensor);
349
350static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id)
351{
352 struct ssp_data *data = dev_id;
353
354 /*
355 * This wrapper is done to preserve error path for ssp_irq_msg, also
356 * it is defined in different file.
357 */
358 ssp_irq_msg(data);
359
360 return IRQ_HANDLED;
361}
362
363static int ssp_initialize_mcu(struct ssp_data *data)
364{
365 int ret;
366
367 ssp_clean_pending_list(data);
368
369 ret = ssp_get_chipid(data);
370 if (ret != SSP_DEVICE_ID) {
371 dev_err(&data->spi->dev, "%s - MCU %s ret = %d\n", __func__,
372 ret < 0 ? "is not working" : "identification failed",
373 ret);
374 return ret < 0 ? ret : -ENODEV;
375 }
376
377 dev_info(&data->spi->dev, "MCU device ID = %d\n", ret);
378
379 /*
380 * needs clarification, for now do not want to export all transfer
381 * methods to sensors' drivers
382 */
383 ret = ssp_set_magnetic_matrix(data);
384 if (ret < 0) {
385 dev_err(&data->spi->dev,
386 "%s - ssp_set_magnetic_matrix failed\n", __func__);
387 return ret;
388 }
389
390 data->available_sensors = ssp_get_sensor_scanning_info(data);
391 if (data->available_sensors == 0) {
392 dev_err(&data->spi->dev,
393 "%s - ssp_get_sensor_scanning_info failed\n", __func__);
394 return -EIO;
395 }
396
397 data->cur_firm_rev = ssp_get_firmware_rev(data);
398 dev_info(&data->spi->dev, "MCU Firm Rev : New = %8u\n",
399 data->cur_firm_rev);
400
401 return ssp_command(data, SSP_MSG2SSP_AP_MCU_DUMP_CHECK, 0);
402}
403
404/*
405 * sensorhub can request its reinitialization as some brutal and rare error
406 * handling. It can be requested from the MCU.
407 */
408static void ssp_refresh_task(struct work_struct *work)
409{
410 struct ssp_data *data = container_of((struct delayed_work *)work,
411 struct ssp_data, work_refresh);
412
413 dev_info(&data->spi->dev, "refreshing\n");
414
415 data->reset_cnt++;
416
417 if (ssp_initialize_mcu(data) >= 0) {
418 ssp_sync_available_sensors(data);
419 if (data->last_ap_state != 0)
420 ssp_command(data, data->last_ap_state, 0);
421
422 if (data->last_resume_state != 0)
423 ssp_command(data, data->last_resume_state, 0);
424
425 data->timeout_cnt = 0;
426 data->com_fail_cnt = 0;
427 }
428}
429
430int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay)
431{
432 cancel_delayed_work_sync(&data->work_refresh);
433
434 return queue_delayed_work(system_power_efficient_wq,
435 &data->work_refresh,
436 msecs_to_jiffies(delay));
437}
438
439#ifdef CONFIG_OF
440static struct of_device_id ssp_of_match[] = {
441 {
442 .compatible = "samsung,sensorhub-rinato",
443 .data = &ssp_rinato_info,
444 }, {
445 .compatible = "samsung,sensorhub-thermostat",
446 .data = &ssp_thermostat_info,
447 },
448 {},
449};
450MODULE_DEVICE_TABLE(of, ssp_of_match);
451
452static struct ssp_data *ssp_parse_dt(struct device *dev)
453{
454 int ret;
455 struct ssp_data *data;
456 struct device_node *node = dev->of_node;
457 const struct of_device_id *match;
458
459 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
460 if (!data)
461 return NULL;
462
463 data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0);
464 if (data->mcu_ap_gpio < 0)
465 goto err_free_pd;
466
467 data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0);
468 if (data->ap_mcu_gpio < 0)
469 goto err_free_pd;
470
471 data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0);
472 if (data->mcu_reset_gpio < 0)
473 goto err_free_pd;
474
475 ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH,
476 "ap-mcu-gpios");
477 if (ret)
478 goto err_free_pd;
479
480 ret = devm_gpio_request_one(dev, data->mcu_reset_gpio,
481 GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios");
482 if (ret)
483 goto err_ap_mcu;
484
485 match = of_match_node(ssp_of_match, node);
486 if (!match)
487 goto err_mcu_reset_gpio;
488
489 data->sensorhub_info = (struct ssp_sensorhub_info *)match->data;
490
491 dev_set_drvdata(dev, data);
492
493 return data;
494
495err_mcu_reset_gpio:
496 devm_gpio_free(dev, data->mcu_reset_gpio);
497err_ap_mcu:
498 devm_gpio_free(dev, data->ap_mcu_gpio);
499err_free_pd:
500 devm_kfree(dev, data);
501 return NULL;
502}
503#else
504static struct ssp_data *ssp_parse_dt(struct device *pdev)
505{
506 return NULL;
507}
508#endif
509
510/**
511 * ssp_register_consumer() - registers iio consumer in ssp framework
512 *
513 * @indio_dev: consumer iio device
514 * @type: ssp sensor type
515 */
516void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type)
517{
518 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
519
520 data->sensor_devs[type] = indio_dev;
521}
522EXPORT_SYMBOL(ssp_register_consumer);
523
524static int ssp_probe(struct spi_device *spi)
525{
526 int ret, i;
527 struct ssp_data *data;
528
529 data = ssp_parse_dt(&spi->dev);
530 if (!data) {
531 dev_err(&spi->dev, "Failed to find platform data\n");
532 return -ENODEV;
533 }
534
535 ret = mfd_add_devices(&spi->dev, -1, sensorhub_sensor_devs,
536 ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL);
537 if (ret < 0) {
538 dev_err(&spi->dev, "mfd add devices fail\n");
539 return ret;
540 }
541
542 spi->mode = SPI_MODE_1;
543 ret = spi_setup(spi);
544 if (ret < 0) {
545 dev_err(&spi->dev, "Failed to setup spi\n");
546 return ret;
547 }
548
549 data->fw_dl_state = SSP_FW_DL_STATE_NONE;
550 data->spi = spi;
551 spi_set_drvdata(spi, data);
552
553 mutex_init(&data->comm_lock);
554
555 for (i = 0; i < SSP_SENSOR_MAX; ++i) {
556 data->delay_buf[i] = SSP_DEFAULT_POLLING_DELAY;
557 data->batch_latency_buf[i] = 0;
558 data->batch_opt_buf[i] = 0;
559 data->check_status[i] = SSP_INITIALIZATION_STATE;
560 }
561
562 data->delay_buf[SSP_BIO_HRM_LIB] = 100;
563
564 data->time_syncing = true;
565
566 mutex_init(&data->pending_lock);
567 INIT_LIST_HEAD(&data->pending_list);
568
569 atomic_set(&data->enable_refcount, 0);
570
571 INIT_WORK(&data->work_wdt, ssp_wdt_work_func);
572 INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task);
573
574 setup_timer(&data->wdt_timer, ssp_wdt_timer_func, (unsigned long)data);
575
576 ret = request_threaded_irq(data->spi->irq, NULL,
577 ssp_irq_thread_fn,
578 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
579 "SSP_Int", data);
580 if (ret < 0) {
581 dev_err(&spi->dev, "Irq request fail\n");
582 goto err_setup_irq;
583 }
584
585 /* Let's start with enabled one so irq balance could be ok */
586 data->shut_down = false;
587
588 /* just to avoid unbalanced irq set wake up */
589 enable_irq_wake(data->spi->irq);
590
591 data->fw_dl_state = ssp_check_fwbl(data);
592 if (data->fw_dl_state == SSP_FW_DL_STATE_NONE) {
593 ret = ssp_initialize_mcu(data);
594 if (ret < 0) {
595 dev_err(&spi->dev, "Initialize_mcu failed\n");
596 goto err_read_reg;
597 }
598 } else {
599 dev_err(&spi->dev, "Firmware version not supported\n");
600 ret = -EPERM;
601 goto err_read_reg;
602 }
603
604 return 0;
605
606err_read_reg:
607 free_irq(data->spi->irq, data);
608err_setup_irq:
609 mutex_destroy(&data->pending_lock);
610 mutex_destroy(&data->comm_lock);
611
612 dev_err(&spi->dev, "Probe failed!\n");
613
614 return ret;
615}
616
617static int ssp_remove(struct spi_device *spi)
618{
619 struct ssp_data *data = spi_get_drvdata(spi);
620
621 if (ssp_command(data, SSP_MSG2SSP_AP_STATUS_SHUTDOWN, 0) < 0)
622 dev_err(&data->spi->dev,
623 "SSP_MSG2SSP_AP_STATUS_SHUTDOWN failed\n");
624
625 ssp_enable_mcu(data, false);
626 ssp_disable_wdt_timer(data);
627
628 ssp_clean_pending_list(data);
629
630 free_irq(data->spi->irq, data);
631
632 del_timer_sync(&data->wdt_timer);
633 cancel_work_sync(&data->work_wdt);
634
635 mutex_destroy(&data->comm_lock);
636 mutex_destroy(&data->pending_lock);
637
638 mfd_remove_devices(&spi->dev);
639
640 return 0;
641}
642
643static int ssp_suspend(struct device *dev)
644{
645 int ret;
646 struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
647
648 data->last_resume_state = SSP_MSG2SSP_AP_STATUS_SUSPEND;
649
650 if (atomic_read(&data->enable_refcount) > 0)
651 ssp_disable_wdt_timer(data);
652
653 ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_SUSPEND, 0);
654 if (ret < 0) {
655 dev_err(&data->spi->dev,
656 "%s SSP_MSG2SSP_AP_STATUS_SUSPEND failed\n", __func__);
657
658 ssp_enable_wdt_timer(data);
659 return ret;
660 }
661
662 data->time_syncing = false;
663 disable_irq(data->spi->irq);
664
665 return 0;
666}
667
668static int ssp_resume(struct device *dev)
669{
670 int ret;
671 struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
672
673 enable_irq(data->spi->irq);
674
675 if (atomic_read(&data->enable_refcount) > 0)
676 ssp_enable_wdt_timer(data);
677
678 ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_RESUME, 0);
679 if (ret < 0) {
680 dev_err(&data->spi->dev,
681 "%s SSP_MSG2SSP_AP_STATUS_RESUME failed\n", __func__);
682 ssp_disable_wdt_timer(data);
683 return ret;
684 }
685
686 /* timesyncing is set by MCU */
687 data->last_resume_state = SSP_MSG2SSP_AP_STATUS_RESUME;
688
689 return 0;
690}
691
692static const struct dev_pm_ops ssp_pm_ops = {
693 SET_SYSTEM_SLEEP_PM_OPS(ssp_suspend, ssp_resume)
694};
695
696static struct spi_driver ssp_driver = {
697 .probe = ssp_probe,
698 .remove = ssp_remove,
699 .driver = {
700 .pm = &ssp_pm_ops,
701 .bus = &spi_bus_type,
702 .owner = THIS_MODULE,
703 .of_match_table = of_match_ptr(ssp_of_match),
704 .name = "sensorhub"
705 },
706};
707
708module_spi_driver(ssp_driver);
709
710MODULE_DESCRIPTION("ssp sensorhub driver");
711MODULE_AUTHOR("Samsung Electronics");
712MODULE_LICENSE("GPL");
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c
new file mode 100644
index 000000000000..a3ae165f8d9f
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_iio.c
@@ -0,0 +1,107 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/iio/common/ssp_sensors.h>
17#include <linux/iio/kfifo_buf.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include "ssp_iio_sensor.h"
21
22/**
23 * ssp_common_buffer_postenable() - generic postenable callback for ssp buffer
24 *
25 * @indio_dev: iio device
26 *
27 * Returns 0 or negative value in case of error
28 */
29int ssp_common_buffer_postenable(struct iio_dev *indio_dev)
30{
31 struct ssp_sensor_data *spd = iio_priv(indio_dev);
32 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
33
34 /* the allocation is made in post because scan size is known in this
35 * moment
36 * */
37 spd->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA);
38 if (!spd->buffer)
39 return -ENOMEM;
40
41 return ssp_enable_sensor(data, spd->type,
42 ssp_get_sensor_delay(data, spd->type));
43}
44EXPORT_SYMBOL(ssp_common_buffer_postenable);
45
46/**
47 * ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer
48 *
49 * @indio_dev: iio device
50 *
51 * Returns 0 or negative value in case of error
52 */
53int ssp_common_buffer_postdisable(struct iio_dev *indio_dev)
54{
55 int ret;
56 struct ssp_sensor_data *spd = iio_priv(indio_dev);
57 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
58
59 ret = ssp_disable_sensor(data, spd->type);
60 if (ret < 0)
61 return ret;
62
63 kfree(spd->buffer);
64
65 return ret;
66}
67EXPORT_SYMBOL(ssp_common_buffer_postdisable);
68
69/**
70 * ssp_common_process_data() - Common process data callback for ssp sensors
71 *
72 * @indio_dev: iio device
73 * @buf: source buffer
74 * @len: sensor data length
75 * @timestamp: system timestamp
76 *
77 * Returns 0 or negative value in case of error
78 */
79int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
80 unsigned int len, int64_t timestamp)
81{
82 __le32 time;
83 int64_t calculated_time;
84 struct ssp_sensor_data *spd = iio_priv(indio_dev);
85
86 if (indio_dev->scan_bytes == 0)
87 return 0;
88
89 /*
90 * it always sends full set of samples, remember about available masks
91 */
92 memcpy(spd->buffer, buf, len);
93
94 if (indio_dev->scan_timestamp) {
95 memcpy(&time, &((char *)buf)[len], SSP_TIME_SIZE);
96 calculated_time =
97 timestamp + (int64_t)le32_to_cpu(time) * 1000000;
98 }
99
100 return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer,
101 calculated_time);
102}
103EXPORT_SYMBOL(ssp_common_process_data);
104
105MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
106MODULE_DESCRIPTION("Samsung sensorhub commons");
107MODULE_LICENSE("GPL");
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
new file mode 100644
index 000000000000..541c6590d69c
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
@@ -0,0 +1,71 @@
1#ifndef __SSP_IIO_SENSOR_H__
2#define __SSP_IIO_SENSOR_H__
3
4#define SSP_CHANNEL_AG(_type, _mod, _index) \
5{ \
6 .type = _type,\
7 .modified = 1,\
8 .channel2 = _mod,\
9 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
10 .scan_index = _index,\
11 .scan_type = {\
12 .sign = 's',\
13 .realbits = 16,\
14 .storagebits = 16,\
15 .shift = 0,\
16 .endianness = IIO_LE,\
17 },\
18}
19
20/* It is defined here as it is a mixed timestamp */
21#define SSP_CHAN_TIMESTAMP(_si) { \
22 .type = IIO_TIMESTAMP, \
23 .channel = -1, \
24 .scan_index = _si, \
25 .scan_type = { \
26 .sign = 's', \
27 .realbits = 64, \
28 .storagebits = 64, \
29 }, \
30}
31
32#define SSP_MS_PER_S 1000
33#define SSP_INVERTED_SCALING_FACTOR 1000000U
34
35#define SSP_FACTOR_WITH_MS \
36 (SSP_INVERTED_SCALING_FACTOR * SSP_MS_PER_S)
37
38int ssp_common_buffer_postenable(struct iio_dev *indio_dev);
39
40int ssp_common_buffer_postdisable(struct iio_dev *indio_dev);
41
42int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
43 unsigned int len, int64_t timestamp);
44
45/* Converts time in ms to frequency */
46static inline void ssp_convert_to_freq(u32 time, int *integer_part,
47 int *fractional)
48{
49 if (time == 0) {
50 *fractional = 0;
51 *integer_part = 0;
52 return;
53 }
54
55 *integer_part = SSP_FACTOR_WITH_MS / time;
56 *fractional = *integer_part % SSP_INVERTED_SCALING_FACTOR;
57 *integer_part = *integer_part / SSP_INVERTED_SCALING_FACTOR;
58}
59
60/* Converts frequency to time in ms */
61static inline int ssp_convert_to_time(int integer_part, int fractional)
62{
63 u64 value;
64
65 value = (u64)integer_part * SSP_INVERTED_SCALING_FACTOR + fractional;
66 if (value == 0)
67 return 0;
68
69 return div64_u64((u64)SSP_FACTOR_WITH_MS, value);
70}
71#endif /* __SSP_IIO_SENSOR_H__ */
diff --git a/drivers/iio/common/ssp_sensors/ssp_spi.c b/drivers/iio/common/ssp_sensors/ssp_spi.c
new file mode 100644
index 000000000000..704284a475ae
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_spi.c
@@ -0,0 +1,608 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include "ssp.h"
17
18#define SSP_DEV (&data->spi->dev)
19#define SSP_GET_MESSAGE_TYPE(data) (data & (3 << SSP_RW))
20
21/*
22 * SSP -> AP Instruction
23 * They tell what packet type can be expected. In the future there will
24 * be less of them. BYPASS means common sensor packets with accel, gyro,
25 * hrm etc. data. LIBRARY and META are mock-up's for now.
26 */
27#define SSP_MSG2AP_INST_BYPASS_DATA 0x37
28#define SSP_MSG2AP_INST_LIBRARY_DATA 0x01
29#define SSP_MSG2AP_INST_DEBUG_DATA 0x03
30#define SSP_MSG2AP_INST_BIG_DATA 0x04
31#define SSP_MSG2AP_INST_META_DATA 0x05
32#define SSP_MSG2AP_INST_TIME_SYNC 0x06
33#define SSP_MSG2AP_INST_RESET 0x07
34
35#define SSP_UNIMPLEMENTED -1
36
37struct ssp_msg_header {
38 u8 cmd;
39 __le16 length;
40 __le16 options;
41 __le32 data;
42} __attribute__((__packed__));
43
44struct ssp_msg {
45 u16 length;
46 u16 options;
47 struct list_head list;
48 struct completion *done;
49 struct ssp_msg_header *h;
50 char *buffer;
51};
52
53static const int ssp_offset_map[SSP_SENSOR_MAX] = {
54 [SSP_ACCELEROMETER_SENSOR] = SSP_ACCELEROMETER_SIZE +
55 SSP_TIME_SIZE,
56 [SSP_GYROSCOPE_SENSOR] = SSP_GYROSCOPE_SIZE +
57 SSP_TIME_SIZE,
58 [SSP_GEOMAGNETIC_UNCALIB_SENSOR] = SSP_UNIMPLEMENTED,
59 [SSP_GEOMAGNETIC_RAW] = SSP_UNIMPLEMENTED,
60 [SSP_GEOMAGNETIC_SENSOR] = SSP_UNIMPLEMENTED,
61 [SSP_PRESSURE_SENSOR] = SSP_UNIMPLEMENTED,
62 [SSP_GESTURE_SENSOR] = SSP_UNIMPLEMENTED,
63 [SSP_PROXIMITY_SENSOR] = SSP_UNIMPLEMENTED,
64 [SSP_TEMPERATURE_HUMIDITY_SENSOR] = SSP_UNIMPLEMENTED,
65 [SSP_LIGHT_SENSOR] = SSP_UNIMPLEMENTED,
66 [SSP_PROXIMITY_RAW] = SSP_UNIMPLEMENTED,
67 [SSP_ORIENTATION_SENSOR] = SSP_UNIMPLEMENTED,
68 [SSP_STEP_DETECTOR] = SSP_UNIMPLEMENTED,
69 [SSP_SIG_MOTION_SENSOR] = SSP_UNIMPLEMENTED,
70 [SSP_GYRO_UNCALIB_SENSOR] = SSP_UNIMPLEMENTED,
71 [SSP_GAME_ROTATION_VECTOR] = SSP_UNIMPLEMENTED,
72 [SSP_ROTATION_VECTOR] = SSP_UNIMPLEMENTED,
73 [SSP_STEP_COUNTER] = SSP_UNIMPLEMENTED,
74 [SSP_BIO_HRM_RAW] = SSP_BIO_HRM_RAW_SIZE +
75 SSP_TIME_SIZE,
76 [SSP_BIO_HRM_RAW_FAC] = SSP_BIO_HRM_RAW_FAC_SIZE +
77 SSP_TIME_SIZE,
78 [SSP_BIO_HRM_LIB] = SSP_BIO_HRM_LIB_SIZE +
79 SSP_TIME_SIZE,
80};
81
82#define SSP_HEADER_SIZE (sizeof(struct ssp_msg_header))
83#define SSP_HEADER_SIZE_ALIGNED (ALIGN(SSP_HEADER_SIZE, 4))
84
85static struct ssp_msg *ssp_create_msg(u8 cmd, u16 len, u16 opt, u32 data)
86{
87 struct ssp_msg_header h;
88 struct ssp_msg *msg;
89
90 msg = kzalloc(sizeof(*msg), GFP_KERNEL);
91 if (!msg)
92 return NULL;
93
94 h.cmd = cmd;
95 h.length = cpu_to_le16(len);
96 h.options = cpu_to_le16(opt);
97 h.data = cpu_to_le32(data);
98
99 msg->buffer = kzalloc(SSP_HEADER_SIZE_ALIGNED + len,
100 GFP_KERNEL | GFP_DMA);
101 if (!msg->buffer) {
102 kfree(msg);
103 return NULL;
104 }
105
106 msg->length = len;
107 msg->options = opt;
108
109 memcpy(msg->buffer, &h, SSP_HEADER_SIZE);
110
111 return msg;
112}
113
114/*
115 * It is a bit heavy to do it this way but often the function is used to compose
116 * the message from smaller chunks which are placed on the stack. Often the
117 * chunks are small so memcpy should be optimalized.
118 */
119static inline void ssp_fill_buffer(struct ssp_msg *m, unsigned int offset,
120 const void *src, unsigned int len)
121{
122 memcpy(&m->buffer[SSP_HEADER_SIZE_ALIGNED + offset], src, len);
123}
124
125static inline void ssp_get_buffer(struct ssp_msg *m, unsigned int offset,
126 void *dest, unsigned int len)
127{
128 memcpy(dest, &m->buffer[SSP_HEADER_SIZE_ALIGNED + offset], len);
129}
130
131#define SSP_GET_BUFFER_AT_INDEX(m, index) \
132 (m->buffer[SSP_HEADER_SIZE_ALIGNED + index])
133#define SSP_SET_BUFFER_AT_INDEX(m, index, val) \
134 (m->buffer[SSP_HEADER_SIZE_ALIGNED + index] = val)
135
136static void ssp_clean_msg(struct ssp_msg *m)
137{
138 kfree(m->buffer);
139 kfree(m);
140}
141
142static int ssp_print_mcu_debug(char *data_frame, int *data_index,
143 int received_len)
144{
145 int length = data_frame[(*data_index)++];
146
147 if (length > received_len - *data_index || length <= 0) {
148 ssp_dbg("[SSP]: MSG From MCU-invalid debug length(%d/%d)\n",
149 length, received_len);
150 return length ? length : -EPROTO;
151 }
152
153 ssp_dbg("[SSP]: MSG From MCU - %s\n", &data_frame[*data_index]);
154
155 *data_index += length;
156
157 return 0;
158}
159
160/*
161 * It was designed that way - additional lines to some kind of handshake,
162 * please do not ask why - only the firmware guy can know it.
163 */
164static int ssp_check_lines(struct ssp_data *data, bool state)
165{
166 int delay_cnt = 0;
167
168 gpio_set_value_cansleep(data->ap_mcu_gpio, state);
169
170 while (gpio_get_value_cansleep(data->mcu_ap_gpio) != state) {
171 usleep_range(3000, 3500);
172
173 if (data->shut_down || delay_cnt++ > 500) {
174 dev_err(SSP_DEV, "%s:timeout, hw ack wait fail %d\n",
175 __func__, state);
176
177 if (!state)
178 gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
179
180 return -ETIMEDOUT;
181 }
182 }
183
184 return 0;
185}
186
187static int ssp_do_transfer(struct ssp_data *data, struct ssp_msg *msg,
188 struct completion *done, int timeout)
189{
190 int status;
191 /*
192 * check if this is a short one way message or the whole transfer has
193 * second part after an interrupt
194 */
195 const bool use_no_irq = msg->length == 0;
196
197 if (data->shut_down)
198 return -EPERM;
199
200 msg->done = done;
201
202 mutex_lock(&data->comm_lock);
203
204 status = ssp_check_lines(data, false);
205 if (status < 0)
206 goto _error_locked;
207
208 status = spi_write(data->spi, msg->buffer, SSP_HEADER_SIZE);
209 if (status < 0) {
210 gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
211 dev_err(SSP_DEV, "%s spi_write fail\n", __func__);
212 goto _error_locked;
213 }
214
215 if (!use_no_irq) {
216 mutex_lock(&data->pending_lock);
217 list_add_tail(&msg->list, &data->pending_list);
218 mutex_unlock(&data->pending_lock);
219 }
220
221 status = ssp_check_lines(data, true);
222 if (status < 0) {
223 if (!use_no_irq) {
224 mutex_lock(&data->pending_lock);
225 list_del(&msg->list);
226 mutex_unlock(&data->pending_lock);
227 }
228 goto _error_locked;
229 }
230
231 mutex_unlock(&data->comm_lock);
232
233 if (!use_no_irq && done)
234 if (wait_for_completion_timeout(done,
235 msecs_to_jiffies(timeout)) ==
236 0) {
237 mutex_lock(&data->pending_lock);
238 list_del(&msg->list);
239 mutex_unlock(&data->pending_lock);
240
241 data->timeout_cnt++;
242 return -ETIMEDOUT;
243 }
244
245 return 0;
246
247_error_locked:
248 mutex_unlock(&data->comm_lock);
249 data->timeout_cnt++;
250 return status;
251}
252
253static inline int ssp_spi_sync_command(struct ssp_data *data,
254 struct ssp_msg *msg)
255{
256 return ssp_do_transfer(data, msg, NULL, 0);
257}
258
259static int ssp_spi_sync(struct ssp_data *data, struct ssp_msg *msg,
260 int timeout)
261{
262 DECLARE_COMPLETION_ONSTACK(done);
263
264 if (WARN_ON(!msg->length))
265 return -EPERM;
266
267 return ssp_do_transfer(data, msg, &done, timeout);
268}
269
270static int ssp_handle_big_data(struct ssp_data *data, char *dataframe, int *idx)
271{
272 /* mock-up, it will be changed with adding another sensor types */
273 *idx += 8;
274 return 0;
275}
276
277static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
278{
279 int idx, sd;
280 struct timespec ts;
281 struct ssp_sensor_data *spd;
282 struct iio_dev **indio_devs = data->sensor_devs;
283
284 getnstimeofday(&ts);
285
286 for (idx = 0; idx < len;) {
287 switch (dataframe[idx++]) {
288 case SSP_MSG2AP_INST_BYPASS_DATA:
289 sd = dataframe[idx++];
290 if (sd < 0 || sd >= SSP_SENSOR_MAX) {
291 dev_err(SSP_DEV,
292 "Mcu data frame1 error %d\n", sd);
293 return -EPROTO;
294 }
295
296 if (indio_devs[sd]) {
297 spd = iio_priv(indio_devs[sd]);
298 if (spd->process_data)
299 spd->process_data(indio_devs[sd],
300 &dataframe[idx],
301 data->timestamp);
302 } else {
303 dev_err(SSP_DEV, "no client for frame\n");
304 }
305
306 idx += ssp_offset_map[sd];
307 break;
308 case SSP_MSG2AP_INST_DEBUG_DATA:
309 sd = ssp_print_mcu_debug(dataframe, &idx, len);
310 if (sd) {
311 dev_err(SSP_DEV,
312 "Mcu data frame3 error %d\n", sd);
313 return sd;
314 }
315 break;
316 case SSP_MSG2AP_INST_LIBRARY_DATA:
317 idx += len;
318 break;
319 case SSP_MSG2AP_INST_BIG_DATA:
320 ssp_handle_big_data(data, dataframe, &idx);
321 break;
322 case SSP_MSG2AP_INST_TIME_SYNC:
323 data->time_syncing = true;
324 break;
325 case SSP_MSG2AP_INST_RESET:
326 ssp_queue_ssp_refresh_task(data, 0);
327 break;
328 }
329 }
330
331 if (data->time_syncing)
332 data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
333
334 return 0;
335}
336
337/* threaded irq */
338int ssp_irq_msg(struct ssp_data *data)
339{
340 bool found = false;
341 char *buffer;
342 u8 msg_type;
343 int ret;
344 u16 length, msg_options;
345 struct ssp_msg *msg, *n;
346
347 ret = spi_read(data->spi, data->header_buffer, SSP_HEADER_BUFFER_SIZE);
348 if (ret < 0) {
349 dev_err(SSP_DEV, "header read fail\n");
350 return ret;
351 }
352
353 length = le16_to_cpu(data->header_buffer[1]);
354 msg_options = le16_to_cpu(data->header_buffer[0]);
355
356 if (length == 0) {
357 dev_err(SSP_DEV, "length received from mcu is 0\n");
358 return -EINVAL;
359 }
360
361 msg_type = SSP_GET_MESSAGE_TYPE(msg_options);
362
363 switch (msg_type) {
364 case SSP_AP2HUB_READ:
365 case SSP_AP2HUB_WRITE:
366 /*
367 * this is a small list, a few elements - the packets can be
368 * received with no order
369 */
370 mutex_lock(&data->pending_lock);
371 list_for_each_entry_safe(msg, n, &data->pending_list, list) {
372 if (msg->options == msg_options) {
373 list_del(&msg->list);
374 found = true;
375 break;
376 }
377 }
378
379 if (!found) {
380 /*
381 * here can be implemented dead messages handling
382 * but the slave should not send such ones - it is to
383 * check but let's handle this
384 */
385 buffer = kmalloc(length, GFP_KERNEL | GFP_DMA);
386 if (!buffer) {
387 ret = -ENOMEM;
388 goto _unlock;
389 }
390
391 /* got dead packet so it is always an error */
392 ret = spi_read(data->spi, buffer, length);
393 if (ret >= 0)
394 ret = -EPROTO;
395
396 kfree(buffer);
397
398 dev_err(SSP_DEV, "No match error %x\n",
399 msg_options);
400
401 goto _unlock;
402 }
403
404 if (msg_type == SSP_AP2HUB_READ)
405 ret = spi_read(data->spi,
406 &msg->buffer[SSP_HEADER_SIZE_ALIGNED],
407 msg->length);
408
409 if (msg_type == SSP_AP2HUB_WRITE) {
410 ret = spi_write(data->spi,
411 &msg->buffer[SSP_HEADER_SIZE_ALIGNED],
412 msg->length);
413 if (msg_options & SSP_AP2HUB_RETURN) {
414 msg->options =
415 SSP_AP2HUB_READ | SSP_AP2HUB_RETURN;
416 msg->length = 1;
417
418 list_add_tail(&msg->list, &data->pending_list);
419 goto _unlock;
420 }
421 }
422
423 if (msg->done)
424 if (!completion_done(msg->done))
425 complete(msg->done);
426_unlock:
427 mutex_unlock(&data->pending_lock);
428 break;
429 case SSP_HUB2AP_WRITE:
430 buffer = kzalloc(length, GFP_KERNEL | GFP_DMA);
431 if (!buffer)
432 return -ENOMEM;
433
434 ret = spi_read(data->spi, buffer, length);
435 if (ret < 0) {
436 dev_err(SSP_DEV, "spi read fail\n");
437 kfree(buffer);
438 break;
439 }
440
441 ret = ssp_parse_dataframe(data, buffer, length);
442
443 kfree(buffer);
444 break;
445
446 default:
447 dev_err(SSP_DEV, "unknown msg type\n");
448 return -EPROTO;
449 }
450
451 return ret;
452}
453
454void ssp_clean_pending_list(struct ssp_data *data)
455{
456 struct ssp_msg *msg, *n;
457
458 mutex_lock(&data->pending_lock);
459 list_for_each_entry_safe(msg, n, &data->pending_list, list) {
460 list_del(&msg->list);
461
462 if (msg->done)
463 if (!completion_done(msg->done))
464 complete(msg->done);
465 }
466 mutex_unlock(&data->pending_lock);
467}
468
469int ssp_command(struct ssp_data *data, char command, int arg)
470{
471 int ret;
472 struct ssp_msg *msg;
473
474 msg = ssp_create_msg(command, 0, SSP_AP2HUB_WRITE, arg);
475 if (!msg)
476 return -ENOMEM;
477
478 ssp_dbg("%s - command 0x%x %d\n", __func__, command, arg);
479
480 ret = ssp_spi_sync_command(data, msg);
481 ssp_clean_msg(msg);
482
483 return ret;
484}
485
486int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type,
487 u8 *send_buf, u8 length)
488{
489 int ret;
490 struct ssp_msg *msg;
491
492 if (data->fw_dl_state == SSP_FW_DL_STATE_DOWNLOADING) {
493 dev_err(SSP_DEV, "%s - Skip Inst! DL state = %d\n",
494 __func__, data->fw_dl_state);
495 return -EBUSY;
496 } else if (!(data->available_sensors & BIT(sensor_type)) &&
497 (inst <= SSP_MSG2SSP_INST_CHANGE_DELAY)) {
498 dev_err(SSP_DEV, "%s - Bypass Inst Skip! - %u\n",
499 __func__, sensor_type);
500 return -EIO; /* just fail */
501 }
502
503 msg = ssp_create_msg(inst, length + 2, SSP_AP2HUB_WRITE, 0);
504 if (!msg)
505 return -ENOMEM;
506
507 ssp_fill_buffer(msg, 0, &sensor_type, 1);
508 ssp_fill_buffer(msg, 1, send_buf, length);
509
510 ssp_dbg("%s - Inst = 0x%x, Sensor Type = 0x%x, data = %u\n",
511 __func__, inst, sensor_type, send_buf[1]);
512
513 ret = ssp_spi_sync(data, msg, 1000);
514 ssp_clean_msg(msg);
515
516 return ret;
517}
518
519int ssp_get_chipid(struct ssp_data *data)
520{
521 int ret;
522 char buffer;
523 struct ssp_msg *msg;
524
525 msg = ssp_create_msg(SSP_MSG2SSP_AP_WHOAMI, 1, SSP_AP2HUB_READ, 0);
526 if (!msg)
527 return -ENOMEM;
528
529 ret = ssp_spi_sync(data, msg, 1000);
530
531 buffer = SSP_GET_BUFFER_AT_INDEX(msg, 0);
532
533 ssp_clean_msg(msg);
534
535 return ret < 0 ? ret : buffer;
536}
537
538int ssp_set_magnetic_matrix(struct ssp_data *data)
539{
540 int ret;
541 struct ssp_msg *msg;
542
543 msg = ssp_create_msg(SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX,
544 data->sensorhub_info->mag_length, SSP_AP2HUB_WRITE,
545 0);
546 if (!msg)
547 return -ENOMEM;
548
549 ssp_fill_buffer(msg, 0, data->sensorhub_info->mag_table,
550 data->sensorhub_info->mag_length);
551
552 ret = ssp_spi_sync(data, msg, 1000);
553 ssp_clean_msg(msg);
554
555 return ret;
556}
557
558unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data)
559{
560 int ret;
561 __le32 result;
562 u32 cpu_result = 0;
563
564 struct ssp_msg *msg = ssp_create_msg(SSP_MSG2SSP_AP_SENSOR_SCANNING, 4,
565 SSP_AP2HUB_READ, 0);
566 if (!msg)
567 return 0;
568
569 ret = ssp_spi_sync(data, msg, 1000);
570 if (ret < 0) {
571 dev_err(SSP_DEV, "%s - spi read fail %d\n", __func__, ret);
572 goto _exit;
573 }
574
575 ssp_get_buffer(msg, 0, &result, 4);
576 cpu_result = le32_to_cpu(result);
577
578 dev_info(SSP_DEV, "%s state: 0x%08x\n", __func__, cpu_result);
579
580_exit:
581 ssp_clean_msg(msg);
582 return cpu_result;
583}
584
585unsigned int ssp_get_firmware_rev(struct ssp_data *data)
586{
587 int ret;
588 __le32 result;
589
590 struct ssp_msg *msg = ssp_create_msg(SSP_MSG2SSP_AP_FIRMWARE_REV, 4,
591 SSP_AP2HUB_READ, 0);
592 if (!msg)
593 return SSP_INVALID_REVISION;
594
595 ret = ssp_spi_sync(data, msg, 1000);
596 if (ret < 0) {
597 dev_err(SSP_DEV, "%s - transfer fail %d\n", __func__, ret);
598 ret = SSP_INVALID_REVISION;
599 goto _exit;
600 }
601
602 ssp_get_buffer(msg, 0, &result, 4);
603 ret = le32_to_cpu(result);
604
605_exit:
606 ssp_clean_msg(msg);
607 return ret;
608}
diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
index 78a6a1ab3ece..5b377373f48d 100644
--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
+++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
@@ -54,7 +54,7 @@ static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
54 if (err) 54 if (err)
55 goto acc_spi_read_error; 55 goto acc_spi_read_error;
56 56
57 memcpy(data, tb->rx_buf, len*sizeof(u8)); 57 memcpy(data, tb->rx_buf, len);
58 mutex_unlock(&tb->buf_lock); 58 mutex_unlock(&tb->buf_lock);
59 return len; 59 return len;
60 60
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 7c5245d9f99c..50ed8d1ca45a 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -445,7 +445,7 @@ static int ad9523_store_eeprom(struct iio_dev *indio_dev)
445 445
446 tmp = 4; 446 tmp = 4;
447 do { 447 do {
448 msleep(16); 448 msleep(20);
449 ret = ad9523_read(indio_dev, 449 ret = ad9523_read(indio_dev,
450 AD9523_EEPROM_DATA_XFER_STATUS); 450 AD9523_EEPROM_DATA_XFER_STATUS);
451 if (ret < 0) 451 if (ret < 0)
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
index 63a25d9e1204..10a0dfc3b01f 100644
--- a/drivers/iio/frequency/adf4350.c
+++ b/drivers/iio/frequency/adf4350.c
@@ -387,10 +387,8 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
387 int ret; 387 int ret;
388 388
389 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 389 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
390 if (!pdata) { 390 if (!pdata)
391 dev_err(dev, "could not allocate memory for platform data\n");
392 return NULL; 391 return NULL;
393 }
394 392
395 strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1); 393 strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1);
396 394
@@ -613,9 +611,8 @@ static int adf4350_remove(struct spi_device *spi)
613 if (st->clk) 611 if (st->clk)
614 clk_disable_unprepare(st->clk); 612 clk_disable_unprepare(st->clk);
615 613
616 if (!IS_ERR(reg)) { 614 if (!IS_ERR(reg))
617 regulator_disable(reg); 615 regulator_disable(reg);
618 }
619 616
620 return 0; 617 return 0;
621} 618}
diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile
index 36a38776f739..f46341b39139 100644
--- a/drivers/iio/gyro/Makefile
+++ b/drivers/iio/gyro/Makefile
@@ -16,6 +16,8 @@ itg3200-y := itg3200_core.o
16itg3200-$(CONFIG_IIO_BUFFER) += itg3200_buffer.o 16itg3200-$(CONFIG_IIO_BUFFER) += itg3200_buffer.o
17obj-$(CONFIG_ITG3200) += itg3200.o 17obj-$(CONFIG_ITG3200) += itg3200.o
18 18
19obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_gyro_sensor.o
20
19obj-$(CONFIG_IIO_ST_GYRO_3AXIS) += st_gyro.o 21obj-$(CONFIG_IIO_ST_GYRO_3AXIS) += st_gyro.o
20st_gyro-y := st_gyro_core.o 22st_gyro-y := st_gyro_core.o
21st_gyro-$(CONFIG_IIO_BUFFER) += st_gyro_buffer.o 23st_gyro-$(CONFIG_IIO_BUFFER) += st_gyro_buffer.o
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index a3ea1e8785d7..a3c3e19de527 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -111,19 +111,12 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
111 int report_id = -1; 111 int report_id = -1;
112 u32 address; 112 u32 address;
113 int ret_type; 113 int ret_type;
114 s32 poll_value;
115 114
116 *val = 0; 115 *val = 0;
117 *val2 = 0; 116 *val2 = 0;
118 switch (mask) { 117 switch (mask) {
119 case 0: 118 case 0:
120 poll_value = hid_sensor_read_poll_value(
121 &gyro_state->common_attributes);
122 if (poll_value < 0)
123 return -EINVAL;
124
125 hid_sensor_power_state(&gyro_state->common_attributes, true); 119 hid_sensor_power_state(&gyro_state->common_attributes, true);
126 msleep_interruptible(poll_value * 2);
127 report_id = gyro_state->gyro[chan->scan_index].report_id; 120 report_id = gyro_state->gyro[chan->scan_index].report_id;
128 address = gyro_3d_addresses[chan->scan_index]; 121 address = gyro_3d_addresses[chan->scan_index];
129 if (report_id >= 0) 122 if (report_id >= 0)
@@ -416,6 +409,7 @@ static struct platform_driver hid_gyro_3d_platform_driver = {
416 .id_table = hid_gyro_3d_ids, 409 .id_table = hid_gyro_3d_ids,
417 .driver = { 410 .driver = {
418 .name = KBUILD_MODNAME, 411 .name = KBUILD_MODNAME,
412 .pm = &hid_sensor_pm_ops,
419 }, 413 },
420 .probe = hid_gyro_3d_probe, 414 .probe = hid_gyro_3d_probe,
421 .remove = hid_gyro_3d_remove, 415 .remove = hid_gyro_3d_remove,
diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c
new file mode 100644
index 000000000000..0a8afdd21728
--- /dev/null
+++ b/drivers/iio/gyro/ssp_gyro_sensor.c
@@ -0,0 +1,168 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/iio/common/ssp_sensors.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/kfifo_buf.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include "../common/ssp_sensors/ssp_iio_sensor.h"
23
24#define SSP_CHANNEL_COUNT 3
25
26#define SSP_GYROSCOPE_NAME "ssp-gyroscope"
27static const char ssp_gyro_name[] = SSP_GYROSCOPE_NAME;
28
29enum ssp_gyro_3d_channel {
30 SSP_CHANNEL_SCAN_INDEX_X,
31 SSP_CHANNEL_SCAN_INDEX_Y,
32 SSP_CHANNEL_SCAN_INDEX_Z,
33 SSP_CHANNEL_SCAN_INDEX_TIME,
34};
35
36static int ssp_gyro_read_raw(struct iio_dev *indio_dev,
37 struct iio_chan_spec const *chan, int *val,
38 int *val2, long mask)
39{
40 u32 t;
41 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
42
43 switch (mask) {
44 case IIO_CHAN_INFO_SAMP_FREQ:
45 t = ssp_get_sensor_delay(data, SSP_GYROSCOPE_SENSOR);
46 ssp_convert_to_freq(t, val, val2);
47 return IIO_VAL_INT_PLUS_MICRO;
48 default:
49 break;
50 }
51
52 return -EINVAL;
53}
54
55static int ssp_gyro_write_raw(struct iio_dev *indio_dev,
56 struct iio_chan_spec const *chan, int val,
57 int val2, long mask)
58{
59 int ret;
60 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
61
62 switch (mask) {
63 case IIO_CHAN_INFO_SAMP_FREQ:
64 ret = ssp_convert_to_time(val, val2);
65 ret = ssp_change_delay(data, SSP_GYROSCOPE_SENSOR, ret);
66 if (ret < 0)
67 dev_err(&indio_dev->dev, "gyro sensor enable fail\n");
68
69 return ret;
70 default:
71 break;
72 }
73
74 return -EINVAL;
75}
76
77static struct iio_info ssp_gyro_iio_info = {
78 .read_raw = &ssp_gyro_read_raw,
79 .write_raw = &ssp_gyro_write_raw,
80};
81
82static const unsigned long ssp_gyro_scan_mask[] = { 0x07, 0, };
83
84static const struct iio_chan_spec ssp_gyro_channels[] = {
85 SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
86 SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
87 SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
88 SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
89};
90
91static int ssp_process_gyro_data(struct iio_dev *indio_dev, void *buf,
92 int64_t timestamp)
93{
94 return ssp_common_process_data(indio_dev, buf, SSP_GYROSCOPE_SIZE,
95 timestamp);
96}
97
98static const struct iio_buffer_setup_ops ssp_gyro_buffer_ops = {
99 .postenable = &ssp_common_buffer_postenable,
100 .postdisable = &ssp_common_buffer_postdisable,
101};
102
103static int ssp_gyro_probe(struct platform_device *pdev)
104{
105 int ret;
106 struct iio_dev *indio_dev;
107 struct ssp_sensor_data *spd;
108 struct iio_buffer *buffer;
109
110 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));
111 if (!indio_dev)
112 return -ENOMEM;
113
114 spd = iio_priv(indio_dev);
115
116 spd->process_data = ssp_process_gyro_data;
117 spd->type = SSP_GYROSCOPE_SENSOR;
118
119 indio_dev->name = ssp_gyro_name;
120 indio_dev->dev.parent = &pdev->dev;
121 indio_dev->info = &ssp_gyro_iio_info;
122 indio_dev->modes = INDIO_BUFFER_SOFTWARE;
123 indio_dev->channels = ssp_gyro_channels;
124 indio_dev->num_channels = ARRAY_SIZE(ssp_gyro_channels);
125 indio_dev->available_scan_masks = ssp_gyro_scan_mask;
126
127 buffer = devm_iio_kfifo_allocate(&pdev->dev);
128 if (!buffer)
129 return -ENOMEM;
130
131 iio_device_attach_buffer(indio_dev, buffer);
132
133 indio_dev->setup_ops = &ssp_gyro_buffer_ops;
134
135 platform_set_drvdata(pdev, indio_dev);
136
137 ret = iio_device_register(indio_dev);
138 if (ret < 0)
139 return ret;
140
141 /* ssp registering should be done after all iio setup */
142 ssp_register_consumer(indio_dev, SSP_GYROSCOPE_SENSOR);
143
144 return 0;
145}
146
147static int ssp_gyro_remove(struct platform_device *pdev)
148{
149 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
150
151 iio_device_unregister(indio_dev);
152
153 return 0;
154}
155
156static struct platform_driver ssp_gyro_driver = {
157 .driver = {
158 .name = SSP_GYROSCOPE_NAME,
159 },
160 .probe = ssp_gyro_probe,
161 .remove = ssp_gyro_remove,
162};
163
164module_platform_driver(ssp_gyro_driver);
165
166MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
167MODULE_DESCRIPTION("Samsung sensorhub gyroscopes driver");
168MODULE_LICENSE("GPL");
diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
index 5f0ea77fe717..359883525ab7 100644
--- a/drivers/iio/iio_core.h
+++ b/drivers/iio/iio_core.h
@@ -48,6 +48,8 @@ unsigned int iio_buffer_poll(struct file *filp,
48ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, 48ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
49 size_t n, loff_t *f_ps); 49 size_t n, loff_t *f_ps);
50 50
51int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev);
52void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev);
51 53
52#define iio_buffer_poll_addr (&iio_buffer_poll) 54#define iio_buffer_poll_addr (&iio_buffer_poll)
53#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer) 55#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
@@ -60,6 +62,13 @@ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
60#define iio_buffer_poll_addr NULL 62#define iio_buffer_poll_addr NULL
61#define iio_buffer_read_first_n_outer_addr NULL 63#define iio_buffer_read_first_n_outer_addr NULL
62 64
65static inline int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
66{
67 return 0;
68}
69
70static inline void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) {}
71
63static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {} 72static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
64static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {} 73static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {}
65 74
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 2b0e45133e9d..5e610f7de5aa 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -25,6 +25,17 @@ config ADIS16480
25 Say yes here to build support for Analog Devices ADIS16375, ADIS16480, 25 Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
26 ADIS16485, ADIS16488 inertial sensors. 26 ADIS16485, ADIS16488 inertial sensors.
27 27
28config KMX61
29 tristate "Kionix KMX61 6-axis accelerometer and magnetometer"
30 depends on I2C
31 select IIO_BUFFER
32 select IIO_TRIGGERED_BUFFER
33 help
34 Say Y here if you want to build a driver for Kionix KMX61 6-axis
35 accelerometer and magnetometer.
36 To compile this driver as module, choose M here: the module will
37 be called kmx61.
38
28source "drivers/iio/imu/inv_mpu6050/Kconfig" 39source "drivers/iio/imu/inv_mpu6050/Kconfig"
29 40
30endmenu 41endmenu
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index 114d2c17cbe2..e1e6e3d70e26 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -14,3 +14,5 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
14obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o 14obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
15 15
16obj-y += inv_mpu6050/ 16obj-y += inv_mpu6050/
17
18obj-$(CONFIG_KMX61) += kmx61.o
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index 2d0608ba88d7..48fbc0bc7e2a 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -7,6 +7,7 @@ config INV_MPU6050_IIO
7 depends on I2C && SYSFS 7 depends on I2C && SYSFS
8 select IIO_BUFFER 8 select IIO_BUFFER
9 select IIO_TRIGGERED_BUFFER 9 select IIO_TRIGGERED_BUFFER
10 select I2C_MUX
10 help 11 help
11 This driver supports the Invensense MPU6050 devices. 12 This driver supports the Invensense MPU6050 devices.
12 This driver can also support MPU6500 in MPU6050 compatibility mode 13 This driver can also support MPU6500 in MPU6050 compatibility mode
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index b75519deac1a..f73e60b7a796 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -23,6 +23,8 @@
23#include <linux/kfifo.h> 23#include <linux/kfifo.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/iio/iio.h> 25#include <linux/iio/iio.h>
26#include <linux/i2c-mux.h>
27#include <linux/acpi.h>
26#include "inv_mpu_iio.h" 28#include "inv_mpu_iio.h"
27 29
28/* 30/*
@@ -52,6 +54,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = {
52 .int_enable = INV_MPU6050_REG_INT_ENABLE, 54 .int_enable = INV_MPU6050_REG_INT_ENABLE,
53 .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, 55 .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
54 .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, 56 .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
57 .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG,
55}; 58};
56 59
57static const struct inv_mpu6050_chip_config chip_config_6050 = { 60static const struct inv_mpu6050_chip_config chip_config_6050 = {
@@ -77,6 +80,83 @@ int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d)
77 return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d); 80 return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d);
78} 81}
79 82
83/*
84 * The i2c read/write needs to happen in unlocked mode. As the parent
85 * adapter is common. If we use locked versions, it will fail as
86 * the mux adapter will lock the parent i2c adapter, while calling
87 * select/deselect functions.
88 */
89static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st,
90 u8 reg, u8 d)
91{
92 int ret;
93 u8 buf[2];
94 struct i2c_msg msg[1] = {
95 {
96 .addr = st->client->addr,
97 .flags = 0,
98 .len = sizeof(buf),
99 .buf = buf,
100 }
101 };
102
103 buf[0] = reg;
104 buf[1] = d;
105 ret = __i2c_transfer(st->client->adapter, msg, 1);
106 if (ret != 1)
107 return ret;
108
109 return 0;
110}
111
112static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv,
113 u32 chan_id)
114{
115 struct iio_dev *indio_dev = mux_priv;
116 struct inv_mpu6050_state *st = iio_priv(indio_dev);
117 int ret = 0;
118
119 /* Use the same mutex which was used everywhere to protect power-op */
120 mutex_lock(&indio_dev->mlock);
121 if (!st->powerup_count) {
122 ret = inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
123 0);
124 if (ret)
125 goto write_error;
126
127 msleep(INV_MPU6050_REG_UP_TIME);
128 }
129 if (!ret) {
130 st->powerup_count++;
131 ret = inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
132 st->client->irq |
133 INV_MPU6050_BIT_BYPASS_EN);
134 }
135write_error:
136 mutex_unlock(&indio_dev->mlock);
137
138 return ret;
139}
140
141static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
142 void *mux_priv, u32 chan_id)
143{
144 struct iio_dev *indio_dev = mux_priv;
145 struct inv_mpu6050_state *st = iio_priv(indio_dev);
146
147 mutex_lock(&indio_dev->mlock);
148 /* It doesn't really mattter, if any of the calls fails */
149 inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
150 st->client->irq);
151 st->powerup_count--;
152 if (!st->powerup_count)
153 inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
154 INV_MPU6050_BIT_SLEEP);
155 mutex_unlock(&indio_dev->mlock);
156
157 return 0;
158}
159
80int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask) 160int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
81{ 161{
82 u8 d, mgmt_1; 162 u8 d, mgmt_1;
@@ -133,13 +213,22 @@ int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
133 213
134int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on) 214int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
135{ 215{
136 int result; 216 int result = 0;
217
218 if (power_on) {
219 /* Already under indio-dev->mlock mutex */
220 if (!st->powerup_count)
221 result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
222 0);
223 if (!result)
224 st->powerup_count++;
225 } else {
226 st->powerup_count--;
227 if (!st->powerup_count)
228 result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
229 INV_MPU6050_BIT_SLEEP);
230 }
137 231
138 if (power_on)
139 result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, 0);
140 else
141 result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
142 INV_MPU6050_BIT_SLEEP);
143 if (result) 232 if (result)
144 return result; 233 return result;
145 234
@@ -673,6 +762,7 @@ static int inv_mpu_probe(struct i2c_client *client,
673 762
674 st = iio_priv(indio_dev); 763 st = iio_priv(indio_dev);
675 st->client = client; 764 st->client = client;
765 st->powerup_count = 0;
676 pdata = dev_get_platdata(&client->dev); 766 pdata = dev_get_platdata(&client->dev);
677 if (pdata) 767 if (pdata)
678 st->plat_data = *pdata; 768 st->plat_data = *pdata;
@@ -720,8 +810,21 @@ static int inv_mpu_probe(struct i2c_client *client,
720 goto out_remove_trigger; 810 goto out_remove_trigger;
721 } 811 }
722 812
813 st->mux_adapter = i2c_add_mux_adapter(client->adapter,
814 &client->dev,
815 indio_dev,
816 0, 0, 0,
817 inv_mpu6050_select_bypass,
818 inv_mpu6050_deselect_bypass);
819 if (!st->mux_adapter) {
820 result = -ENODEV;
821 goto out_unreg_device;
822 }
823
723 return 0; 824 return 0;
724 825
826out_unreg_device:
827 iio_device_unregister(indio_dev);
725out_remove_trigger: 828out_remove_trigger:
726 inv_mpu6050_remove_trigger(st); 829 inv_mpu6050_remove_trigger(st);
727out_unreg_ring: 830out_unreg_ring:
@@ -734,6 +837,7 @@ static int inv_mpu_remove(struct i2c_client *client)
734 struct iio_dev *indio_dev = i2c_get_clientdata(client); 837 struct iio_dev *indio_dev = i2c_get_clientdata(client);
735 struct inv_mpu6050_state *st = iio_priv(indio_dev); 838 struct inv_mpu6050_state *st = iio_priv(indio_dev);
736 839
840 i2c_del_mux_adapter(st->mux_adapter);
737 iio_device_unregister(indio_dev); 841 iio_device_unregister(indio_dev);
738 inv_mpu6050_remove_trigger(st); 842 inv_mpu6050_remove_trigger(st);
739 iio_triggered_buffer_cleanup(indio_dev); 843 iio_triggered_buffer_cleanup(indio_dev);
@@ -772,6 +876,13 @@ static const struct i2c_device_id inv_mpu_id[] = {
772 876
773MODULE_DEVICE_TABLE(i2c, inv_mpu_id); 877MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
774 878
879static const struct acpi_device_id inv_acpi_match[] = {
880 {"INVN6500", 0},
881 { },
882};
883
884MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
885
775static struct i2c_driver inv_mpu_driver = { 886static struct i2c_driver inv_mpu_driver = {
776 .probe = inv_mpu_probe, 887 .probe = inv_mpu_probe,
777 .remove = inv_mpu_remove, 888 .remove = inv_mpu_remove,
@@ -780,6 +891,7 @@ static struct i2c_driver inv_mpu_driver = {
780 .owner = THIS_MODULE, 891 .owner = THIS_MODULE,
781 .name = "inv-mpu6050", 892 .name = "inv-mpu6050",
782 .pm = INV_MPU6050_PMOPS, 893 .pm = INV_MPU6050_PMOPS,
894 .acpi_match_table = ACPI_PTR(inv_acpi_match),
783 }, 895 },
784}; 896};
785 897
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index e7799315d4dc..aa837de57079 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -54,6 +54,7 @@ struct inv_mpu6050_reg_map {
54 u8 int_enable; 54 u8 int_enable;
55 u8 pwr_mgmt_1; 55 u8 pwr_mgmt_1;
56 u8 pwr_mgmt_2; 56 u8 pwr_mgmt_2;
57 u8 int_pin_cfg;
57}; 58};
58 59
59/*device enum */ 60/*device enum */
@@ -119,6 +120,8 @@ struct inv_mpu6050_state {
119 enum inv_devices chip_type; 120 enum inv_devices chip_type;
120 spinlock_t time_stamp_lock; 121 spinlock_t time_stamp_lock;
121 struct i2c_client *client; 122 struct i2c_client *client;
123 struct i2c_adapter *mux_adapter;
124 unsigned int powerup_count;
122 struct inv_mpu6050_platform_data plat_data; 125 struct inv_mpu6050_platform_data plat_data;
123 DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE); 126 DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
124}; 127};
@@ -179,6 +182,9 @@ struct inv_mpu6050_state {
179/* 6 + 6 round up and plus 8 */ 182/* 6 + 6 round up and plus 8 */
180#define INV_MPU6050_OUTPUT_DATA_SIZE 24 183#define INV_MPU6050_OUTPUT_DATA_SIZE 24
181 184
185#define INV_MPU6050_REG_INT_PIN_CFG 0x37
186#define INV_MPU6050_BIT_BYPASS_EN 0x2
187
182/* init parameters */ 188/* init parameters */
183#define INV_MPU6050_INIT_FIFO_RATE 50 189#define INV_MPU6050_INIT_FIFO_RATE 50
184#define INV_MPU6050_TIME_STAMP_TOR 5 190#define INV_MPU6050_TIME_STAMP_TOR 5
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index 926fccea8de0..844610c3a3a9 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -116,40 +116,35 @@ int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
116 int ret; 116 int ret;
117 struct inv_mpu6050_state *st = iio_priv(indio_dev); 117 struct inv_mpu6050_state *st = iio_priv(indio_dev);
118 118
119 st->trig = iio_trigger_alloc("%s-dev%d", 119 st->trig = devm_iio_trigger_alloc(&indio_dev->dev,
120 indio_dev->name, 120 "%s-dev%d",
121 indio_dev->id); 121 indio_dev->name,
122 if (st->trig == NULL) { 122 indio_dev->id);
123 ret = -ENOMEM; 123 if (!st->trig)
124 goto error_ret; 124 return -ENOMEM;
125 } 125
126 ret = request_irq(st->client->irq, &iio_trigger_generic_data_rdy_poll, 126 ret = devm_request_irq(&indio_dev->dev, st->client->irq,
127 IRQF_TRIGGER_RISING, 127 &iio_trigger_generic_data_rdy_poll,
128 "inv_mpu", 128 IRQF_TRIGGER_RISING,
129 st->trig); 129 "inv_mpu",
130 st->trig);
130 if (ret) 131 if (ret)
131 goto error_free_trig; 132 return ret;
133
132 st->trig->dev.parent = &st->client->dev; 134 st->trig->dev.parent = &st->client->dev;
133 st->trig->ops = &inv_mpu_trigger_ops; 135 st->trig->ops = &inv_mpu_trigger_ops;
134 iio_trigger_set_drvdata(st->trig, indio_dev); 136 iio_trigger_set_drvdata(st->trig, indio_dev);
137
135 ret = iio_trigger_register(st->trig); 138 ret = iio_trigger_register(st->trig);
136 if (ret) 139 if (ret)
137 goto error_free_irq; 140 return ret;
141
138 indio_dev->trig = iio_trigger_get(st->trig); 142 indio_dev->trig = iio_trigger_get(st->trig);
139 143
140 return 0; 144 return 0;
141
142error_free_irq:
143 free_irq(st->client->irq, st->trig);
144error_free_trig:
145 iio_trigger_free(st->trig);
146error_ret:
147 return ret;
148} 145}
149 146
150void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st) 147void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st)
151{ 148{
152 iio_trigger_unregister(st->trig); 149 iio_trigger_unregister(st->trig);
153 free_irq(st->client->irq, st->trig);
154 iio_trigger_free(st->trig);
155} 150}
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
new file mode 100644
index 000000000000..5cc3692acf37
--- /dev/null
+++ b/drivers/iio/imu/kmx61.c
@@ -0,0 +1,1595 @@
1/*
2 * KMX61 - Kionix 6-axis Accelerometer/Magnetometer
3 *
4 * Copyright (c) 2014, Intel Corporation.
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F).
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/acpi.h>
17#include <linux/gpio/consumer.h>
18#include <linux/interrupt.h>
19#include <linux/pm.h>
20#include <linux/pm_runtime.h>
21#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h>
23#include <linux/iio/events.h>
24#include <linux/iio/trigger.h>
25#include <linux/iio/buffer.h>
26#include <linux/iio/triggered_buffer.h>
27#include <linux/iio/trigger_consumer.h>
28
29#define KMX61_DRV_NAME "kmx61"
30#define KMX61_GPIO_NAME "kmx61_int"
31#define KMX61_IRQ_NAME "kmx61_event"
32
33#define KMX61_REG_WHO_AM_I 0x00
34#define KMX61_REG_INS1 0x01
35#define KMX61_REG_INS2 0x02
36
37/*
38 * three 16-bit accelerometer output registers for X/Y/Z axis
39 * we use only XOUT_L as a base register, all other addresses
40 * can be obtained by applying an offset and are provided here
41 * only for clarity.
42 */
43#define KMX61_ACC_XOUT_L 0x0A
44#define KMX61_ACC_XOUT_H 0x0B
45#define KMX61_ACC_YOUT_L 0x0C
46#define KMX61_ACC_YOUT_H 0x0D
47#define KMX61_ACC_ZOUT_L 0x0E
48#define KMX61_ACC_ZOUT_H 0x0F
49
50/*
51 * one 16-bit temperature output register
52 */
53#define KMX61_TEMP_L 0x10
54#define KMX61_TEMP_H 0x11
55
56/*
57 * three 16-bit magnetometer output registers for X/Y/Z axis
58 */
59#define KMX61_MAG_XOUT_L 0x12
60#define KMX61_MAG_XOUT_H 0x13
61#define KMX61_MAG_YOUT_L 0x14
62#define KMX61_MAG_YOUT_H 0x15
63#define KMX61_MAG_ZOUT_L 0x16
64#define KMX61_MAG_ZOUT_H 0x17
65
66#define KMX61_REG_INL 0x28
67#define KMX61_REG_STBY 0x29
68#define KMX61_REG_CTRL1 0x2A
69#define KMX61_REG_CTRL2 0x2B
70#define KMX61_REG_ODCNTL 0x2C
71#define KMX61_REG_INC1 0x2D
72
73#define KMX61_REG_WUF_THRESH 0x3D
74#define KMX61_REG_WUF_TIMER 0x3E
75
76#define KMX61_ACC_STBY_BIT BIT(0)
77#define KMX61_MAG_STBY_BIT BIT(1)
78#define KMX61_ACT_STBY_BIT BIT(7)
79
80#define KMX61_ALL_STBY (KMX61_ACC_STBY_BIT | KMX61_MAG_STBY_BIT)
81
82#define KMX61_REG_INS1_BIT_WUFS BIT(1)
83
84#define KMX61_REG_INS2_BIT_ZP BIT(0)
85#define KMX61_REG_INS2_BIT_ZN BIT(1)
86#define KMX61_REG_INS2_BIT_YP BIT(2)
87#define KMX61_REG_INS2_BIT_YN BIT(3)
88#define KMX61_REG_INS2_BIT_XP BIT(4)
89#define KMX61_REG_INS2_BIT_XN BIT(5)
90
91#define KMX61_REG_CTRL1_GSEL_MASK 0x03
92
93#define KMX61_REG_CTRL1_BIT_RES BIT(4)
94#define KMX61_REG_CTRL1_BIT_DRDYE BIT(5)
95#define KMX61_REG_CTRL1_BIT_WUFE BIT(6)
96#define KMX61_REG_CTRL1_BIT_BTSE BIT(7)
97
98#define KMX61_REG_INC1_BIT_WUFS BIT(0)
99#define KMX61_REG_INC1_BIT_DRDYM BIT(1)
100#define KMX61_REG_INC1_BIT_DRDYA BIT(2)
101#define KMX61_REG_INC1_BIT_IEN BIT(5)
102
103#define KMX61_ACC_ODR_SHIFT 0
104#define KMX61_MAG_ODR_SHIFT 4
105#define KMX61_ACC_ODR_MASK 0x0F
106#define KMX61_MAG_ODR_MASK 0xF0
107
108#define KMX61_OWUF_MASK 0x7
109
110#define KMX61_DEFAULT_WAKE_THRESH 1
111#define KMX61_DEFAULT_WAKE_DURATION 1
112
113#define KMX61_SLEEP_DELAY_MS 2000
114
115#define KMX61_CHIP_ID 0x12
116
117/* KMX61 devices */
118#define KMX61_ACC 0x01
119#define KMX61_MAG 0x02
120
121struct kmx61_data {
122 struct i2c_client *client;
123
124 /* serialize access to non-atomic ops, e.g set_mode */
125 struct mutex lock;
126
127 /* standby state */
128 bool acc_stby;
129 bool mag_stby;
130
131 /* power state */
132 bool acc_ps;
133 bool mag_ps;
134
135 /* config bits */
136 u8 range;
137 u8 odr_bits;
138 u8 wake_thresh;
139 u8 wake_duration;
140
141 /* accelerometer specific data */
142 struct iio_dev *acc_indio_dev;
143 struct iio_trigger *acc_dready_trig;
144 struct iio_trigger *motion_trig;
145 bool acc_dready_trig_on;
146 bool motion_trig_on;
147 bool ev_enable_state;
148
149 /* magnetometer specific data */
150 struct iio_dev *mag_indio_dev;
151 struct iio_trigger *mag_dready_trig;
152 bool mag_dready_trig_on;
153};
154
155enum kmx61_range {
156 KMX61_RANGE_2G,
157 KMX61_RANGE_4G,
158 KMX61_RANGE_8G,
159};
160
161enum kmx61_axis {
162 KMX61_AXIS_X,
163 KMX61_AXIS_Y,
164 KMX61_AXIS_Z,
165};
166
167static const u16 kmx61_uscale_table[] = {9582, 19163, 38326};
168
169static const struct {
170 int val;
171 int val2;
172 u8 odr_bits;
173} kmx61_samp_freq_table[] = { {12, 500000, 0x00},
174 {25, 0, 0x01},
175 {50, 0, 0x02},
176 {100, 0, 0x03},
177 {200, 0, 0x04},
178 {400, 0, 0x05},
179 {800, 0, 0x06},
180 {1600, 0, 0x07},
181 {0, 781000, 0x08},
182 {1, 563000, 0x09},
183 {3, 125000, 0x0A},
184 {6, 250000, 0x0B} };
185
186static const struct {
187 int val;
188 int val2;
189 int odr_bits;
190} kmx61_wake_up_odr_table[] = { {0, 781000, 0x00},
191 {1, 563000, 0x01},
192 {3, 125000, 0x02},
193 {6, 250000, 0x03},
194 {12, 500000, 0x04},
195 {25, 0, 0x05},
196 {50, 0, 0x06},
197 {100, 0, 0x06},
198 {200, 0, 0x06},
199 {400, 0, 0x06},
200 {800, 0, 0x06},
201 {1600, 0, 0x06} };
202
203static IIO_CONST_ATTR(accel_scale_available, "0.009582 0.019163 0.038326");
204static IIO_CONST_ATTR(magn_scale_available, "0.001465");
205static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
206 "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800");
207
208static struct attribute *kmx61_acc_attributes[] = {
209 &iio_const_attr_accel_scale_available.dev_attr.attr,
210 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
211 NULL,
212};
213
214static struct attribute *kmx61_mag_attributes[] = {
215 &iio_const_attr_magn_scale_available.dev_attr.attr,
216 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
217 NULL,
218};
219
220static const struct attribute_group kmx61_acc_attribute_group = {
221 .attrs = kmx61_acc_attributes,
222};
223
224static const struct attribute_group kmx61_mag_attribute_group = {
225 .attrs = kmx61_mag_attributes,
226};
227
228static const struct iio_event_spec kmx61_event = {
229 .type = IIO_EV_TYPE_THRESH,
230 .dir = IIO_EV_DIR_EITHER,
231 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
232 BIT(IIO_EV_INFO_ENABLE) |
233 BIT(IIO_EV_INFO_PERIOD),
234};
235
236#define KMX61_ACC_CHAN(_axis) { \
237 .type = IIO_ACCEL, \
238 .modified = 1, \
239 .channel2 = IIO_MOD_ ## _axis, \
240 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
241 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
242 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
243 .address = KMX61_ACC, \
244 .scan_index = KMX61_AXIS_ ## _axis, \
245 .scan_type = { \
246 .sign = 's', \
247 .realbits = 12, \
248 .storagebits = 16, \
249 .shift = 4, \
250 .endianness = IIO_LE, \
251 }, \
252 .event_spec = &kmx61_event, \
253 .num_event_specs = 1 \
254}
255
256#define KMX61_MAG_CHAN(_axis) { \
257 .type = IIO_MAGN, \
258 .modified = 1, \
259 .channel2 = IIO_MOD_ ## _axis, \
260 .address = KMX61_MAG, \
261 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
262 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
263 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
264 .scan_index = KMX61_AXIS_ ## _axis, \
265 .scan_type = { \
266 .sign = 's', \
267 .realbits = 14, \
268 .storagebits = 16, \
269 .shift = 2, \
270 .endianness = IIO_LE, \
271 }, \
272}
273
274static const struct iio_chan_spec kmx61_acc_channels[] = {
275 KMX61_ACC_CHAN(X),
276 KMX61_ACC_CHAN(Y),
277 KMX61_ACC_CHAN(Z),
278};
279
280static const struct iio_chan_spec kmx61_mag_channels[] = {
281 KMX61_MAG_CHAN(X),
282 KMX61_MAG_CHAN(Y),
283 KMX61_MAG_CHAN(Z),
284};
285
286static void kmx61_set_data(struct iio_dev *indio_dev, struct kmx61_data *data)
287{
288 struct kmx61_data **priv = iio_priv(indio_dev);
289
290 *priv = data;
291}
292
293static struct kmx61_data *kmx61_get_data(struct iio_dev *indio_dev)
294{
295 return *(struct kmx61_data **)iio_priv(indio_dev);
296}
297
298static int kmx61_convert_freq_to_bit(int val, int val2)
299{
300 int i;
301
302 for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
303 if (val == kmx61_samp_freq_table[i].val &&
304 val2 == kmx61_samp_freq_table[i].val2)
305 return kmx61_samp_freq_table[i].odr_bits;
306 return -EINVAL;
307}
308
309static int kmx61_convert_bit_to_freq(u8 odr_bits, int *val, int *val2)
310{
311 int i;
312
313 for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
314 if (odr_bits == kmx61_samp_freq_table[i].odr_bits) {
315 *val = kmx61_samp_freq_table[i].val;
316 *val2 = kmx61_samp_freq_table[i].val2;
317 return 0;
318 }
319 return -EINVAL;
320}
321
322
323static int kmx61_convert_wake_up_odr_to_bit(int val, int val2)
324{
325 int i;
326
327 for (i = 0; i < ARRAY_SIZE(kmx61_wake_up_odr_table); ++i)
328 if (kmx61_wake_up_odr_table[i].val == val &&
329 kmx61_wake_up_odr_table[i].val2 == val2)
330 return kmx61_wake_up_odr_table[i].odr_bits;
331 return -EINVAL;
332}
333
334/**
335 * kmx61_set_mode() - set KMX61 device operating mode
336 * @data - kmx61 device private data pointer
337 * @mode - bitmask, indicating operating mode for @device
338 * @device - bitmask, indicating device for which @mode needs to be set
339 * @update - update stby bits stored in device's private @data
340 *
341 * For each sensor (accelerometer/magnetometer) there are two operating modes
342 * STANDBY and OPERATION. Neither accel nor magn can be disabled independently
343 * if they are both enabled. Internal sensors state is saved in acc_stby and
344 * mag_stby members of driver's private @data.
345 */
346static int kmx61_set_mode(struct kmx61_data *data, u8 mode, u8 device,
347 bool update)
348{
349 int ret;
350 int acc_stby = -1, mag_stby = -1;
351
352 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
353 if (ret < 0) {
354 dev_err(&data->client->dev, "Error reading reg_stby\n");
355 return ret;
356 }
357 if (device & KMX61_ACC) {
358 if (mode & KMX61_ACC_STBY_BIT) {
359 ret |= KMX61_ACC_STBY_BIT;
360 acc_stby = 1;
361 } else {
362 ret &= ~KMX61_ACC_STBY_BIT;
363 acc_stby = 0;
364 }
365 }
366
367 if (device & KMX61_MAG) {
368 if (mode & KMX61_MAG_STBY_BIT) {
369 ret |= KMX61_MAG_STBY_BIT;
370 mag_stby = 1;
371 } else {
372 ret &= ~KMX61_MAG_STBY_BIT;
373 mag_stby = 0;
374 }
375 }
376
377 if (mode & KMX61_ACT_STBY_BIT)
378 ret |= KMX61_ACT_STBY_BIT;
379
380 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_STBY, ret);
381 if (ret < 0) {
382 dev_err(&data->client->dev, "Error writing reg_stby\n");
383 return ret;
384 }
385
386 if (acc_stby != -1 && update)
387 data->acc_stby = acc_stby;
388 if (mag_stby != -1 && update)
389 data->mag_stby = mag_stby;
390
391 return 0;
392}
393
394static int kmx61_get_mode(struct kmx61_data *data, u8 *mode, u8 device)
395{
396 int ret;
397
398 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
399 if (ret < 0) {
400 dev_err(&data->client->dev, "Error reading reg_stby\n");
401 return ret;
402 }
403 *mode = 0;
404
405 if (device & KMX61_ACC) {
406 if (ret & KMX61_ACC_STBY_BIT)
407 *mode |= KMX61_ACC_STBY_BIT;
408 else
409 *mode &= ~KMX61_ACC_STBY_BIT;
410 }
411
412 if (device & KMX61_MAG) {
413 if (ret & KMX61_MAG_STBY_BIT)
414 *mode |= KMX61_MAG_STBY_BIT;
415 else
416 *mode &= ~KMX61_MAG_STBY_BIT;
417 }
418
419 return 0;
420}
421
422static int kmx61_set_wake_up_odr(struct kmx61_data *data, int val, int val2)
423{
424 int ret, odr_bits;
425
426 odr_bits = kmx61_convert_wake_up_odr_to_bit(val, val2);
427 if (odr_bits < 0)
428 return odr_bits;
429
430 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL2,
431 odr_bits);
432 if (ret < 0)
433 dev_err(&data->client->dev, "Error writing reg_ctrl2\n");
434 return ret;
435}
436
437static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device)
438{
439 int ret;
440 u8 mode;
441 int lodr_bits, odr_bits;
442
443 ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
444 if (ret < 0)
445 return ret;
446
447 lodr_bits = kmx61_convert_freq_to_bit(val, val2);
448 if (lodr_bits < 0)
449 return lodr_bits;
450
451 /* To change ODR, accel and magn must be in STDBY */
452 ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
453 true);
454 if (ret < 0)
455 return ret;
456
457 odr_bits = 0;
458 if (device & KMX61_ACC)
459 odr_bits |= lodr_bits << KMX61_ACC_ODR_SHIFT;
460 if (device & KMX61_MAG)
461 odr_bits |= lodr_bits << KMX61_MAG_ODR_SHIFT;
462
463 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_ODCNTL,
464 odr_bits);
465 if (ret < 0)
466 return ret;
467
468 data->odr_bits = odr_bits;
469
470 if (device & KMX61_ACC) {
471 ret = kmx61_set_wake_up_odr(data, val, val2);
472 if (ret)
473 return ret;
474 }
475
476 return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
477}
478
479static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2,
480 u8 device)
481{ int i;
482 u8 lodr_bits;
483
484 if (device & KMX61_ACC)
485 lodr_bits = (data->odr_bits >> KMX61_ACC_ODR_SHIFT) &
486 KMX61_ACC_ODR_MASK;
487 else if (device & KMX61_MAG)
488 lodr_bits = (data->odr_bits >> KMX61_MAG_ODR_SHIFT) &
489 KMX61_MAG_ODR_MASK;
490 else
491 return -EINVAL;
492
493 for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
494 if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) {
495 *val = kmx61_samp_freq_table[i].val;
496 *val2 = kmx61_samp_freq_table[i].val2;
497 return 0;
498 }
499 return -EINVAL;
500}
501
502static int kmx61_set_range(struct kmx61_data *data, u8 range)
503{
504 int ret;
505
506 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
507 if (ret < 0) {
508 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
509 return ret;
510 }
511
512 ret &= ~KMX61_REG_CTRL1_GSEL_MASK;
513 ret |= range & KMX61_REG_CTRL1_GSEL_MASK;
514
515 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
516 if (ret < 0) {
517 dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
518 return ret;
519 }
520
521 data->range = range;
522
523 return 0;
524}
525
526static int kmx61_set_scale(struct kmx61_data *data, u16 uscale)
527{
528 int ret, i;
529 u8 mode;
530
531 for (i = 0; i < ARRAY_SIZE(kmx61_uscale_table); i++) {
532 if (kmx61_uscale_table[i] == uscale) {
533 ret = kmx61_get_mode(data, &mode,
534 KMX61_ACC | KMX61_MAG);
535 if (ret < 0)
536 return ret;
537
538 ret = kmx61_set_mode(data, KMX61_ALL_STBY,
539 KMX61_ACC | KMX61_MAG, true);
540 if (ret < 0)
541 return ret;
542
543 ret = kmx61_set_range(data, i);
544 if (ret < 0)
545 return ret;
546
547 return kmx61_set_mode(data, mode,
548 KMX61_ACC | KMX61_MAG, true);
549 }
550 }
551 return -EINVAL;
552}
553
554static int kmx61_chip_init(struct kmx61_data *data)
555{
556 int ret, val, val2;
557
558 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_WHO_AM_I);
559 if (ret < 0) {
560 dev_err(&data->client->dev, "Error reading who_am_i\n");
561 return ret;
562 }
563
564 if (ret != KMX61_CHIP_ID) {
565 dev_err(&data->client->dev,
566 "Wrong chip id, got %x expected %x\n",
567 ret, KMX61_CHIP_ID);
568 return -EINVAL;
569 }
570
571 /* set accel 12bit, 4g range */
572 ret = kmx61_set_range(data, KMX61_RANGE_4G);
573 if (ret < 0)
574 return ret;
575
576 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_ODCNTL);
577 if (ret < 0) {
578 dev_err(&data->client->dev, "Error reading reg_odcntl\n");
579 return ret;
580 }
581 data->odr_bits = ret;
582
583 /* set output data rate for wake up (motion detection) function */
584 ret = kmx61_convert_bit_to_freq(data->odr_bits, &val, &val2);
585 if (ret < 0)
586 return ret;
587
588 ret = kmx61_set_wake_up_odr(data, val, val2);
589 if (ret < 0)
590 return ret;
591
592 /* set acc/magn to OPERATION mode */
593 ret = kmx61_set_mode(data, 0, KMX61_ACC | KMX61_MAG, true);
594 if (ret < 0)
595 return ret;
596
597 data->wake_thresh = KMX61_DEFAULT_WAKE_THRESH;
598 data->wake_duration = KMX61_DEFAULT_WAKE_DURATION;
599
600 return 0;
601}
602
603static int kmx61_setup_new_data_interrupt(struct kmx61_data *data,
604 bool status, u8 device)
605{
606 u8 mode;
607 int ret;
608
609 ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
610 if (ret < 0)
611 return ret;
612
613 ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
614 if (ret < 0)
615 return ret;
616
617 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INC1);
618 if (ret < 0) {
619 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
620 return ret;
621 }
622
623 if (status) {
624 ret |= KMX61_REG_INC1_BIT_IEN;
625 if (device & KMX61_ACC)
626 ret |= KMX61_REG_INC1_BIT_DRDYA;
627 if (device & KMX61_MAG)
628 ret |= KMX61_REG_INC1_BIT_DRDYM;
629 } else {
630 ret &= ~KMX61_REG_INC1_BIT_IEN;
631 if (device & KMX61_ACC)
632 ret &= ~KMX61_REG_INC1_BIT_DRDYA;
633 if (device & KMX61_MAG)
634 ret &= ~KMX61_REG_INC1_BIT_DRDYM;
635 }
636 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_INC1, ret);
637 if (ret < 0) {
638 dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
639 return ret;
640 }
641
642 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
643 if (ret < 0) {
644 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
645 return ret;
646 }
647
648 if (status)
649 ret |= KMX61_REG_CTRL1_BIT_DRDYE;
650 else
651 ret &= ~KMX61_REG_CTRL1_BIT_DRDYE;
652
653 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
654 if (ret < 0) {
655 dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
656 return ret;
657 }
658
659 return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
660}
661
662static int kmx61_chip_update_thresholds(struct kmx61_data *data)
663{
664 int ret;
665
666 ret = i2c_smbus_write_byte_data(data->client,
667 KMX61_REG_WUF_TIMER,
668 data->wake_duration);
669 if (ret < 0) {
670 dev_err(&data->client->dev, "Errow writing reg_wuf_timer\n");
671 return ret;
672 }
673
674 ret = i2c_smbus_write_byte_data(data->client,
675 KMX61_REG_WUF_THRESH,
676 data->wake_thresh);
677 if (ret < 0)
678 dev_err(&data->client->dev, "Error writing reg_wuf_thresh\n");
679
680 return ret;
681}
682
683static int kmx61_setup_any_motion_interrupt(struct kmx61_data *data,
684 bool status)
685{
686 u8 mode;
687 int ret;
688
689 ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
690 if (ret < 0)
691 return ret;
692
693 ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
694 if (ret < 0)
695 return ret;
696
697 ret = kmx61_chip_update_thresholds(data);
698 if (ret < 0)
699 return ret;
700
701 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INC1);
702 if (ret < 0) {
703 dev_err(&data->client->dev, "Error reading reg_inc1\n");
704 return ret;
705 }
706 if (status)
707 ret |= (KMX61_REG_INC1_BIT_IEN | KMX61_REG_INC1_BIT_WUFS);
708 else
709 ret &= ~(KMX61_REG_INC1_BIT_IEN | KMX61_REG_INC1_BIT_WUFS);
710
711 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_INC1, ret);
712 if (ret < 0) {
713 dev_err(&data->client->dev, "Error writing reg_inc1\n");
714 return ret;
715 }
716
717 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
718 if (ret < 0) {
719 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
720 return ret;
721 }
722
723 if (status)
724 ret |= KMX61_REG_CTRL1_BIT_WUFE | KMX61_REG_CTRL1_BIT_BTSE;
725 else
726 ret &= ~(KMX61_REG_CTRL1_BIT_WUFE | KMX61_REG_CTRL1_BIT_BTSE);
727
728 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
729 if (ret < 0) {
730 dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
731 return ret;
732 }
733 mode |= KMX61_ACT_STBY_BIT;
734 return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
735}
736
737/**
738 * kmx61_set_power_state() - set power state for kmx61 @device
739 * @data - kmx61 device private pointer
740 * @on - power state to be set for @device
741 * @device - bitmask indicating device for which @on state needs to be set
742 *
743 * Notice that when ACC power state needs to be set to ON and MAG is in
744 * OPERATION then we know that kmx61_runtime_resume was already called
745 * so we must set ACC OPERATION mode here. The same happens when MAG power
746 * state needs to be set to ON and ACC is in OPERATION.
747 */
748static int kmx61_set_power_state(struct kmx61_data *data, bool on, u8 device)
749{
750#ifdef CONFIG_PM
751 int ret;
752
753 if (device & KMX61_ACC) {
754 if (on && !data->acc_ps && !data->mag_stby) {
755 ret = kmx61_set_mode(data, 0, KMX61_ACC, true);
756 if (ret < 0)
757 return ret;
758 }
759 data->acc_ps = on;
760 }
761 if (device & KMX61_MAG) {
762 if (on && !data->mag_ps && !data->acc_stby) {
763 ret = kmx61_set_mode(data, 0, KMX61_MAG, true);
764 if (ret < 0)
765 return ret;
766 }
767 data->mag_ps = on;
768 }
769
770 if (on) {
771 ret = pm_runtime_get_sync(&data->client->dev);
772 } else {
773 pm_runtime_mark_last_busy(&data->client->dev);
774 ret = pm_runtime_put_autosuspend(&data->client->dev);
775 }
776 if (ret < 0) {
777 dev_err(&data->client->dev,
778 "Failed: kmx61_set_power_state for %d, ret %d\n",
779 on, ret);
780 if (on)
781 pm_runtime_put_noidle(&data->client->dev);
782
783 return ret;
784 }
785#endif
786 return 0;
787}
788
789static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset)
790{
791 int ret;
792 u8 reg = base + offset * 2;
793
794 ret = i2c_smbus_read_word_data(data->client, reg);
795 if (ret < 0)
796 dev_err(&data->client->dev, "failed to read reg at %x\n", reg);
797
798 return ret;
799}
800
801static int kmx61_read_raw(struct iio_dev *indio_dev,
802 struct iio_chan_spec const *chan, int *val,
803 int *val2, long mask)
804{
805 int ret;
806 u8 base_reg;
807 struct kmx61_data *data = kmx61_get_data(indio_dev);
808
809 switch (mask) {
810 case IIO_CHAN_INFO_RAW:
811 switch (chan->type) {
812 case IIO_ACCEL:
813 base_reg = KMX61_ACC_XOUT_L;
814 break;
815 case IIO_MAGN:
816 base_reg = KMX61_MAG_XOUT_L;
817 break;
818 default:
819 return -EINVAL;
820 }
821 mutex_lock(&data->lock);
822
823 ret = kmx61_set_power_state(data, true, chan->address);
824 if (ret) {
825 mutex_unlock(&data->lock);
826 return ret;
827 }
828
829 ret = kmx61_read_measurement(data, base_reg, chan->scan_index);
830 if (ret < 0) {
831 kmx61_set_power_state(data, false, chan->address);
832 mutex_unlock(&data->lock);
833 return ret;
834 }
835 *val = sign_extend32(ret >> chan->scan_type.shift,
836 chan->scan_type.realbits - 1);
837 ret = kmx61_set_power_state(data, false, chan->address);
838
839 mutex_unlock(&data->lock);
840 if (ret)
841 return ret;
842 return IIO_VAL_INT;
843 case IIO_CHAN_INFO_SCALE:
844 switch (chan->type) {
845 case IIO_ACCEL:
846 *val = 0;
847 *val2 = kmx61_uscale_table[data->range];
848 return IIO_VAL_INT_PLUS_MICRO;
849 case IIO_MAGN:
850 /* 14 bits res, 1465 microGauss per magn count */
851 *val = 0;
852 *val2 = 1465;
853 return IIO_VAL_INT_PLUS_MICRO;
854 default:
855 return -EINVAL;
856 }
857 case IIO_CHAN_INFO_SAMP_FREQ:
858 if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
859 return -EINVAL;
860
861 mutex_lock(&data->lock);
862 ret = kmx61_get_odr(data, val, val2, chan->address);
863 mutex_unlock(&data->lock);
864 if (ret)
865 return -EINVAL;
866 return IIO_VAL_INT_PLUS_MICRO;
867 }
868 return -EINVAL;
869}
870
871static int kmx61_write_raw(struct iio_dev *indio_dev,
872 struct iio_chan_spec const *chan, int val,
873 int val2, long mask)
874{
875 int ret;
876 struct kmx61_data *data = kmx61_get_data(indio_dev);
877
878 switch (mask) {
879 case IIO_CHAN_INFO_SAMP_FREQ:
880 if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
881 return -EINVAL;
882
883 mutex_lock(&data->lock);
884 ret = kmx61_set_odr(data, val, val2, chan->address);
885 mutex_unlock(&data->lock);
886 return ret;
887 case IIO_CHAN_INFO_SCALE:
888 switch (chan->type) {
889 case IIO_ACCEL:
890 if (val != 0)
891 return -EINVAL;
892 mutex_lock(&data->lock);
893 ret = kmx61_set_scale(data, val2);
894 mutex_unlock(&data->lock);
895 return ret;
896 default:
897 return -EINVAL;
898 }
899 default:
900 return -EINVAL;
901 }
902}
903
904static int kmx61_read_event(struct iio_dev *indio_dev,
905 const struct iio_chan_spec *chan,
906 enum iio_event_type type,
907 enum iio_event_direction dir,
908 enum iio_event_info info,
909 int *val, int *val2)
910{
911 struct kmx61_data *data = kmx61_get_data(indio_dev);
912
913 *val2 = 0;
914 switch (info) {
915 case IIO_EV_INFO_VALUE:
916 *val = data->wake_thresh;
917 return IIO_VAL_INT;
918 case IIO_EV_INFO_PERIOD:
919 *val = data->wake_duration;
920 return IIO_VAL_INT;
921 default:
922 return -EINVAL;
923 }
924}
925
926static int kmx61_write_event(struct iio_dev *indio_dev,
927 const struct iio_chan_spec *chan,
928 enum iio_event_type type,
929 enum iio_event_direction dir,
930 enum iio_event_info info,
931 int val, int val2)
932{
933 struct kmx61_data *data = kmx61_get_data(indio_dev);
934
935 if (data->ev_enable_state)
936 return -EBUSY;
937
938 switch (info) {
939 case IIO_EV_INFO_VALUE:
940 data->wake_thresh = val;
941 return IIO_VAL_INT;
942 case IIO_EV_INFO_PERIOD:
943 data->wake_duration = val;
944 return IIO_VAL_INT;
945 default:
946 return -EINVAL;
947 }
948}
949
950static int kmx61_read_event_config(struct iio_dev *indio_dev,
951 const struct iio_chan_spec *chan,
952 enum iio_event_type type,
953 enum iio_event_direction dir)
954{
955 struct kmx61_data *data = kmx61_get_data(indio_dev);
956
957 return data->ev_enable_state;
958}
959
960static int kmx61_write_event_config(struct iio_dev *indio_dev,
961 const struct iio_chan_spec *chan,
962 enum iio_event_type type,
963 enum iio_event_direction dir,
964 int state)
965{
966 struct kmx61_data *data = kmx61_get_data(indio_dev);
967 int ret = 0;
968
969 if (state && data->ev_enable_state)
970 return 0;
971
972 mutex_lock(&data->lock);
973
974 if (!state && data->motion_trig_on) {
975 data->ev_enable_state = false;
976 goto err_unlock;
977 }
978
979 ret = kmx61_set_power_state(data, state, KMX61_ACC);
980 if (ret < 0)
981 goto err_unlock;
982
983 ret = kmx61_setup_any_motion_interrupt(data, state);
984 if (ret < 0) {
985 kmx61_set_power_state(data, false, KMX61_ACC);
986 goto err_unlock;
987 }
988
989 data->ev_enable_state = state;
990
991err_unlock:
992 mutex_unlock(&data->lock);
993
994 return ret;
995}
996
997static int kmx61_acc_validate_trigger(struct iio_dev *indio_dev,
998 struct iio_trigger *trig)
999{
1000 struct kmx61_data *data = kmx61_get_data(indio_dev);
1001
1002 if (data->acc_dready_trig != trig && data->motion_trig != trig)
1003 return -EINVAL;
1004
1005 return 0;
1006}
1007
1008static int kmx61_mag_validate_trigger(struct iio_dev *indio_dev,
1009 struct iio_trigger *trig)
1010{
1011 struct kmx61_data *data = kmx61_get_data(indio_dev);
1012
1013 if (data->mag_dready_trig != trig)
1014 return -EINVAL;
1015
1016 return 0;
1017}
1018
1019static const struct iio_info kmx61_acc_info = {
1020 .driver_module = THIS_MODULE,
1021 .read_raw = kmx61_read_raw,
1022 .write_raw = kmx61_write_raw,
1023 .attrs = &kmx61_acc_attribute_group,
1024 .read_event_value = kmx61_read_event,
1025 .write_event_value = kmx61_write_event,
1026 .read_event_config = kmx61_read_event_config,
1027 .write_event_config = kmx61_write_event_config,
1028 .validate_trigger = kmx61_acc_validate_trigger,
1029};
1030
1031static const struct iio_info kmx61_mag_info = {
1032 .driver_module = THIS_MODULE,
1033 .read_raw = kmx61_read_raw,
1034 .write_raw = kmx61_write_raw,
1035 .attrs = &kmx61_mag_attribute_group,
1036 .validate_trigger = kmx61_mag_validate_trigger,
1037};
1038
1039
1040static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
1041 bool state)
1042{
1043 int ret = 0;
1044 u8 device;
1045
1046 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
1047 struct kmx61_data *data = kmx61_get_data(indio_dev);
1048
1049 mutex_lock(&data->lock);
1050
1051 if (!state && data->ev_enable_state && data->motion_trig_on) {
1052 data->motion_trig_on = false;
1053 goto err_unlock;
1054 }
1055
1056 if (data->acc_dready_trig == trig || data->motion_trig == trig)
1057 device = KMX61_ACC;
1058 else
1059 device = KMX61_MAG;
1060
1061 ret = kmx61_set_power_state(data, state, device);
1062 if (ret < 0)
1063 goto err_unlock;
1064
1065 if (data->acc_dready_trig == trig || data->mag_dready_trig == trig)
1066 ret = kmx61_setup_new_data_interrupt(data, state, device);
1067 else
1068 ret = kmx61_setup_any_motion_interrupt(data, state);
1069 if (ret < 0) {
1070 kmx61_set_power_state(data, false, device);
1071 goto err_unlock;
1072 }
1073
1074 if (data->acc_dready_trig == trig)
1075 data->acc_dready_trig_on = state;
1076 else if (data->mag_dready_trig == trig)
1077 data->mag_dready_trig_on = state;
1078 else
1079 data->motion_trig_on = state;
1080err_unlock:
1081 mutex_unlock(&data->lock);
1082
1083 return ret;
1084}
1085
1086static int kmx61_trig_try_reenable(struct iio_trigger *trig)
1087{
1088 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
1089 struct kmx61_data *data = kmx61_get_data(indio_dev);
1090 int ret;
1091
1092 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INL);
1093 if (ret < 0) {
1094 dev_err(&data->client->dev, "Error reading reg_inl\n");
1095 return ret;
1096 }
1097
1098 return 0;
1099}
1100
1101static const struct iio_trigger_ops kmx61_trigger_ops = {
1102 .set_trigger_state = kmx61_data_rdy_trigger_set_state,
1103 .try_reenable = kmx61_trig_try_reenable,
1104 .owner = THIS_MODULE,
1105};
1106
1107static irqreturn_t kmx61_event_handler(int irq, void *private)
1108{
1109 struct kmx61_data *data = private;
1110 struct iio_dev *indio_dev = data->acc_indio_dev;
1111 int ret;
1112
1113 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INS1);
1114 if (ret < 0) {
1115 dev_err(&data->client->dev, "Error reading reg_ins1\n");
1116 goto ack_intr;
1117 }
1118
1119 if (ret & KMX61_REG_INS1_BIT_WUFS) {
1120 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INS2);
1121 if (ret < 0) {
1122 dev_err(&data->client->dev, "Error reading reg_ins2\n");
1123 goto ack_intr;
1124 }
1125
1126 if (ret & KMX61_REG_INS2_BIT_XN)
1127 iio_push_event(indio_dev,
1128 IIO_MOD_EVENT_CODE(IIO_ACCEL,
1129 0,
1130 IIO_MOD_X,
1131 IIO_EV_TYPE_THRESH,
1132 IIO_EV_DIR_FALLING),
1133 0);
1134
1135 if (ret & KMX61_REG_INS2_BIT_XP)
1136 iio_push_event(indio_dev,
1137 IIO_MOD_EVENT_CODE(IIO_ACCEL,
1138 0,
1139 IIO_MOD_X,
1140 IIO_EV_TYPE_THRESH,
1141 IIO_EV_DIR_RISING),
1142 0);
1143
1144 if (ret & KMX61_REG_INS2_BIT_YN)
1145 iio_push_event(indio_dev,
1146 IIO_MOD_EVENT_CODE(IIO_ACCEL,
1147 0,
1148 IIO_MOD_Y,
1149 IIO_EV_TYPE_THRESH,
1150 IIO_EV_DIR_FALLING),
1151 0);
1152
1153 if (ret & KMX61_REG_INS2_BIT_YP)
1154 iio_push_event(indio_dev,
1155 IIO_MOD_EVENT_CODE(IIO_ACCEL,
1156 0,
1157 IIO_MOD_Y,
1158 IIO_EV_TYPE_THRESH,
1159 IIO_EV_DIR_RISING),
1160 0);
1161
1162 if (ret & KMX61_REG_INS2_BIT_ZN)
1163 iio_push_event(indio_dev,
1164 IIO_MOD_EVENT_CODE(IIO_ACCEL,
1165 0,
1166 IIO_MOD_Z,
1167 IIO_EV_TYPE_THRESH,
1168 IIO_EV_DIR_FALLING),
1169 0);
1170
1171 if (ret & KMX61_REG_INS2_BIT_ZP)
1172 iio_push_event(indio_dev,
1173 IIO_MOD_EVENT_CODE(IIO_ACCEL,
1174 0,
1175 IIO_MOD_Z,
1176 IIO_EV_TYPE_THRESH,
1177 IIO_EV_DIR_RISING),
1178 0);
1179 }
1180
1181ack_intr:
1182 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
1183 if (ret < 0)
1184 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
1185
1186 ret |= KMX61_REG_CTRL1_BIT_RES;
1187 ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
1188 if (ret < 0)
1189 dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
1190
1191 ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INL);
1192 if (ret < 0)
1193 dev_err(&data->client->dev, "Error reading reg_inl\n");
1194
1195 return IRQ_HANDLED;
1196}
1197
1198static irqreturn_t kmx61_data_rdy_trig_poll(int irq, void *private)
1199{
1200 struct kmx61_data *data = private;
1201
1202 if (data->acc_dready_trig_on)
1203 iio_trigger_poll(data->acc_dready_trig);
1204 if (data->mag_dready_trig_on)
1205 iio_trigger_poll(data->mag_dready_trig);
1206
1207 if (data->motion_trig_on)
1208 iio_trigger_poll(data->motion_trig);
1209
1210 if (data->ev_enable_state)
1211 return IRQ_WAKE_THREAD;
1212 return IRQ_HANDLED;
1213}
1214
1215static irqreturn_t kmx61_trigger_handler(int irq, void *p)
1216{
1217 struct iio_poll_func *pf = p;
1218 struct iio_dev *indio_dev = pf->indio_dev;
1219 struct kmx61_data *data = kmx61_get_data(indio_dev);
1220 int bit, ret, i = 0;
1221 u8 base;
1222 s16 buffer[8];
1223
1224 if (indio_dev == data->acc_indio_dev)
1225 base = KMX61_ACC_XOUT_L;
1226 else
1227 base = KMX61_MAG_XOUT_L;
1228
1229 mutex_lock(&data->lock);
1230 for_each_set_bit(bit, indio_dev->buffer->scan_mask,
1231 indio_dev->masklength) {
1232 ret = kmx61_read_measurement(data, base, bit);
1233 if (ret < 0) {
1234 mutex_unlock(&data->lock);
1235 goto err;
1236 }
1237 buffer[i++] = ret;
1238 }
1239 mutex_unlock(&data->lock);
1240
1241 iio_push_to_buffers(indio_dev, buffer);
1242err:
1243 iio_trigger_notify_done(indio_dev->trig);
1244
1245 return IRQ_HANDLED;
1246}
1247
1248static const char *kmx61_match_acpi_device(struct device *dev)
1249{
1250 const struct acpi_device_id *id;
1251
1252 id = acpi_match_device(dev->driver->acpi_match_table, dev);
1253 if (!id)
1254 return NULL;
1255 return dev_name(dev);
1256}
1257
1258static int kmx61_gpio_probe(struct i2c_client *client, struct kmx61_data *data)
1259{
1260 struct device *dev;
1261 struct gpio_desc *gpio;
1262 int ret;
1263
1264 if (!client)
1265 return -EINVAL;
1266
1267 dev = &client->dev;
1268
1269 /* data ready gpio interrupt pin */
1270 gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0);
1271 if (IS_ERR(gpio)) {
1272 dev_err(dev, "acpi gpio get index failed\n");
1273 return PTR_ERR(gpio);
1274 }
1275
1276 ret = gpiod_direction_input(gpio);
1277 if (ret)
1278 return ret;
1279
1280 ret = gpiod_to_irq(gpio);
1281
1282 dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
1283 return ret;
1284}
1285
1286static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data,
1287 const struct iio_info *info,
1288 const struct iio_chan_spec *chan,
1289 int num_channels,
1290 const char *name)
1291{
1292 struct iio_dev *indio_dev;
1293
1294 indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data));
1295 if (!indio_dev)
1296 return ERR_PTR(-ENOMEM);
1297
1298 kmx61_set_data(indio_dev, data);
1299
1300 indio_dev->dev.parent = &data->client->dev;
1301 indio_dev->channels = chan;
1302 indio_dev->num_channels = num_channels;
1303 indio_dev->name = name;
1304 indio_dev->modes = INDIO_DIRECT_MODE;
1305 indio_dev->info = info;
1306
1307 return indio_dev;
1308}
1309
1310static struct iio_trigger *kmx61_trigger_setup(struct kmx61_data *data,
1311 struct iio_dev *indio_dev,
1312 const char *tag)
1313{
1314 struct iio_trigger *trig;
1315 int ret;
1316
1317 trig = devm_iio_trigger_alloc(&data->client->dev,
1318 "%s-%s-dev%d",
1319 indio_dev->name,
1320 tag,
1321 indio_dev->id);
1322 if (!trig)
1323 return ERR_PTR(-ENOMEM);
1324
1325 trig->dev.parent = &data->client->dev;
1326 trig->ops = &kmx61_trigger_ops;
1327 iio_trigger_set_drvdata(trig, indio_dev);
1328
1329 ret = iio_trigger_register(trig);
1330 if (ret)
1331 return ERR_PTR(ret);
1332
1333 return trig;
1334}
1335
1336static int kmx61_probe(struct i2c_client *client,
1337 const struct i2c_device_id *id)
1338{
1339 int ret;
1340 struct kmx61_data *data;
1341 const char *name = NULL;
1342
1343 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
1344 if (!data)
1345 return -ENOMEM;
1346
1347 i2c_set_clientdata(client, data);
1348 data->client = client;
1349
1350 mutex_init(&data->lock);
1351
1352 if (id)
1353 name = id->name;
1354 else if (ACPI_HANDLE(&client->dev))
1355 name = kmx61_match_acpi_device(&client->dev);
1356 else
1357 return -ENODEV;
1358
1359 data->acc_indio_dev =
1360 kmx61_indiodev_setup(data, &kmx61_acc_info,
1361 kmx61_acc_channels,
1362 ARRAY_SIZE(kmx61_acc_channels),
1363 name);
1364 if (IS_ERR(data->acc_indio_dev))
1365 return PTR_ERR(data->acc_indio_dev);
1366
1367 data->mag_indio_dev =
1368 kmx61_indiodev_setup(data, &kmx61_mag_info,
1369 kmx61_mag_channels,
1370 ARRAY_SIZE(kmx61_mag_channels),
1371 name);
1372 if (IS_ERR(data->mag_indio_dev))
1373 return PTR_ERR(data->mag_indio_dev);
1374
1375 ret = kmx61_chip_init(data);
1376 if (ret < 0)
1377 return ret;
1378
1379 if (client->irq < 0)
1380 client->irq = kmx61_gpio_probe(client, data);
1381
1382 if (client->irq >= 0) {
1383 ret = devm_request_threaded_irq(&client->dev, client->irq,
1384 kmx61_data_rdy_trig_poll,
1385 kmx61_event_handler,
1386 IRQF_TRIGGER_RISING,
1387 KMX61_IRQ_NAME,
1388 data);
1389 if (ret)
1390 goto err_chip_uninit;
1391
1392 data->acc_dready_trig =
1393 kmx61_trigger_setup(data, data->acc_indio_dev,
1394 "dready");
1395 if (IS_ERR(data->acc_dready_trig)) {
1396 ret = PTR_ERR(data->acc_dready_trig);
1397 goto err_chip_uninit;
1398 }
1399
1400 data->mag_dready_trig =
1401 kmx61_trigger_setup(data, data->mag_indio_dev,
1402 "dready");
1403 if (IS_ERR(data->mag_dready_trig)) {
1404 ret = PTR_ERR(data->mag_dready_trig);
1405 goto err_trigger_unregister_acc_dready;
1406 }
1407
1408 data->motion_trig =
1409 kmx61_trigger_setup(data, data->acc_indio_dev,
1410 "any-motion");
1411 if (IS_ERR(data->motion_trig)) {
1412 ret = PTR_ERR(data->motion_trig);
1413 goto err_trigger_unregister_mag_dready;
1414 }
1415
1416 ret = iio_triggered_buffer_setup(data->acc_indio_dev,
1417 &iio_pollfunc_store_time,
1418 kmx61_trigger_handler,
1419 NULL);
1420 if (ret < 0) {
1421 dev_err(&data->client->dev,
1422 "Failed to setup acc triggered buffer\n");
1423 goto err_trigger_unregister_motion;
1424 }
1425
1426 ret = iio_triggered_buffer_setup(data->mag_indio_dev,
1427 &iio_pollfunc_store_time,
1428 kmx61_trigger_handler,
1429 NULL);
1430 if (ret < 0) {
1431 dev_err(&data->client->dev,
1432 "Failed to setup mag triggered buffer\n");
1433 goto err_buffer_cleanup_acc;
1434 }
1435 }
1436
1437 ret = iio_device_register(data->acc_indio_dev);
1438 if (ret < 0) {
1439 dev_err(&client->dev, "Failed to register acc iio device\n");
1440 goto err_buffer_cleanup_mag;
1441 }
1442
1443 ret = iio_device_register(data->mag_indio_dev);
1444 if (ret < 0) {
1445 dev_err(&client->dev, "Failed to register mag iio device\n");
1446 goto err_iio_unregister_acc;
1447 }
1448
1449 ret = pm_runtime_set_active(&client->dev);
1450 if (ret < 0)
1451 goto err_iio_unregister_mag;
1452
1453 pm_runtime_enable(&client->dev);
1454 pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
1455 pm_runtime_use_autosuspend(&client->dev);
1456
1457 return 0;
1458
1459err_iio_unregister_mag:
1460 iio_device_unregister(data->mag_indio_dev);
1461err_iio_unregister_acc:
1462 iio_device_unregister(data->acc_indio_dev);
1463err_buffer_cleanup_mag:
1464 if (client->irq >= 0)
1465 iio_triggered_buffer_cleanup(data->mag_indio_dev);
1466err_buffer_cleanup_acc:
1467 if (client->irq >= 0)
1468 iio_triggered_buffer_cleanup(data->acc_indio_dev);
1469err_trigger_unregister_motion:
1470 iio_trigger_unregister(data->motion_trig);
1471err_trigger_unregister_mag_dready:
1472 iio_trigger_unregister(data->mag_dready_trig);
1473err_trigger_unregister_acc_dready:
1474 iio_trigger_unregister(data->acc_dready_trig);
1475err_chip_uninit:
1476 kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
1477 return ret;
1478}
1479
1480static int kmx61_remove(struct i2c_client *client)
1481{
1482 struct kmx61_data *data = i2c_get_clientdata(client);
1483
1484 pm_runtime_disable(&client->dev);
1485 pm_runtime_set_suspended(&client->dev);
1486 pm_runtime_put_noidle(&client->dev);
1487
1488 iio_device_unregister(data->acc_indio_dev);
1489 iio_device_unregister(data->mag_indio_dev);
1490
1491 if (client->irq >= 0) {
1492 iio_triggered_buffer_cleanup(data->acc_indio_dev);
1493 iio_triggered_buffer_cleanup(data->mag_indio_dev);
1494 iio_trigger_unregister(data->acc_dready_trig);
1495 iio_trigger_unregister(data->mag_dready_trig);
1496 iio_trigger_unregister(data->motion_trig);
1497 }
1498
1499 mutex_lock(&data->lock);
1500 kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
1501 mutex_unlock(&data->lock);
1502
1503 return 0;
1504}
1505
1506#ifdef CONFIG_PM_SLEEP
1507static int kmx61_suspend(struct device *dev)
1508{
1509 int ret;
1510 struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
1511
1512 mutex_lock(&data->lock);
1513 ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
1514 false);
1515 mutex_unlock(&data->lock);
1516
1517 return ret;
1518}
1519
1520static int kmx61_resume(struct device *dev)
1521{
1522 u8 stby = 0;
1523 struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
1524
1525 if (data->acc_stby)
1526 stby |= KMX61_ACC_STBY_BIT;
1527 if (data->mag_stby)
1528 stby |= KMX61_MAG_STBY_BIT;
1529
1530 return kmx61_set_mode(data, stby, KMX61_ACC | KMX61_MAG, true);
1531}
1532#endif
1533
1534#ifdef CONFIG_PM
1535static int kmx61_runtime_suspend(struct device *dev)
1536{
1537 struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
1538 int ret;
1539
1540 mutex_lock(&data->lock);
1541 ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
1542 mutex_unlock(&data->lock);
1543
1544 return ret;
1545}
1546
1547static int kmx61_runtime_resume(struct device *dev)
1548{
1549 struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
1550 u8 stby = 0;
1551
1552 if (!data->acc_ps)
1553 stby |= KMX61_ACC_STBY_BIT;
1554 if (!data->mag_ps)
1555 stby |= KMX61_MAG_STBY_BIT;
1556
1557 return kmx61_set_mode(data, stby, KMX61_ACC | KMX61_MAG, true);
1558}
1559#endif
1560
1561static const struct dev_pm_ops kmx61_pm_ops = {
1562 SET_SYSTEM_SLEEP_PM_OPS(kmx61_suspend, kmx61_resume)
1563 SET_RUNTIME_PM_OPS(kmx61_runtime_suspend, kmx61_runtime_resume, NULL)
1564};
1565
1566static const struct acpi_device_id kmx61_acpi_match[] = {
1567 {"KMX61021", 0},
1568 {}
1569};
1570
1571MODULE_DEVICE_TABLE(acpi, kmx61_acpi_match);
1572
1573static const struct i2c_device_id kmx61_id[] = {
1574 {"kmx611021", 0},
1575 {}
1576};
1577
1578MODULE_DEVICE_TABLE(i2c, kmx61_id);
1579
1580static struct i2c_driver kmx61_driver = {
1581 .driver = {
1582 .name = KMX61_DRV_NAME,
1583 .acpi_match_table = ACPI_PTR(kmx61_acpi_match),
1584 .pm = &kmx61_pm_ops,
1585 },
1586 .probe = kmx61_probe,
1587 .remove = kmx61_remove,
1588 .id_table = kmx61_id,
1589};
1590
1591module_i2c_driver(kmx61_driver);
1592
1593MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
1594MODULE_DESCRIPTION("KMX61 accelerometer/magnetometer driver");
1595MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index f971f79103ec..71333140d42c 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -178,6 +178,80 @@ static ssize_t iio_scan_el_show(struct device *dev,
178 return sprintf(buf, "%d\n", ret); 178 return sprintf(buf, "%d\n", ret);
179} 179}
180 180
181/* Note NULL used as error indicator as it doesn't make sense. */
182static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
183 unsigned int masklength,
184 const unsigned long *mask)
185{
186 if (bitmap_empty(mask, masklength))
187 return NULL;
188 while (*av_masks) {
189 if (bitmap_subset(mask, av_masks, masklength))
190 return av_masks;
191 av_masks += BITS_TO_LONGS(masklength);
192 }
193 return NULL;
194}
195
196static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
197 const unsigned long *mask)
198{
199 if (!indio_dev->setup_ops->validate_scan_mask)
200 return true;
201
202 return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask);
203}
204
205/**
206 * iio_scan_mask_set() - set particular bit in the scan mask
207 * @indio_dev: the iio device
208 * @buffer: the buffer whose scan mask we are interested in
209 * @bit: the bit to be set.
210 *
211 * Note that at this point we have no way of knowing what other
212 * buffers might request, hence this code only verifies that the
213 * individual buffers request is plausible.
214 */
215static int iio_scan_mask_set(struct iio_dev *indio_dev,
216 struct iio_buffer *buffer, int bit)
217{
218 const unsigned long *mask;
219 unsigned long *trialmask;
220
221 trialmask = kmalloc(sizeof(*trialmask)*
222 BITS_TO_LONGS(indio_dev->masklength),
223 GFP_KERNEL);
224
225 if (trialmask == NULL)
226 return -ENOMEM;
227 if (!indio_dev->masklength) {
228 WARN_ON("Trying to set scanmask prior to registering buffer\n");
229 goto err_invalid_mask;
230 }
231 bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
232 set_bit(bit, trialmask);
233
234 if (!iio_validate_scan_mask(indio_dev, trialmask))
235 goto err_invalid_mask;
236
237 if (indio_dev->available_scan_masks) {
238 mask = iio_scan_mask_match(indio_dev->available_scan_masks,
239 indio_dev->masklength,
240 trialmask);
241 if (!mask)
242 goto err_invalid_mask;
243 }
244 bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
245
246 kfree(trialmask);
247
248 return 0;
249
250err_invalid_mask:
251 kfree(trialmask);
252 return -EINVAL;
253}
254
181static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) 255static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit)
182{ 256{
183 clear_bit(bit, buffer->scan_mask); 257 clear_bit(bit, buffer->scan_mask);
@@ -309,115 +383,19 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
309 return ret; 383 return ret;
310} 384}
311 385
312static const char * const iio_scan_elements_group_name = "scan_elements"; 386static ssize_t iio_buffer_read_length(struct device *dev,
313 387 struct device_attribute *attr,
314int iio_buffer_register(struct iio_dev *indio_dev, 388 char *buf)
315 const struct iio_chan_spec *channels,
316 int num_channels)
317{
318 struct iio_dev_attr *p;
319 struct attribute **attr;
320 struct iio_buffer *buffer = indio_dev->buffer;
321 int ret, i, attrn, attrcount, attrcount_orig = 0;
322
323 if (buffer->attrs)
324 indio_dev->groups[indio_dev->groupcounter++] = buffer->attrs;
325
326 if (buffer->scan_el_attrs != NULL) {
327 attr = buffer->scan_el_attrs->attrs;
328 while (*attr++ != NULL)
329 attrcount_orig++;
330 }
331 attrcount = attrcount_orig;
332 INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
333 if (channels) {
334 /* new magic */
335 for (i = 0; i < num_channels; i++) {
336 if (channels[i].scan_index < 0)
337 continue;
338
339 /* Establish necessary mask length */
340 if (channels[i].scan_index >
341 (int)indio_dev->masklength - 1)
342 indio_dev->masklength
343 = channels[i].scan_index + 1;
344
345 ret = iio_buffer_add_channel_sysfs(indio_dev,
346 &channels[i]);
347 if (ret < 0)
348 goto error_cleanup_dynamic;
349 attrcount += ret;
350 if (channels[i].type == IIO_TIMESTAMP)
351 indio_dev->scan_index_timestamp =
352 channels[i].scan_index;
353 }
354 if (indio_dev->masklength && buffer->scan_mask == NULL) {
355 buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
356 sizeof(*buffer->scan_mask),
357 GFP_KERNEL);
358 if (buffer->scan_mask == NULL) {
359 ret = -ENOMEM;
360 goto error_cleanup_dynamic;
361 }
362 }
363 }
364
365 buffer->scan_el_group.name = iio_scan_elements_group_name;
366
367 buffer->scan_el_group.attrs = kcalloc(attrcount + 1,
368 sizeof(buffer->scan_el_group.attrs[0]),
369 GFP_KERNEL);
370 if (buffer->scan_el_group.attrs == NULL) {
371 ret = -ENOMEM;
372 goto error_free_scan_mask;
373 }
374 if (buffer->scan_el_attrs)
375 memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs,
376 sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig);
377 attrn = attrcount_orig;
378
379 list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
380 buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr;
381 indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group;
382
383 return 0;
384
385error_free_scan_mask:
386 kfree(buffer->scan_mask);
387error_cleanup_dynamic:
388 iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
389
390 return ret;
391}
392EXPORT_SYMBOL(iio_buffer_register);
393
394void iio_buffer_unregister(struct iio_dev *indio_dev)
395{
396 kfree(indio_dev->buffer->scan_mask);
397 kfree(indio_dev->buffer->scan_el_group.attrs);
398 iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list);
399}
400EXPORT_SYMBOL(iio_buffer_unregister);
401
402ssize_t iio_buffer_read_length(struct device *dev,
403 struct device_attribute *attr,
404 char *buf)
405{ 389{
406 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 390 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
407 struct iio_buffer *buffer = indio_dev->buffer; 391 struct iio_buffer *buffer = indio_dev->buffer;
408 392
409 if (buffer->access->get_length) 393 return sprintf(buf, "%d\n", buffer->length);
410 return sprintf(buf, "%d\n",
411 buffer->access->get_length(buffer));
412
413 return 0;
414} 394}
415EXPORT_SYMBOL(iio_buffer_read_length);
416 395
417ssize_t iio_buffer_write_length(struct device *dev, 396static ssize_t iio_buffer_write_length(struct device *dev,
418 struct device_attribute *attr, 397 struct device_attribute *attr,
419 const char *buf, 398 const char *buf, size_t len)
420 size_t len)
421{ 399{
422 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 400 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
423 struct iio_buffer *buffer = indio_dev->buffer; 401 struct iio_buffer *buffer = indio_dev->buffer;
@@ -428,47 +406,28 @@ ssize_t iio_buffer_write_length(struct device *dev,
428 if (ret) 406 if (ret)
429 return ret; 407 return ret;
430 408
431 if (buffer->access->get_length) 409 if (val == buffer->length)
432 if (val == buffer->access->get_length(buffer)) 410 return len;
433 return len;
434 411
435 mutex_lock(&indio_dev->mlock); 412 mutex_lock(&indio_dev->mlock);
436 if (iio_buffer_is_active(indio_dev->buffer)) { 413 if (iio_buffer_is_active(indio_dev->buffer)) {
437 ret = -EBUSY; 414 ret = -EBUSY;
438 } else { 415 } else {
439 if (buffer->access->set_length) 416 buffer->access->set_length(buffer, val);
440 buffer->access->set_length(buffer, val);
441 ret = 0; 417 ret = 0;
442 } 418 }
443 mutex_unlock(&indio_dev->mlock); 419 mutex_unlock(&indio_dev->mlock);
444 420
445 return ret ? ret : len; 421 return ret ? ret : len;
446} 422}
447EXPORT_SYMBOL(iio_buffer_write_length);
448 423
449ssize_t iio_buffer_show_enable(struct device *dev, 424static ssize_t iio_buffer_show_enable(struct device *dev,
450 struct device_attribute *attr, 425 struct device_attribute *attr,
451 char *buf) 426 char *buf)
452{ 427{
453 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 428 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
454 return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer)); 429 return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer));
455} 430}
456EXPORT_SYMBOL(iio_buffer_show_enable);
457
458/* Note NULL used as error indicator as it doesn't make sense. */
459static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
460 unsigned int masklength,
461 const unsigned long *mask)
462{
463 if (bitmap_empty(mask, masklength))
464 return NULL;
465 while (*av_masks) {
466 if (bitmap_subset(mask, av_masks, masklength))
467 return av_masks;
468 av_masks += BITS_TO_LONGS(masklength);
469 }
470 return NULL;
471}
472 431
473static int iio_compute_scan_bytes(struct iio_dev *indio_dev, 432static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
474 const unsigned long *mask, bool timestamp) 433 const unsigned long *mask, bool timestamp)
@@ -680,6 +639,8 @@ static int __iio_update_buffers(struct iio_dev *indio_dev,
680 indio_dev->currentmode = INDIO_BUFFER_TRIGGERED; 639 indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
681 } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) { 640 } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
682 indio_dev->currentmode = INDIO_BUFFER_HARDWARE; 641 indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
642 } else if (indio_dev->modes & INDIO_BUFFER_SOFTWARE) {
643 indio_dev->currentmode = INDIO_BUFFER_SOFTWARE;
683 } else { /* Should never be reached */ 644 } else { /* Should never be reached */
684 ret = -EINVAL; 645 ret = -EINVAL;
685 goto error_run_postdisable; 646 goto error_run_postdisable;
@@ -755,10 +716,10 @@ out_unlock:
755} 716}
756EXPORT_SYMBOL_GPL(iio_update_buffers); 717EXPORT_SYMBOL_GPL(iio_update_buffers);
757 718
758ssize_t iio_buffer_store_enable(struct device *dev, 719static ssize_t iio_buffer_store_enable(struct device *dev,
759 struct device_attribute *attr, 720 struct device_attribute *attr,
760 const char *buf, 721 const char *buf,
761 size_t len) 722 size_t len)
762{ 723{
763 int ret; 724 int ret;
764 bool requested_state; 725 bool requested_state;
@@ -790,83 +751,146 @@ done:
790 mutex_unlock(&indio_dev->mlock); 751 mutex_unlock(&indio_dev->mlock);
791 return (ret < 0) ? ret : len; 752 return (ret < 0) ? ret : len;
792} 753}
793EXPORT_SYMBOL(iio_buffer_store_enable);
794 754
795/** 755static const char * const iio_scan_elements_group_name = "scan_elements";
796 * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected
797 * @indio_dev: the iio device
798 * @mask: scan mask to be checked
799 *
800 * Return true if exactly one bit is set in the scan mask, false otherwise. It
801 * can be used for devices where only one channel can be active for sampling at
802 * a time.
803 */
804bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
805 const unsigned long *mask)
806{
807 return bitmap_weight(mask, indio_dev->masklength) == 1;
808}
809EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot);
810
811static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
812 const unsigned long *mask)
813{
814 if (!indio_dev->setup_ops->validate_scan_mask)
815 return true;
816 756
817 return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask); 757static DEVICE_ATTR(length, S_IRUGO | S_IWUSR, iio_buffer_read_length,
818} 758 iio_buffer_write_length);
759static struct device_attribute dev_attr_length_ro = __ATTR(length,
760 S_IRUGO, iio_buffer_read_length, NULL);
761static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
762 iio_buffer_show_enable, iio_buffer_store_enable);
819 763
820/** 764int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
821 * iio_scan_mask_set() - set particular bit in the scan mask
822 * @indio_dev: the iio device
823 * @buffer: the buffer whose scan mask we are interested in
824 * @bit: the bit to be set.
825 *
826 * Note that at this point we have no way of knowing what other
827 * buffers might request, hence this code only verifies that the
828 * individual buffers request is plausible.
829 */
830int iio_scan_mask_set(struct iio_dev *indio_dev,
831 struct iio_buffer *buffer, int bit)
832{ 765{
833 const unsigned long *mask; 766 struct iio_dev_attr *p;
834 unsigned long *trialmask; 767 struct attribute **attr;
768 struct iio_buffer *buffer = indio_dev->buffer;
769 int ret, i, attrn, attrcount, attrcount_orig = 0;
770 const struct iio_chan_spec *channels;
835 771
836 trialmask = kmalloc(sizeof(*trialmask)* 772 if (!buffer)
837 BITS_TO_LONGS(indio_dev->masklength), 773 return 0;
838 GFP_KERNEL);
839 774
840 if (trialmask == NULL) 775 attrcount = 0;
776 if (buffer->attrs) {
777 while (buffer->attrs[attrcount] != NULL)
778 attrcount++;
779 }
780
781 buffer->buffer_group.name = "buffer";
782 buffer->buffer_group.attrs = kcalloc(attrcount + 3,
783 sizeof(*buffer->buffer_group.attrs), GFP_KERNEL);
784 if (!buffer->buffer_group.attrs)
841 return -ENOMEM; 785 return -ENOMEM;
842 if (!indio_dev->masklength) { 786
843 WARN_ON("Trying to set scanmask prior to registering buffer\n"); 787 if (buffer->access->set_length)
844 goto err_invalid_mask; 788 buffer->buffer_group.attrs[0] = &dev_attr_length.attr;
789 else
790 buffer->buffer_group.attrs[0] = &dev_attr_length_ro.attr;
791 buffer->buffer_group.attrs[1] = &dev_attr_enable.attr;
792 if (buffer->attrs)
793 memcpy(&buffer->buffer_group.attrs[2], buffer->attrs,
794 sizeof(*&buffer->buffer_group.attrs) * attrcount);
795 buffer->buffer_group.attrs[attrcount+2] = NULL;
796
797 indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group;
798
799 if (buffer->scan_el_attrs != NULL) {
800 attr = buffer->scan_el_attrs->attrs;
801 while (*attr++ != NULL)
802 attrcount_orig++;
845 } 803 }
846 bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); 804 attrcount = attrcount_orig;
847 set_bit(bit, trialmask); 805 INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
806 channels = indio_dev->channels;
807 if (channels) {
808 /* new magic */
809 for (i = 0; i < indio_dev->num_channels; i++) {
810 if (channels[i].scan_index < 0)
811 continue;
848 812
849 if (!iio_validate_scan_mask(indio_dev, trialmask)) 813 /* Establish necessary mask length */
850 goto err_invalid_mask; 814 if (channels[i].scan_index >
815 (int)indio_dev->masklength - 1)
816 indio_dev->masklength
817 = channels[i].scan_index + 1;
851 818
852 if (indio_dev->available_scan_masks) { 819 ret = iio_buffer_add_channel_sysfs(indio_dev,
853 mask = iio_scan_mask_match(indio_dev->available_scan_masks, 820 &channels[i]);
854 indio_dev->masklength, 821 if (ret < 0)
855 trialmask); 822 goto error_cleanup_dynamic;
856 if (!mask) 823 attrcount += ret;
857 goto err_invalid_mask; 824 if (channels[i].type == IIO_TIMESTAMP)
825 indio_dev->scan_index_timestamp =
826 channels[i].scan_index;
827 }
828 if (indio_dev->masklength && buffer->scan_mask == NULL) {
829 buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
830 sizeof(*buffer->scan_mask),
831 GFP_KERNEL);
832 if (buffer->scan_mask == NULL) {
833 ret = -ENOMEM;
834 goto error_cleanup_dynamic;
835 }
836 }
858 } 837 }
859 bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
860 838
861 kfree(trialmask); 839 buffer->scan_el_group.name = iio_scan_elements_group_name;
840
841 buffer->scan_el_group.attrs = kcalloc(attrcount + 1,
842 sizeof(buffer->scan_el_group.attrs[0]),
843 GFP_KERNEL);
844 if (buffer->scan_el_group.attrs == NULL) {
845 ret = -ENOMEM;
846 goto error_free_scan_mask;
847 }
848 if (buffer->scan_el_attrs)
849 memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs,
850 sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig);
851 attrn = attrcount_orig;
852
853 list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
854 buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr;
855 indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group;
862 856
863 return 0; 857 return 0;
864 858
865err_invalid_mask: 859error_free_scan_mask:
866 kfree(trialmask); 860 kfree(buffer->scan_mask);
867 return -EINVAL; 861error_cleanup_dynamic:
862 iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
863 kfree(indio_dev->buffer->buffer_group.attrs);
864
865 return ret;
866}
867
868void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev)
869{
870 if (!indio_dev->buffer)
871 return;
872
873 kfree(indio_dev->buffer->scan_mask);
874 kfree(indio_dev->buffer->buffer_group.attrs);
875 kfree(indio_dev->buffer->scan_el_group.attrs);
876 iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list);
877}
878
879/**
880 * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected
881 * @indio_dev: the iio device
882 * @mask: scan mask to be checked
883 *
884 * Return true if exactly one bit is set in the scan mask, false otherwise. It
885 * can be used for devices where only one channel can be active for sampling at
886 * a time.
887 */
888bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
889 const unsigned long *mask)
890{
891 return bitmap_weight(mask, indio_dev->masklength) == 1;
868} 892}
869EXPORT_SYMBOL_GPL(iio_scan_mask_set); 893EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot);
870 894
871int iio_scan_mask_query(struct iio_dev *indio_dev, 895int iio_scan_mask_query(struct iio_dev *indio_dev,
872 struct iio_buffer *buffer, int bit) 896 struct iio_buffer *buffer, int bit)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index af3e76d652ba..aaba9d3d980e 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -70,6 +70,11 @@ static const char * const iio_chan_type_name_spec[] = {
70 [IIO_CCT] = "cct", 70 [IIO_CCT] = "cct",
71 [IIO_PRESSURE] = "pressure", 71 [IIO_PRESSURE] = "pressure",
72 [IIO_HUMIDITYRELATIVE] = "humidityrelative", 72 [IIO_HUMIDITYRELATIVE] = "humidityrelative",
73 [IIO_ACTIVITY] = "activity",
74 [IIO_STEPS] = "steps",
75 [IIO_ENERGY] = "energy",
76 [IIO_DISTANCE] = "distance",
77 [IIO_VELOCITY] = "velocity",
73}; 78};
74 79
75static const char * const iio_modifier_names[] = { 80static const char * const iio_modifier_names[] = {
@@ -91,6 +96,11 @@ static const char * const iio_modifier_names[] = {
91 [IIO_MOD_NORTH_TRUE] = "from_north_true", 96 [IIO_MOD_NORTH_TRUE] = "from_north_true",
92 [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp", 97 [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
93 [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp", 98 [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
99 [IIO_MOD_RUNNING] = "running",
100 [IIO_MOD_JOGGING] = "jogging",
101 [IIO_MOD_WALKING] = "walking",
102 [IIO_MOD_STILL] = "still",
103 [IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z] = "sqrt(x^2+y^2+z^2)",
94}; 104};
95 105
96/* relies on pairs of these shared then separate */ 106/* relies on pairs of these shared then separate */
@@ -113,6 +123,11 @@ static const char * const iio_chan_info_postfix[] = {
113 [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain", 123 [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
114 [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis", 124 [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
115 [IIO_CHAN_INFO_INT_TIME] = "integration_time", 125 [IIO_CHAN_INFO_INT_TIME] = "integration_time",
126 [IIO_CHAN_INFO_ENABLE] = "en",
127 [IIO_CHAN_INFO_CALIBHEIGHT] = "calibheight",
128 [IIO_CHAN_INFO_CALIBWEIGHT] = "calibweight",
129 [IIO_CHAN_INFO_DEBOUNCE_COUNT] = "debounce_count",
130 [IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time",
116}; 131};
117 132
118/** 133/**
@@ -1035,7 +1050,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
1035 if (!ptr) 1050 if (!ptr)
1036 return NULL; 1051 return NULL;
1037 1052
1038 /* use raw alloc_dr for kmalloc caller tracing */
1039 iio_dev = iio_device_alloc(sizeof_priv); 1053 iio_dev = iio_device_alloc(sizeof_priv);
1040 if (iio_dev) { 1054 if (iio_dev) {
1041 *ptr = iio_dev; 1055 *ptr = iio_dev;
@@ -1127,6 +1141,29 @@ static const struct file_operations iio_buffer_fileops = {
1127 .compat_ioctl = iio_ioctl, 1141 .compat_ioctl = iio_ioctl,
1128}; 1142};
1129 1143
1144static int iio_check_unique_scan_index(struct iio_dev *indio_dev)
1145{
1146 int i, j;
1147 const struct iio_chan_spec *channels = indio_dev->channels;
1148
1149 if (!(indio_dev->modes & INDIO_ALL_BUFFER_MODES))
1150 return 0;
1151
1152 for (i = 0; i < indio_dev->num_channels - 1; i++) {
1153 if (channels[i].scan_index < 0)
1154 continue;
1155 for (j = i + 1; j < indio_dev->num_channels; j++)
1156 if (channels[i].scan_index == channels[j].scan_index) {
1157 dev_err(&indio_dev->dev,
1158 "Duplicate scan index %d\n",
1159 channels[i].scan_index);
1160 return -EINVAL;
1161 }
1162 }
1163
1164 return 0;
1165}
1166
1130static const struct iio_buffer_setup_ops noop_ring_setup_ops; 1167static const struct iio_buffer_setup_ops noop_ring_setup_ops;
1131 1168
1132/** 1169/**
@@ -1141,6 +1178,10 @@ int iio_device_register(struct iio_dev *indio_dev)
1141 if (!indio_dev->dev.of_node && indio_dev->dev.parent) 1178 if (!indio_dev->dev.of_node && indio_dev->dev.parent)
1142 indio_dev->dev.of_node = indio_dev->dev.parent->of_node; 1179 indio_dev->dev.of_node = indio_dev->dev.parent->of_node;
1143 1180
1181 ret = iio_check_unique_scan_index(indio_dev);
1182 if (ret < 0)
1183 return ret;
1184
1144 /* configure elements for the chrdev */ 1185 /* configure elements for the chrdev */
1145 indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); 1186 indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);
1146 1187
@@ -1150,11 +1191,19 @@ int iio_device_register(struct iio_dev *indio_dev)
1150 "Failed to register debugfs interfaces\n"); 1191 "Failed to register debugfs interfaces\n");
1151 return ret; 1192 return ret;
1152 } 1193 }
1194
1195 ret = iio_buffer_alloc_sysfs_and_mask(indio_dev);
1196 if (ret) {
1197 dev_err(indio_dev->dev.parent,
1198 "Failed to create buffer sysfs interfaces\n");
1199 goto error_unreg_debugfs;
1200 }
1201
1153 ret = iio_device_register_sysfs(indio_dev); 1202 ret = iio_device_register_sysfs(indio_dev);
1154 if (ret) { 1203 if (ret) {
1155 dev_err(indio_dev->dev.parent, 1204 dev_err(indio_dev->dev.parent,
1156 "Failed to register sysfs interfaces\n"); 1205 "Failed to register sysfs interfaces\n");
1157 goto error_unreg_debugfs; 1206 goto error_buffer_free_sysfs;
1158 } 1207 }
1159 ret = iio_device_register_eventset(indio_dev); 1208 ret = iio_device_register_eventset(indio_dev);
1160 if (ret) { 1209 if (ret) {
@@ -1187,6 +1236,8 @@ error_unreg_eventset:
1187 iio_device_unregister_eventset(indio_dev); 1236 iio_device_unregister_eventset(indio_dev);
1188error_free_sysfs: 1237error_free_sysfs:
1189 iio_device_unregister_sysfs(indio_dev); 1238 iio_device_unregister_sysfs(indio_dev);
1239error_buffer_free_sysfs:
1240 iio_buffer_free_sysfs_and_mask(indio_dev);
1190error_unreg_debugfs: 1241error_unreg_debugfs:
1191 iio_device_unregister_debugfs(indio_dev); 1242 iio_device_unregister_debugfs(indio_dev);
1192 return ret; 1243 return ret;
@@ -1215,6 +1266,8 @@ void iio_device_unregister(struct iio_dev *indio_dev)
1215 iio_buffer_wakeup_poll(indio_dev); 1266 iio_buffer_wakeup_poll(indio_dev);
1216 1267
1217 mutex_unlock(&indio_dev->info_exist_lock); 1268 mutex_unlock(&indio_dev->info_exist_lock);
1269
1270 iio_buffer_free_sysfs_and_mask(indio_dev);
1218} 1271}
1219EXPORT_SYMBOL(iio_device_unregister); 1272EXPORT_SYMBOL(iio_device_unregister);
1220 1273
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 0c1e37e3120a..a4b397048f71 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -197,6 +197,7 @@ static const char * const iio_ev_type_text[] = {
197 [IIO_EV_TYPE_ROC] = "roc", 197 [IIO_EV_TYPE_ROC] = "roc",
198 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", 198 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
199 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", 199 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
200 [IIO_EV_TYPE_CHANGE] = "change",
200}; 201};
201 202
202static const char * const iio_ev_dir_text[] = { 203static const char * const iio_ev_dir_text[] = {
@@ -327,9 +328,15 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
327 for_each_set_bit(i, mask, sizeof(*mask)*8) { 328 for_each_set_bit(i, mask, sizeof(*mask)*8) {
328 if (i >= ARRAY_SIZE(iio_ev_info_text)) 329 if (i >= ARRAY_SIZE(iio_ev_info_text))
329 return -EINVAL; 330 return -EINVAL;
330 postfix = kasprintf(GFP_KERNEL, "%s_%s_%s", 331 if (dir != IIO_EV_DIR_NONE)
331 iio_ev_type_text[type], iio_ev_dir_text[dir], 332 postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
332 iio_ev_info_text[i]); 333 iio_ev_type_text[type],
334 iio_ev_dir_text[dir],
335 iio_ev_info_text[i]);
336 else
337 postfix = kasprintf(GFP_KERNEL, "%s_%s",
338 iio_ev_type_text[type],
339 iio_ev_info_text[i]);
333 if (postfix == NULL) 340 if (postfix == NULL)
334 return -ENOMEM; 341 return -ENOMEM;
335 342
@@ -404,7 +411,7 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
404{ 411{
405 int j, ret, attrcount = 0; 412 int j, ret, attrcount = 0;
406 413
407 /* Dynically created from the channels array */ 414 /* Dynamically created from the channels array */
408 for (j = 0; j < indio_dev->num_channels; j++) { 415 for (j = 0; j < indio_dev->num_channels; j++) {
409 ret = iio_device_add_event_sysfs(indio_dev, 416 ret = iio_device_add_event_sysfs(indio_dev,
410 &indio_dev->channels[j]); 417 &indio_dev->channels[j]);
diff --git a/drivers/iio/industrialio-triggered-buffer.c b/drivers/iio/industrialio-triggered-buffer.c
index d6f54930b34a..15a5341b5e7b 100644
--- a/drivers/iio/industrialio-triggered-buffer.c
+++ b/drivers/iio/industrialio-triggered-buffer.c
@@ -32,7 +32,7 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
32 * 32 *
33 * This function combines some common tasks which will normally be performed 33 * This function combines some common tasks which will normally be performed
34 * when setting up a triggered buffer. It will allocate the buffer and the 34 * when setting up a triggered buffer. It will allocate the buffer and the
35 * pollfunc, as well as register the buffer with the IIO core. 35 * pollfunc.
36 * 36 *
37 * Before calling this function the indio_dev structure should already be 37 * Before calling this function the indio_dev structure should already be
38 * completely initialized, but not yet registered. In practice this means that 38 * completely initialized, but not yet registered. In practice this means that
@@ -49,7 +49,7 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
49 struct iio_buffer *buffer; 49 struct iio_buffer *buffer;
50 int ret; 50 int ret;
51 51
52 buffer = iio_kfifo_allocate(indio_dev); 52 buffer = iio_kfifo_allocate();
53 if (!buffer) { 53 if (!buffer) {
54 ret = -ENOMEM; 54 ret = -ENOMEM;
55 goto error_ret; 55 goto error_ret;
@@ -78,16 +78,8 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
78 /* Flag that polled ring buffering is possible */ 78 /* Flag that polled ring buffering is possible */
79 indio_dev->modes |= INDIO_BUFFER_TRIGGERED; 79 indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
80 80
81 ret = iio_buffer_register(indio_dev,
82 indio_dev->channels,
83 indio_dev->num_channels);
84 if (ret)
85 goto error_dealloc_pollfunc;
86
87 return 0; 81 return 0;
88 82
89error_dealloc_pollfunc:
90 iio_dealloc_pollfunc(indio_dev->pollfunc);
91error_kfifo_free: 83error_kfifo_free:
92 iio_kfifo_free(indio_dev->buffer); 84 iio_kfifo_free(indio_dev->buffer);
93error_ret: 85error_ret:
@@ -101,7 +93,6 @@ EXPORT_SYMBOL(iio_triggered_buffer_setup);
101 */ 93 */
102void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev) 94void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
103{ 95{
104 iio_buffer_unregister(indio_dev);
105 iio_dealloc_pollfunc(indio_dev->pollfunc); 96 iio_dealloc_pollfunc(indio_dev->pollfunc);
106 iio_kfifo_free(indio_dev->buffer); 97 iio_kfifo_free(indio_dev->buffer);
107} 98}
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 90c8cb727cc7..c8bad3cf891d 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -116,8 +116,11 @@ static int __of_iio_simple_xlate(struct iio_dev *indio_dev,
116 if (!iiospec->args_count) 116 if (!iiospec->args_count)
117 return 0; 117 return 0;
118 118
119 if (iiospec->args[0] >= indio_dev->num_channels) 119 if (iiospec->args[0] >= indio_dev->num_channels) {
120 dev_err(&indio_dev->dev, "invalid channel index %u\n",
121 iiospec->args[0]);
120 return -EINVAL; 122 return -EINVAL;
123 }
121 124
122 return iiospec->args[0]; 125 return iiospec->args[0];
123} 126}
@@ -634,3 +637,28 @@ err_unlock:
634 return ret; 637 return ret;
635} 638}
636EXPORT_SYMBOL_GPL(iio_get_channel_type); 639EXPORT_SYMBOL_GPL(iio_get_channel_type);
640
641static int iio_channel_write(struct iio_channel *chan, int val, int val2,
642 enum iio_chan_info_enum info)
643{
644 return chan->indio_dev->info->write_raw(chan->indio_dev,
645 chan->channel, val, val2, info);
646}
647
648int iio_write_channel_raw(struct iio_channel *chan, int val)
649{
650 int ret;
651
652 mutex_lock(&chan->indio_dev->info_exist_lock);
653 if (chan->indio_dev->info == NULL) {
654 ret = -ENODEV;
655 goto err_unlock;
656 }
657
658 ret = iio_channel_write(chan, val, 0, IIO_CHAN_INFO_RAW);
659err_unlock:
660 mutex_unlock(&chan->indio_dev->info_exist_lock);
661
662 return ret;
663}
664EXPORT_SYMBOL_GPL(iio_write_channel_raw);
diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c
index 7134e8ada09a..b2beea01c49b 100644
--- a/drivers/iio/kfifo_buf.c
+++ b/drivers/iio/kfifo_buf.c
@@ -47,30 +47,6 @@ static int iio_request_update_kfifo(struct iio_buffer *r)
47 return ret; 47 return ret;
48} 48}
49 49
50static int iio_get_length_kfifo(struct iio_buffer *r)
51{
52 return r->length;
53}
54
55static IIO_BUFFER_ENABLE_ATTR;
56static IIO_BUFFER_LENGTH_ATTR;
57
58static struct attribute *iio_kfifo_attributes[] = {
59 &dev_attr_length.attr,
60 &dev_attr_enable.attr,
61 NULL,
62};
63
64static struct attribute_group iio_kfifo_attribute_group = {
65 .attrs = iio_kfifo_attributes,
66 .name = "buffer",
67};
68
69static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r)
70{
71 return r->bytes_per_datum;
72}
73
74static int iio_mark_update_needed_kfifo(struct iio_buffer *r) 50static int iio_mark_update_needed_kfifo(struct iio_buffer *r)
75{ 51{
76 struct iio_kfifo *kf = iio_to_kfifo(r); 52 struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -159,26 +135,25 @@ static const struct iio_buffer_access_funcs kfifo_access_funcs = {
159 .read_first_n = &iio_read_first_n_kfifo, 135 .read_first_n = &iio_read_first_n_kfifo,
160 .data_available = iio_kfifo_buf_data_available, 136 .data_available = iio_kfifo_buf_data_available,
161 .request_update = &iio_request_update_kfifo, 137 .request_update = &iio_request_update_kfifo,
162 .get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
163 .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, 138 .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
164 .get_length = &iio_get_length_kfifo,
165 .set_length = &iio_set_length_kfifo, 139 .set_length = &iio_set_length_kfifo,
166 .release = &iio_kfifo_buffer_release, 140 .release = &iio_kfifo_buffer_release,
167}; 141};
168 142
169struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) 143struct iio_buffer *iio_kfifo_allocate(void)
170{ 144{
171 struct iio_kfifo *kf; 145 struct iio_kfifo *kf;
172 146
173 kf = kzalloc(sizeof *kf, GFP_KERNEL); 147 kf = kzalloc(sizeof(*kf), GFP_KERNEL);
174 if (!kf) 148 if (!kf)
175 return NULL; 149 return NULL;
150
176 kf->update_needed = true; 151 kf->update_needed = true;
177 iio_buffer_init(&kf->buffer); 152 iio_buffer_init(&kf->buffer);
178 kf->buffer.attrs = &iio_kfifo_attribute_group;
179 kf->buffer.access = &kfifo_access_funcs; 153 kf->buffer.access = &kfifo_access_funcs;
180 kf->buffer.length = 2; 154 kf->buffer.length = 2;
181 mutex_init(&kf->user_lock); 155 mutex_init(&kf->user_lock);
156
182 return &kf->buffer; 157 return &kf->buffer;
183} 158}
184EXPORT_SYMBOL(iio_kfifo_allocate); 159EXPORT_SYMBOL(iio_kfifo_allocate);
@@ -189,4 +164,58 @@ void iio_kfifo_free(struct iio_buffer *r)
189} 164}
190EXPORT_SYMBOL(iio_kfifo_free); 165EXPORT_SYMBOL(iio_kfifo_free);
191 166
167static void devm_iio_kfifo_release(struct device *dev, void *res)
168{
169 iio_kfifo_free(*(struct iio_buffer **)res);
170}
171
172static int devm_iio_kfifo_match(struct device *dev, void *res, void *data)
173{
174 struct iio_buffer **r = res;
175
176 if (WARN_ON(!r || !*r))
177 return 0;
178
179 return *r == data;
180}
181
182/**
183 * devm_iio_fifo_allocate - Resource-managed iio_kfifo_allocate()
184 * @dev: Device to allocate kfifo buffer for
185 *
186 * RETURNS:
187 * Pointer to allocated iio_buffer on success, NULL on failure.
188 */
189struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
190{
191 struct iio_buffer **ptr, *r;
192
193 ptr = devres_alloc(devm_iio_kfifo_release, sizeof(*ptr), GFP_KERNEL);
194 if (!ptr)
195 return NULL;
196
197 r = iio_kfifo_allocate();
198 if (r) {
199 *ptr = r;
200 devres_add(dev, ptr);
201 } else {
202 devres_free(ptr);
203 }
204
205 return r;
206}
207EXPORT_SYMBOL(devm_iio_kfifo_allocate);
208
209/**
210 * devm_iio_fifo_free - Resource-managed iio_kfifo_free()
211 * @dev: Device the buffer belongs to
212 * @r: The buffer associated with the device
213 */
214void devm_iio_kfifo_free(struct device *dev, struct iio_buffer *r)
215{
216 WARN_ON(devres_release(dev, devm_iio_kfifo_release,
217 devm_iio_kfifo_match, r));
218}
219EXPORT_SYMBOL(devm_iio_kfifo_free);
220
192MODULE_LICENSE("GPL"); 221MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 5bea821adcae..ae68c64bdad3 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -48,6 +48,17 @@ config CM32181
48 To compile this driver as a module, choose M here: 48 To compile this driver as a module, choose M here:
49 the module will be called cm32181. 49 the module will be called cm32181.
50 50
51config CM3232
52 depends on I2C
53 tristate "CM3232 ambient light sensor"
54 help
55 Say Y here if you use cm3232.
56 This option enables ambient light sensor using
57 Capella Microsystems cm3232 device driver.
58
59 To compile this driver as a module, choose M here:
60 the module will be called cm3232.
61
51config CM36651 62config CM36651
52 depends on I2C 63 depends on I2C
53 tristate "CM36651 driver" 64 tristate "CM36651 driver"
@@ -95,6 +106,9 @@ config HID_SENSOR_ALS
95 Say yes here to build support for the HID SENSOR 106 Say yes here to build support for the HID SENSOR
96 Ambient light sensor. 107 Ambient light sensor.
97 108
109 To compile this driver as a module, choose M here: the
110 module will be called hid-sensor-als.
111
98config HID_SENSOR_PROX 112config HID_SENSOR_PROX
99 depends on HID_SENSOR_HUB 113 depends on HID_SENSOR_HUB
100 select IIO_BUFFER 114 select IIO_BUFFER
@@ -109,6 +123,16 @@ config HID_SENSOR_PROX
109 To compile this driver as a module, choose M here: the 123 To compile this driver as a module, choose M here: the
110 module will be called hid-sensor-prox. 124 module will be called hid-sensor-prox.
111 125
126config JSA1212
127 tristate "JSA1212 ALS and proximity sensor driver"
128 depends on I2C
129 help
130 Say Y here if you want to build a IIO driver for JSA1212
131 proximity & ALS sensor device.
132
133 To compile this driver as a module, choose M here:
134 the module will be called jsa1212.
135
112config SENSORS_LM3533 136config SENSORS_LM3533
113 tristate "LM3533 ambient light sensor" 137 tristate "LM3533 ambient light sensor"
114 depends on MFD_LM3533 138 depends on MFD_LM3533
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 47877a36cc12..b12a5160d9e0 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -7,11 +7,13 @@ obj-$(CONFIG_ADJD_S311) += adjd_s311.o
7obj-$(CONFIG_AL3320A) += al3320a.o 7obj-$(CONFIG_AL3320A) += al3320a.o
8obj-$(CONFIG_APDS9300) += apds9300.o 8obj-$(CONFIG_APDS9300) += apds9300.o
9obj-$(CONFIG_CM32181) += cm32181.o 9obj-$(CONFIG_CM32181) += cm32181.o
10obj-$(CONFIG_CM3232) += cm3232.o
10obj-$(CONFIG_CM36651) += cm36651.o 11obj-$(CONFIG_CM36651) += cm36651.o
11obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o 12obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
12obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o 13obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
13obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o 14obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o
14obj-$(CONFIG_ISL29125) += isl29125.o 15obj-$(CONFIG_ISL29125) += isl29125.o
16obj-$(CONFIG_JSA1212) += jsa1212.o
15obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o 17obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
16obj-$(CONFIG_LTR501) += ltr501.o 18obj-$(CONFIG_LTR501) += ltr501.o
17obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o 19obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index ad36b294e4d5..5d12ae54d088 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -169,7 +169,7 @@ static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
169 * @cm32181: pointer of struct cm32181. 169 * @cm32181: pointer of struct cm32181.
170 * 170 *
171 * Convert sensor raw data to lux. It depends on integration 171 * Convert sensor raw data to lux. It depends on integration
172 * time and claibscale variable. 172 * time and calibscale variable.
173 * 173 *
174 * Return: Positive value is lux, otherwise is error code. 174 * Return: Positive value is lux, otherwise is error code.
175 */ 175 */
diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c
new file mode 100644
index 000000000000..90e3519a91de
--- /dev/null
+++ b/drivers/iio/light/cm3232.c
@@ -0,0 +1,403 @@
1/*
2 * CM3232 Ambient Light Sensor
3 *
4 * Copyright (C) 2014-2015 Capella Microsystems Inc.
5 * Author: Kevin Tsai <ktsai@capellamicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2, as published
9 * by the Free Software Foundation.
10 *
11 * IIO driver for CM3232 (7-bit I2C slave address 0x10).
12 */
13
14#include <linux/i2c.h>
15#include <linux/module.h>
16#include <linux/iio/iio.h>
17#include <linux/iio/sysfs.h>
18#include <linux/init.h>
19
20/* Registers Address */
21#define CM3232_REG_ADDR_CMD 0x00
22#define CM3232_REG_ADDR_ALS 0x50
23#define CM3232_REG_ADDR_ID 0x53
24
25#define CM3232_CMD_ALS_DISABLE BIT(0)
26
27#define CM3232_CMD_ALS_IT_SHIFT 2
28#define CM3232_CMD_ALS_IT_MASK (BIT(2) | BIT(3) | BIT(4))
29#define CM3232_CMD_ALS_IT_DEFAULT (0x01 << CM3232_CMD_ALS_IT_SHIFT)
30
31#define CM3232_CMD_ALS_RESET BIT(6)
32
33#define CM3232_CMD_DEFAULT CM3232_CMD_ALS_IT_DEFAULT
34
35#define CM3232_HW_ID 0x32
36#define CM3232_CALIBSCALE_DEFAULT 100000
37#define CM3232_CALIBSCALE_RESOLUTION 100000
38#define CM3232_MLUX_PER_LUX 1000
39
40#define CM3232_MLUX_PER_BIT_DEFAULT 64
41#define CM3232_MLUX_PER_BIT_BASE_IT 100000
42
43static const struct {
44 int val;
45 int val2;
46 u8 it;
47} cm3232_als_it_scales[] = {
48 {0, 100000, 0}, /* 0.100000 */
49 {0, 200000, 1}, /* 0.200000 */
50 {0, 400000, 2}, /* 0.400000 */
51 {0, 800000, 3}, /* 0.800000 */
52 {1, 600000, 4}, /* 1.600000 */
53 {3, 200000, 5}, /* 3.200000 */
54};
55
56struct cm3232_als_info {
57 u8 regs_cmd_default;
58 u8 hw_id;
59 int calibscale;
60 int mlux_per_bit;
61 int mlux_per_bit_base_it;
62};
63
64static struct cm3232_als_info cm3232_als_info_default = {
65 .regs_cmd_default = CM3232_CMD_DEFAULT,
66 .hw_id = CM3232_HW_ID,
67 .calibscale = CM3232_CALIBSCALE_DEFAULT,
68 .mlux_per_bit = CM3232_MLUX_PER_BIT_DEFAULT,
69 .mlux_per_bit_base_it = CM3232_MLUX_PER_BIT_BASE_IT,
70};
71
72struct cm3232_chip {
73 struct i2c_client *client;
74 struct cm3232_als_info *als_info;
75 u8 regs_cmd;
76 u16 regs_als;
77};
78
79/**
80 * cm3232_reg_init() - Initialize CM3232
81 * @chip: pointer of struct cm3232_chip.
82 *
83 * Check and initialize CM3232 ambient light sensor.
84 *
85 * Return: 0 for success; otherwise for error code.
86 */
87static int cm3232_reg_init(struct cm3232_chip *chip)
88{
89 struct i2c_client *client = chip->client;
90 s32 ret;
91
92 chip->als_info = &cm3232_als_info_default;
93
94 /* Identify device */
95 ret = i2c_smbus_read_word_data(client, CM3232_REG_ADDR_ID);
96 if (ret < 0) {
97 dev_err(&chip->client->dev, "Error reading addr_id\n");
98 return ret;
99 }
100
101 if ((ret & 0xFF) != chip->als_info->hw_id)
102 return -ENODEV;
103
104 /* Disable and reset device */
105 chip->regs_cmd = CM3232_CMD_ALS_DISABLE | CM3232_CMD_ALS_RESET;
106 ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
107 chip->regs_cmd);
108 if (ret < 0) {
109 dev_err(&chip->client->dev, "Error writing reg_cmd\n");
110 return ret;
111 }
112
113 /* Register default value */
114 chip->regs_cmd = chip->als_info->regs_cmd_default;
115
116 /* Configure register */
117 ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
118 chip->regs_cmd);
119 if (ret < 0)
120 dev_err(&chip->client->dev, "Error writing reg_cmd\n");
121
122 return 0;
123}
124
125/**
126 * cm3232_read_als_it() - Get sensor integration time
127 * @chip: pointer of struct cm3232_chip
128 * @val: pointer of int to load the integration (sec).
129 * @val2: pointer of int to load the integration time (microsecond).
130 *
131 * Report the current integration time.
132 *
133 * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
134 */
135static int cm3232_read_als_it(struct cm3232_chip *chip, int *val, int *val2)
136{
137 u16 als_it;
138 int i;
139
140 als_it = chip->regs_cmd;
141 als_it &= CM3232_CMD_ALS_IT_MASK;
142 als_it >>= CM3232_CMD_ALS_IT_SHIFT;
143 for (i = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++) {
144 if (als_it == cm3232_als_it_scales[i].it) {
145 *val = cm3232_als_it_scales[i].val;
146 *val2 = cm3232_als_it_scales[i].val2;
147 return IIO_VAL_INT_PLUS_MICRO;
148 }
149 }
150
151 return -EINVAL;
152}
153
154/**
155 * cm3232_write_als_it() - Write sensor integration time
156 * @chip: pointer of struct cm3232_chip.
157 * @val: integration time in second.
158 * @val2: integration time in microsecond.
159 *
160 * Convert integration time to sensor value.
161 *
162 * Return: i2c_smbus_write_byte_data command return value.
163 */
164static int cm3232_write_als_it(struct cm3232_chip *chip, int val, int val2)
165{
166 struct i2c_client *client = chip->client;
167 u16 als_it, cmd;
168 int i;
169 s32 ret;
170
171 for (i = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++) {
172 if (val == cm3232_als_it_scales[i].val &&
173 val2 == cm3232_als_it_scales[i].val2) {
174
175 als_it = cm3232_als_it_scales[i].it;
176 als_it <<= CM3232_CMD_ALS_IT_SHIFT;
177
178 cmd = chip->regs_cmd & ~CM3232_CMD_ALS_IT_MASK;
179 cmd |= als_it;
180 ret = i2c_smbus_write_byte_data(client,
181 CM3232_REG_ADDR_CMD,
182 cmd);
183 if (ret < 0)
184 return ret;
185 chip->regs_cmd = cmd;
186 return 0;
187 }
188 }
189 return -EINVAL;
190}
191
192/**
193 * cm3232_get_lux() - report current lux value
194 * @chip: pointer of struct cm3232_chip.
195 *
196 * Convert sensor data to lux. It depends on integration
197 * time and calibscale variable.
198 *
199 * Return: Zero or positive value is lux, otherwise error code.
200 */
201static int cm3232_get_lux(struct cm3232_chip *chip)
202{
203 struct i2c_client *client = chip->client;
204 struct cm3232_als_info *als_info = chip->als_info;
205 int ret;
206 int val, val2;
207 int als_it;
208 u64 lux;
209
210 /* Calculate mlux per bit based on als_it */
211 ret = cm3232_read_als_it(chip, &val, &val2);
212 if (ret < 0)
213 return -EINVAL;
214 als_it = val * 1000000 + val2;
215 lux = (__force u64)als_info->mlux_per_bit;
216 lux *= als_info->mlux_per_bit_base_it;
217 lux = div_u64(lux, als_it);
218
219 ret = i2c_smbus_read_word_data(client, CM3232_REG_ADDR_ALS);
220 if (ret < 0) {
221 dev_err(&client->dev, "Error reading reg_addr_als\n");
222 return ret;
223 }
224
225 chip->regs_als = (u16)ret;
226 lux *= chip->regs_als;
227 lux *= als_info->calibscale;
228 lux = div_u64(lux, CM3232_CALIBSCALE_RESOLUTION);
229 lux = div_u64(lux, CM3232_MLUX_PER_LUX);
230
231 if (lux > 0xFFFF)
232 lux = 0xFFFF;
233
234 return (int)lux;
235}
236
237static int cm3232_read_raw(struct iio_dev *indio_dev,
238 struct iio_chan_spec const *chan,
239 int *val, int *val2, long mask)
240{
241 struct cm3232_chip *chip = iio_priv(indio_dev);
242 struct cm3232_als_info *als_info = chip->als_info;
243 int ret;
244
245 switch (mask) {
246 case IIO_CHAN_INFO_PROCESSED:
247 ret = cm3232_get_lux(chip);
248 if (ret < 0)
249 return ret;
250 *val = ret;
251 return IIO_VAL_INT;
252 case IIO_CHAN_INFO_CALIBSCALE:
253 *val = als_info->calibscale;
254 return IIO_VAL_INT;
255 case IIO_CHAN_INFO_INT_TIME:
256 return cm3232_read_als_it(chip, val, val2);
257 }
258
259 return -EINVAL;
260}
261
262static int cm3232_write_raw(struct iio_dev *indio_dev,
263 struct iio_chan_spec const *chan,
264 int val, int val2, long mask)
265{
266 struct cm3232_chip *chip = iio_priv(indio_dev);
267 struct cm3232_als_info *als_info = chip->als_info;
268
269 switch (mask) {
270 case IIO_CHAN_INFO_CALIBSCALE:
271 als_info->calibscale = val;
272 return 0;
273 case IIO_CHAN_INFO_INT_TIME:
274 return cm3232_write_als_it(chip, val, val2);
275 }
276
277 return -EINVAL;
278}
279
280/**
281 * cm3232_get_it_available() - Get available ALS IT value
282 * @dev: pointer of struct device.
283 * @attr: pointer of struct device_attribute.
284 * @buf: pointer of return string buffer.
285 *
286 * Display the available integration time in second.
287 *
288 * Return: string length.
289 */
290static ssize_t cm3232_get_it_available(struct device *dev,
291 struct device_attribute *attr, char *buf)
292{
293 int i, len;
294
295 for (i = 0, len = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++)
296 len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ",
297 cm3232_als_it_scales[i].val,
298 cm3232_als_it_scales[i].val2);
299 return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
300}
301
302static const struct iio_chan_spec cm3232_channels[] = {
303 {
304 .type = IIO_LIGHT,
305 .info_mask_separate =
306 BIT(IIO_CHAN_INFO_PROCESSED) |
307 BIT(IIO_CHAN_INFO_CALIBSCALE) |
308 BIT(IIO_CHAN_INFO_INT_TIME),
309 }
310};
311
312static IIO_DEVICE_ATTR(in_illuminance_integration_time_available,
313 S_IRUGO, cm3232_get_it_available, NULL, 0);
314
315static struct attribute *cm3232_attributes[] = {
316 &iio_dev_attr_in_illuminance_integration_time_available.dev_attr.attr,
317 NULL,
318};
319
320static const struct attribute_group cm3232_attribute_group = {
321 .attrs = cm3232_attributes
322};
323
324static const struct iio_info cm3232_info = {
325 .driver_module = THIS_MODULE,
326 .read_raw = &cm3232_read_raw,
327 .write_raw = &cm3232_write_raw,
328 .attrs = &cm3232_attribute_group,
329};
330
331static int cm3232_probe(struct i2c_client *client,
332 const struct i2c_device_id *id)
333{
334 struct cm3232_chip *chip;
335 struct iio_dev *indio_dev;
336 int ret;
337
338 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
339 if (!indio_dev)
340 return -ENOMEM;
341
342 chip = iio_priv(indio_dev);
343 i2c_set_clientdata(client, indio_dev);
344 chip->client = client;
345
346 indio_dev->dev.parent = &client->dev;
347 indio_dev->channels = cm3232_channels;
348 indio_dev->num_channels = ARRAY_SIZE(cm3232_channels);
349 indio_dev->info = &cm3232_info;
350 indio_dev->name = id->name;
351 indio_dev->modes = INDIO_DIRECT_MODE;
352
353 ret = cm3232_reg_init(chip);
354 if (ret) {
355 dev_err(&client->dev,
356 "%s: register init failed\n",
357 __func__);
358 return ret;
359 }
360
361 return iio_device_register(indio_dev);
362}
363
364static int cm3232_remove(struct i2c_client *client)
365{
366 struct iio_dev *indio_dev = i2c_get_clientdata(client);
367
368 i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
369 CM3232_CMD_ALS_DISABLE);
370
371 iio_device_unregister(indio_dev);
372
373 return 0;
374}
375
376static const struct i2c_device_id cm3232_id[] = {
377 {"cm3232", 0},
378 {}
379};
380
381MODULE_DEVICE_TABLE(i2c, cm3232_id);
382
383static const struct of_device_id cm3232_of_match[] = {
384 {.compatible = "capella,cm3232"},
385 {}
386};
387
388static struct i2c_driver cm3232_driver = {
389 .driver = {
390 .name = "cm3232",
391 .owner = THIS_MODULE,
392 .of_match_table = of_match_ptr(cm3232_of_match),
393 },
394 .id_table = cm3232_id,
395 .probe = cm3232_probe,
396 .remove = cm3232_remove,
397};
398
399module_i2c_driver(cm3232_driver);
400
401MODULE_AUTHOR("Kevin Tsai <ktsai@capellamicro.com>");
402MODULE_DESCRIPTION("CM3232 ambient light sensor driver");
403MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index a5283d75c096..948acfc38b8c 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -80,7 +80,6 @@ static int als_read_raw(struct iio_dev *indio_dev,
80 int report_id = -1; 80 int report_id = -1;
81 u32 address; 81 u32 address;
82 int ret_type; 82 int ret_type;
83 s32 poll_value;
84 83
85 *val = 0; 84 *val = 0;
86 *val2 = 0; 85 *val2 = 0;
@@ -97,15 +96,8 @@ static int als_read_raw(struct iio_dev *indio_dev,
97 break; 96 break;
98 } 97 }
99 if (report_id >= 0) { 98 if (report_id >= 0) {
100 poll_value = hid_sensor_read_poll_value(
101 &als_state->common_attributes);
102 if (poll_value < 0)
103 return -EINVAL;
104
105 hid_sensor_power_state(&als_state->common_attributes, 99 hid_sensor_power_state(&als_state->common_attributes,
106 true); 100 true);
107 msleep_interruptible(poll_value * 2);
108
109 *val = sensor_hub_input_attr_get_raw_value( 101 *val = sensor_hub_input_attr_get_raw_value(
110 als_state->common_attributes.hsdev, 102 als_state->common_attributes.hsdev,
111 HID_USAGE_SENSOR_ALS, address, 103 HID_USAGE_SENSOR_ALS, address,
@@ -381,6 +373,7 @@ static struct platform_driver hid_als_platform_driver = {
381 .id_table = hid_als_ids, 373 .id_table = hid_als_ids,
382 .driver = { 374 .driver = {
383 .name = KBUILD_MODNAME, 375 .name = KBUILD_MODNAME,
376 .pm = &hid_sensor_pm_ops,
384 }, 377 },
385 .probe = hid_als_probe, 378 .probe = hid_als_probe,
386 .remove = hid_als_remove, 379 .remove = hid_als_remove,
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index f5a514698fd8..3ecf79ed08ac 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -75,7 +75,6 @@ static int prox_read_raw(struct iio_dev *indio_dev,
75 int report_id = -1; 75 int report_id = -1;
76 u32 address; 76 u32 address;
77 int ret_type; 77 int ret_type;
78 s32 poll_value;
79 78
80 *val = 0; 79 *val = 0;
81 *val2 = 0; 80 *val2 = 0;
@@ -92,16 +91,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,
92 break; 91 break;
93 } 92 }
94 if (report_id >= 0) { 93 if (report_id >= 0) {
95 poll_value = hid_sensor_read_poll_value(
96 &prox_state->common_attributes);
97 if (poll_value < 0)
98 return -EINVAL;
99
100 hid_sensor_power_state(&prox_state->common_attributes, 94 hid_sensor_power_state(&prox_state->common_attributes,
101 true); 95 true);
102
103 msleep_interruptible(poll_value * 2);
104
105 *val = sensor_hub_input_attr_get_raw_value( 96 *val = sensor_hub_input_attr_get_raw_value(
106 prox_state->common_attributes.hsdev, 97 prox_state->common_attributes.hsdev,
107 HID_USAGE_SENSOR_PROX, address, 98 HID_USAGE_SENSOR_PROX, address,
@@ -373,6 +364,7 @@ static struct platform_driver hid_prox_platform_driver = {
373 .id_table = hid_prox_ids, 364 .id_table = hid_prox_ids,
374 .driver = { 365 .driver = {
375 .name = KBUILD_MODNAME, 366 .name = KBUILD_MODNAME,
367 .pm = &hid_sensor_pm_ops,
376 }, 368 },
377 .probe = hid_prox_probe, 369 .probe = hid_prox_probe,
378 .remove = hid_prox_remove, 370 .remove = hid_prox_remove,
diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c
new file mode 100644
index 000000000000..29de7e7d9562
--- /dev/null
+++ b/drivers/iio/light/jsa1212.c
@@ -0,0 +1,471 @@
1/*
2 * JSA1212 Ambient Light & Proximity Sensor Driver
3 *
4 * Copyright (c) 2014, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * JSA1212 I2C slave address: 0x44(ADDR tied to GND), 0x45(ADDR tied to VDD)
16 *
17 * TODO: Interrupt support, thresholds, range support.
18 */
19
20#include <linux/kernel.h>
21#include <linux/slab.h>
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/mutex.h>
26#include <linux/acpi.h>
27#include <linux/regmap.h>
28#include <linux/iio/iio.h>
29#include <linux/iio/sysfs.h>
30
31/* JSA1212 reg address */
32#define JSA1212_CONF_REG 0x01
33#define JSA1212_INT_REG 0x02
34#define JSA1212_PXS_LT_REG 0x03
35#define JSA1212_PXS_HT_REG 0x04
36#define JSA1212_ALS_TH1_REG 0x05
37#define JSA1212_ALS_TH2_REG 0x06
38#define JSA1212_ALS_TH3_REG 0x07
39#define JSA1212_PXS_DATA_REG 0x08
40#define JSA1212_ALS_DT1_REG 0x09
41#define JSA1212_ALS_DT2_REG 0x0A
42#define JSA1212_ALS_RNG_REG 0x0B
43#define JSA1212_MAX_REG 0x0C
44
45/* JSA1212 reg masks */
46#define JSA1212_CONF_MASK 0xFF
47#define JSA1212_INT_MASK 0xFF
48#define JSA1212_PXS_LT_MASK 0xFF
49#define JSA1212_PXS_HT_MASK 0xFF
50#define JSA1212_ALS_TH1_MASK 0xFF
51#define JSA1212_ALS_TH2_LT_MASK 0x0F
52#define JSA1212_ALS_TH2_HT_MASK 0xF0
53#define JSA1212_ALS_TH3_MASK 0xFF
54#define JSA1212_PXS_DATA_MASK 0xFF
55#define JSA1212_ALS_DATA_MASK 0x0FFF
56#define JSA1212_ALS_DT1_MASK 0xFF
57#define JSA1212_ALS_DT2_MASK 0x0F
58#define JSA1212_ALS_RNG_MASK 0x07
59
60/* JSA1212 CONF REG bits */
61#define JSA1212_CONF_PXS_MASK 0x80
62#define JSA1212_CONF_PXS_ENABLE 0x80
63#define JSA1212_CONF_PXS_DISABLE 0x00
64#define JSA1212_CONF_ALS_MASK 0x04
65#define JSA1212_CONF_ALS_ENABLE 0x04
66#define JSA1212_CONF_ALS_DISABLE 0x00
67#define JSA1212_CONF_IRDR_MASK 0x08
68/* Proxmity sensing IRDR current sink settings */
69#define JSA1212_CONF_IRDR_200MA 0x08
70#define JSA1212_CONF_IRDR_100MA 0x00
71#define JSA1212_CONF_PXS_SLP_MASK 0x70
72#define JSA1212_CONF_PXS_SLP_0MS 0x70
73#define JSA1212_CONF_PXS_SLP_12MS 0x60
74#define JSA1212_CONF_PXS_SLP_50MS 0x50
75#define JSA1212_CONF_PXS_SLP_75MS 0x40
76#define JSA1212_CONF_PXS_SLP_100MS 0x30
77#define JSA1212_CONF_PXS_SLP_200MS 0x20
78#define JSA1212_CONF_PXS_SLP_400MS 0x10
79#define JSA1212_CONF_PXS_SLP_800MS 0x00
80
81/* JSA1212 INT REG bits */
82#define JSA1212_INT_CTRL_MASK 0x01
83#define JSA1212_INT_CTRL_EITHER 0x00
84#define JSA1212_INT_CTRL_BOTH 0x01
85#define JSA1212_INT_ALS_PRST_MASK 0x06
86#define JSA1212_INT_ALS_PRST_1CONV 0x00
87#define JSA1212_INT_ALS_PRST_4CONV 0x02
88#define JSA1212_INT_ALS_PRST_8CONV 0x04
89#define JSA1212_INT_ALS_PRST_16CONV 0x06
90#define JSA1212_INT_ALS_FLAG_MASK 0x08
91#define JSA1212_INT_ALS_FLAG_CLR 0x00
92#define JSA1212_INT_PXS_PRST_MASK 0x60
93#define JSA1212_INT_PXS_PRST_1CONV 0x00
94#define JSA1212_INT_PXS_PRST_4CONV 0x20
95#define JSA1212_INT_PXS_PRST_8CONV 0x40
96#define JSA1212_INT_PXS_PRST_16CONV 0x60
97#define JSA1212_INT_PXS_FLAG_MASK 0x80
98#define JSA1212_INT_PXS_FLAG_CLR 0x00
99
100/* JSA1212 ALS RNG REG bits */
101#define JSA1212_ALS_RNG_0_2048 0x00
102#define JSA1212_ALS_RNG_0_1024 0x01
103#define JSA1212_ALS_RNG_0_512 0x02
104#define JSA1212_ALS_RNG_0_256 0x03
105#define JSA1212_ALS_RNG_0_128 0x04
106
107/* JSA1212 INT threshold range */
108#define JSA1212_ALS_TH_MIN 0x0000
109#define JSA1212_ALS_TH_MAX 0x0FFF
110#define JSA1212_PXS_TH_MIN 0x00
111#define JSA1212_PXS_TH_MAX 0xFF
112
113#define JSA1212_ALS_DELAY_MS 200
114#define JSA1212_PXS_DELAY_MS 100
115
116#define JSA1212_DRIVER_NAME "jsa1212"
117#define JSA1212_REGMAP_NAME "jsa1212_regmap"
118
119enum jsa1212_op_mode {
120 JSA1212_OPMODE_ALS_EN,
121 JSA1212_OPMODE_PXS_EN,
122};
123
124struct jsa1212_data {
125 struct i2c_client *client;
126 struct mutex lock;
127 u8 als_rng_idx;
128 bool als_en; /* ALS enable status */
129 bool pxs_en; /* proximity enable status */
130 struct regmap *regmap;
131};
132
133/* ALS range idx to val mapping */
134static const int jsa1212_als_range_val[] = {2048, 1024, 512, 256, 128,
135 128, 128, 128};
136
137/* Enables or disables ALS function based on status */
138static int jsa1212_als_enable(struct jsa1212_data *data, u8 status)
139{
140 int ret;
141
142 ret = regmap_update_bits(data->regmap, JSA1212_CONF_REG,
143 JSA1212_CONF_ALS_MASK,
144 status);
145 if (ret < 0)
146 return ret;
147
148 data->als_en = !!status;
149
150 return 0;
151}
152
153/* Enables or disables PXS function based on status */
154static int jsa1212_pxs_enable(struct jsa1212_data *data, u8 status)
155{
156 int ret;
157
158 ret = regmap_update_bits(data->regmap, JSA1212_CONF_REG,
159 JSA1212_CONF_PXS_MASK,
160 status);
161 if (ret < 0)
162 return ret;
163
164 data->pxs_en = !!status;
165
166 return 0;
167}
168
169static int jsa1212_read_als_data(struct jsa1212_data *data,
170 unsigned int *val)
171{
172 int ret;
173 __le16 als_data;
174
175 ret = jsa1212_als_enable(data, JSA1212_CONF_ALS_ENABLE);
176 if (ret < 0)
177 return ret;
178
179 /* Delay for data output */
180 msleep(JSA1212_ALS_DELAY_MS);
181
182 /* Read 12 bit data */
183 ret = regmap_bulk_read(data->regmap, JSA1212_ALS_DT1_REG, &als_data, 2);
184 if (ret < 0) {
185 dev_err(&data->client->dev, "als data read err\n");
186 goto als_data_read_err;
187 }
188
189 *val = le16_to_cpu(als_data);
190
191als_data_read_err:
192 return jsa1212_als_enable(data, JSA1212_CONF_ALS_DISABLE);
193}
194
195static int jsa1212_read_pxs_data(struct jsa1212_data *data,
196 unsigned int *val)
197{
198 int ret;
199 unsigned int pxs_data;
200
201 ret = jsa1212_pxs_enable(data, JSA1212_CONF_PXS_ENABLE);
202 if (ret < 0)
203 return ret;
204
205 /* Delay for data output */
206 msleep(JSA1212_PXS_DELAY_MS);
207
208 /* Read out all data */
209 ret = regmap_read(data->regmap, JSA1212_PXS_DATA_REG, &pxs_data);
210 if (ret < 0) {
211 dev_err(&data->client->dev, "pxs data read err\n");
212 goto pxs_data_read_err;
213 }
214
215 *val = pxs_data & JSA1212_PXS_DATA_MASK;
216
217pxs_data_read_err:
218 return jsa1212_pxs_enable(data, JSA1212_CONF_PXS_DISABLE);
219}
220
221static int jsa1212_read_raw(struct iio_dev *indio_dev,
222 struct iio_chan_spec const *chan,
223 int *val, int *val2, long mask)
224{
225 int ret;
226 struct jsa1212_data *data = iio_priv(indio_dev);
227
228 switch (mask) {
229 case IIO_CHAN_INFO_RAW:
230 mutex_lock(&data->lock);
231 switch (chan->type) {
232 case IIO_LIGHT:
233 ret = jsa1212_read_als_data(data, val);
234 break;
235 case IIO_PROXIMITY:
236 ret = jsa1212_read_pxs_data(data, val);
237 break;
238 default:
239 ret = -EINVAL;
240 break;
241 }
242 mutex_unlock(&data->lock);
243 return ret < 0 ? ret : IIO_VAL_INT;
244 case IIO_CHAN_INFO_SCALE:
245 switch (chan->type) {
246 case IIO_LIGHT:
247 *val = jsa1212_als_range_val[data->als_rng_idx];
248 *val2 = BIT(12); /* Max 12 bit value */
249 return IIO_VAL_FRACTIONAL;
250 default:
251 break;
252 }
253 break;
254 default:
255 break;
256 }
257
258 return -EINVAL;
259}
260
261static const struct iio_chan_spec jsa1212_channels[] = {
262 {
263 .type = IIO_LIGHT,
264 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
265 BIT(IIO_CHAN_INFO_SCALE),
266 },
267 {
268 .type = IIO_PROXIMITY,
269 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
270 }
271};
272
273static const struct iio_info jsa1212_info = {
274 .driver_module = THIS_MODULE,
275 .read_raw = &jsa1212_read_raw,
276};
277
278static int jsa1212_chip_init(struct jsa1212_data *data)
279{
280 int ret;
281
282 ret = regmap_write(data->regmap, JSA1212_CONF_REG,
283 (JSA1212_CONF_PXS_SLP_50MS |
284 JSA1212_CONF_IRDR_200MA));
285 if (ret < 0)
286 return ret;
287
288 ret = regmap_write(data->regmap, JSA1212_INT_REG,
289 JSA1212_INT_ALS_PRST_4CONV);
290 if (ret < 0)
291 return ret;
292
293 data->als_rng_idx = JSA1212_ALS_RNG_0_2048;
294
295 return 0;
296}
297
298static bool jsa1212_is_volatile_reg(struct device *dev, unsigned int reg)
299{
300 switch (reg) {
301 case JSA1212_PXS_DATA_REG:
302 case JSA1212_ALS_DT1_REG:
303 case JSA1212_ALS_DT2_REG:
304 case JSA1212_INT_REG:
305 return true;
306 default:
307 return false;
308 }
309}
310
311static struct regmap_config jsa1212_regmap_config = {
312 .name = JSA1212_REGMAP_NAME,
313 .reg_bits = 8,
314 .val_bits = 8,
315 .max_register = JSA1212_MAX_REG,
316 .cache_type = REGCACHE_RBTREE,
317 .volatile_reg = jsa1212_is_volatile_reg,
318};
319
320static int jsa1212_probe(struct i2c_client *client,
321 const struct i2c_device_id *id)
322{
323 struct jsa1212_data *data;
324 struct iio_dev *indio_dev;
325 struct regmap *regmap;
326 int ret;
327
328 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
329 return -ENODEV;
330
331 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
332 if (!indio_dev)
333 return -ENOMEM;
334
335 regmap = devm_regmap_init_i2c(client, &jsa1212_regmap_config);
336 if (IS_ERR(regmap)) {
337 dev_err(&client->dev, "Regmap initialization failed.\n");
338 return PTR_ERR(regmap);
339 }
340
341 data = iio_priv(indio_dev);
342
343 i2c_set_clientdata(client, indio_dev);
344 data->client = client;
345 data->regmap = regmap;
346
347 mutex_init(&data->lock);
348
349 ret = jsa1212_chip_init(data);
350 if (ret < 0)
351 return ret;
352
353 indio_dev->dev.parent = &client->dev;
354 indio_dev->channels = jsa1212_channels;
355 indio_dev->num_channels = ARRAY_SIZE(jsa1212_channels);
356 indio_dev->name = JSA1212_DRIVER_NAME;
357 indio_dev->modes = INDIO_DIRECT_MODE;
358
359 indio_dev->info = &jsa1212_info;
360
361 ret = iio_device_register(indio_dev);
362 if (ret < 0)
363 dev_err(&client->dev, "%s: register device failed\n", __func__);
364
365 return ret;
366}
367
368 /* power off the device */
369static int jsa1212_power_off(struct jsa1212_data *data)
370{
371 int ret;
372
373 mutex_lock(&data->lock);
374
375 ret = regmap_update_bits(data->regmap, JSA1212_CONF_REG,
376 JSA1212_CONF_ALS_MASK |
377 JSA1212_CONF_PXS_MASK,
378 JSA1212_CONF_ALS_DISABLE |
379 JSA1212_CONF_PXS_DISABLE);
380
381 if (ret < 0)
382 dev_err(&data->client->dev, "power off cmd failed\n");
383
384 mutex_unlock(&data->lock);
385
386 return ret;
387}
388
389static int jsa1212_remove(struct i2c_client *client)
390{
391 struct iio_dev *indio_dev = i2c_get_clientdata(client);
392 struct jsa1212_data *data = iio_priv(indio_dev);
393
394 iio_device_unregister(indio_dev);
395
396 return jsa1212_power_off(data);
397}
398
399#ifdef CONFIG_PM_SLEEP
400static int jsa1212_suspend(struct device *dev)
401{
402 struct jsa1212_data *data;
403
404 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
405
406 return jsa1212_power_off(data);
407}
408
409static int jsa1212_resume(struct device *dev)
410{
411 int ret = 0;
412 struct jsa1212_data *data;
413
414 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
415
416 mutex_lock(&data->lock);
417
418 if (data->als_en) {
419 ret = jsa1212_als_enable(data, JSA1212_CONF_ALS_ENABLE);
420 if (ret < 0) {
421 dev_err(dev, "als resume failed\n");
422 goto unlock_and_ret;
423 }
424 }
425
426 if (data->pxs_en) {
427 ret = jsa1212_pxs_enable(data, JSA1212_CONF_PXS_ENABLE);
428 if (ret < 0)
429 dev_err(dev, "pxs resume failed\n");
430 }
431
432unlock_and_ret:
433 mutex_unlock(&data->lock);
434 return ret;
435}
436
437static SIMPLE_DEV_PM_OPS(jsa1212_pm_ops, jsa1212_suspend, jsa1212_resume);
438
439#define JSA1212_PM_OPS (&jsa1212_pm_ops)
440#else
441#define JSA1212_PM_OPS NULL
442#endif
443
444static const struct acpi_device_id jsa1212_acpi_match[] = {
445 {"JSA1212", 0},
446 { },
447};
448MODULE_DEVICE_TABLE(acpi, jsa1212_acpi_match);
449
450static const struct i2c_device_id jsa1212_id[] = {
451 { JSA1212_DRIVER_NAME, 0 },
452 { }
453};
454MODULE_DEVICE_TABLE(i2c, jsa1212_id);
455
456static struct i2c_driver jsa1212_driver = {
457 .driver = {
458 .name = JSA1212_DRIVER_NAME,
459 .pm = JSA1212_PM_OPS,
460 .owner = THIS_MODULE,
461 .acpi_match_table = ACPI_PTR(jsa1212_acpi_match),
462 },
463 .probe = jsa1212_probe,
464 .remove = jsa1212_remove,
465 .id_table = jsa1212_id,
466};
467module_i2c_driver(jsa1212_driver);
468
469MODULE_AUTHOR("Sathya Kuppuswamy <sathyanarayanan.kuppuswamy@linux.intel.com>");
470MODULE_DESCRIPTION("JSA1212 proximity/ambient light sensor driver");
471MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index ae3c71bdd6c6..076bc46fad03 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -657,7 +657,7 @@ static ALS_HYSTERESIS_ATTR_RO(3);
657#define ILLUMINANCE_ATTR_RO(_name) \ 657#define ILLUMINANCE_ATTR_RO(_name) \
658 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL) 658 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL)
659#define ILLUMINANCE_ATTR_RW(_name) \ 659#define ILLUMINANCE_ATTR_RW(_name) \
660 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR , \ 660 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR, \
661 show_##_name, store_##_name) 661 show_##_name, store_##_name)
662/* 662/*
663 * ALS Zone threshold-event enable 663 * ALS Zone threshold-event enable
diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c
index a9e449b0be0c..71c2bde275aa 100644
--- a/drivers/iio/light/tcs3414.c
+++ b/drivers/iio/light/tcs3414.c
@@ -149,8 +149,8 @@ static int tcs3414_read_raw(struct iio_dev *indio_dev,
149 *val = ret; 149 *val = ret;
150 return IIO_VAL_INT; 150 return IIO_VAL_INT;
151 case IIO_CHAN_INFO_SCALE: 151 case IIO_CHAN_INFO_SCALE:
152 i = (data->gain & TCS3414_GAIN_MASK) >> TCS3414_GAIN_SHIFT; 152 i = (data->gain & TCS3414_GAIN_MASK) >> TCS3414_GAIN_SHIFT;
153 *val = tcs3414_scales[i][0]; 153 *val = tcs3414_scales[i][0];
154 *val2 = tcs3414_scales[i][1]; 154 *val2 = tcs3414_scales[i][1];
155 return IIO_VAL_INT_PLUS_MICRO; 155 return IIO_VAL_INT_PLUS_MICRO;
156 case IIO_CHAN_INFO_INT_TIME: 156 case IIO_CHAN_INFO_INT_TIME:
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index b2dba9e506ab..4c7a4c52dd06 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -6,26 +6,21 @@
6menu "Magnetometer sensors" 6menu "Magnetometer sensors"
7 7
8config AK8975 8config AK8975
9 tristate "Asahi Kasei AK8975 3-Axis Magnetometer" 9 tristate "Asahi Kasei AK 3-Axis Magnetometer"
10 depends on I2C 10 depends on I2C
11 depends on GPIOLIB 11 depends on GPIOLIB
12 help 12 help
13 Say yes here to build support for Asahi Kasei AK8975 3-Axis 13 Say yes here to build support for Asahi Kasei AK8975, AK8963,
14 Magnetometer. This driver can also support AK8963, if i2c 14 AK09911 or AK09912 3-Axis Magnetometer.
15 device name is identified as ak8963.
16 15
17 To compile this driver as a module, choose M here: the module 16 To compile this driver as a module, choose M here: the module
18 will be called ak8975. 17 will be called ak8975.
19 18
20config AK09911 19config AK09911
21 tristate "Asahi Kasei AK09911 3-axis Compass" 20 tristate "Asahi Kasei AK09911 3-axis Compass"
22 depends on I2C 21 select AK8975
23 help 22 help
24 Say yes here to build support for Asahi Kasei AK09911 3-Axis 23 Deprecated: AK09911 is now supported by AK8975 driver.
25 Magnetometer.
26
27 To compile this driver as a module, choose M here: the module
28 will be called ak09911.
29 24
30config MAG3110 25config MAG3110
31 tristate "Freescale MAG3110 3-Axis Magnetometer" 26 tristate "Freescale MAG3110 3-Axis Magnetometer"
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index b91315e0b826..0f5d3c985799 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -3,7 +3,6 @@
3# 3#
4 4
5# When adding new entries keep the list in alphabetical order 5# When adding new entries keep the list in alphabetical order
6obj-$(CONFIG_AK09911) += ak09911.o
7obj-$(CONFIG_AK8975) += ak8975.o 6obj-$(CONFIG_AK8975) += ak8975.o
8obj-$(CONFIG_MAG3110) += mag3110.o 7obj-$(CONFIG_MAG3110) += mag3110.o
9obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o 8obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
diff --git a/drivers/iio/magnetometer/ak09911.c b/drivers/iio/magnetometer/ak09911.c
deleted file mode 100644
index b2bc942ff6b8..000000000000
--- a/drivers/iio/magnetometer/ak09911.c
+++ /dev/null
@@ -1,326 +0,0 @@
1/*
2 * AK09911 3-axis compass driver
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/i2c.h>
22#include <linux/acpi.h>
23#include <linux/iio/iio.h>
24
25#define AK09911_REG_WIA1 0x00
26#define AK09911_REG_WIA2 0x01
27#define AK09911_WIA1_VALUE 0x48
28#define AK09911_WIA2_VALUE 0x05
29
30#define AK09911_REG_ST1 0x10
31#define AK09911_REG_HXL 0x11
32#define AK09911_REG_HXH 0x12
33#define AK09911_REG_HYL 0x13
34#define AK09911_REG_HYH 0x14
35#define AK09911_REG_HZL 0x15
36#define AK09911_REG_HZH 0x16
37
38#define AK09911_REG_ASAX 0x60
39#define AK09911_REG_ASAY 0x61
40#define AK09911_REG_ASAZ 0x62
41
42#define AK09911_REG_CNTL1 0x30
43#define AK09911_REG_CNTL2 0x31
44#define AK09911_REG_CNTL3 0x32
45
46#define AK09911_MODE_SNG_MEASURE 0x01
47#define AK09911_MODE_SELF_TEST 0x10
48#define AK09911_MODE_FUSE_ACCESS 0x1F
49#define AK09911_MODE_POWERDOWN 0x00
50#define AK09911_RESET_DATA 0x01
51
52#define AK09911_REG_CNTL1 0x30
53#define AK09911_REG_CNTL2 0x31
54#define AK09911_REG_CNTL3 0x32
55
56#define AK09911_RAW_TO_GAUSS(asa) ((((asa) + 128) * 6000) / 256)
57
58#define AK09911_MAX_CONVERSION_TIMEOUT_MS 500
59#define AK09911_CONVERSION_DONE_POLL_TIME_MS 10
60
61struct ak09911_data {
62 struct i2c_client *client;
63 struct mutex lock;
64 u8 asa[3];
65 long raw_to_gauss[3];
66};
67
68static const int ak09911_index_to_reg[] = {
69 AK09911_REG_HXL, AK09911_REG_HYL, AK09911_REG_HZL,
70};
71
72static int ak09911_set_mode(struct i2c_client *client, u8 mode)
73{
74 int ret;
75
76 switch (mode) {
77 case AK09911_MODE_SNG_MEASURE:
78 case AK09911_MODE_SELF_TEST:
79 case AK09911_MODE_FUSE_ACCESS:
80 case AK09911_MODE_POWERDOWN:
81 ret = i2c_smbus_write_byte_data(client,
82 AK09911_REG_CNTL2, mode);
83 if (ret < 0) {
84 dev_err(&client->dev, "set_mode error\n");
85 return ret;
86 }
87 /* After mode change wait atleast 100us */
88 usleep_range(100, 500);
89 break;
90 default:
91 dev_err(&client->dev,
92 "%s: Unknown mode(%d).", __func__, mode);
93 return -EINVAL;
94 }
95
96 return ret;
97}
98
99/* Get Sensitivity Adjustment value */
100static int ak09911_get_asa(struct i2c_client *client)
101{
102 struct iio_dev *indio_dev = i2c_get_clientdata(client);
103 struct ak09911_data *data = iio_priv(indio_dev);
104 int ret;
105
106 ret = ak09911_set_mode(client, AK09911_MODE_FUSE_ACCESS);
107 if (ret < 0)
108 return ret;
109
110 /* Get asa data and store in the device data. */
111 ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_ASAX,
112 3, data->asa);
113 if (ret < 0) {
114 dev_err(&client->dev, "Not able to read asa data\n");
115 return ret;
116 }
117
118 ret = ak09911_set_mode(client, AK09911_MODE_POWERDOWN);
119 if (ret < 0)
120 return ret;
121
122 data->raw_to_gauss[0] = AK09911_RAW_TO_GAUSS(data->asa[0]);
123 data->raw_to_gauss[1] = AK09911_RAW_TO_GAUSS(data->asa[1]);
124 data->raw_to_gauss[2] = AK09911_RAW_TO_GAUSS(data->asa[2]);
125
126 return 0;
127}
128
129static int ak09911_verify_chip_id(struct i2c_client *client)
130{
131 u8 wia_val[2];
132 int ret;
133
134 ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_WIA1,
135 2, wia_val);
136 if (ret < 0) {
137 dev_err(&client->dev, "Error reading WIA\n");
138 return ret;
139 }
140
141 dev_dbg(&client->dev, "WIA %02x %02x\n", wia_val[0], wia_val[1]);
142
143 if (wia_val[0] != AK09911_WIA1_VALUE ||
144 wia_val[1] != AK09911_WIA2_VALUE) {
145 dev_err(&client->dev, "Device ak09911 not found\n");
146 return -ENODEV;
147 }
148
149 return 0;
150}
151
152static int wait_conversion_complete_polled(struct ak09911_data *data)
153{
154 struct i2c_client *client = data->client;
155 u8 read_status;
156 u32 timeout_ms = AK09911_MAX_CONVERSION_TIMEOUT_MS;
157 int ret;
158
159 /* Wait for the conversion to complete. */
160 while (timeout_ms) {
161 msleep_interruptible(AK09911_CONVERSION_DONE_POLL_TIME_MS);
162 ret = i2c_smbus_read_byte_data(client, AK09911_REG_ST1);
163 if (ret < 0) {
164 dev_err(&client->dev, "Error in reading ST1\n");
165 return ret;
166 }
167 read_status = ret & 0x01;
168 if (read_status)
169 break;
170 timeout_ms -= AK09911_CONVERSION_DONE_POLL_TIME_MS;
171 }
172 if (!timeout_ms) {
173 dev_err(&client->dev, "Conversion timeout happened\n");
174 return -EIO;
175 }
176
177 return read_status;
178}
179
180static int ak09911_read_axis(struct iio_dev *indio_dev, int index, int *val)
181{
182 struct ak09911_data *data = iio_priv(indio_dev);
183 struct i2c_client *client = data->client;
184 int ret;
185
186 mutex_lock(&data->lock);
187
188 ret = ak09911_set_mode(client, AK09911_MODE_SNG_MEASURE);
189 if (ret < 0)
190 goto fn_exit;
191
192 ret = wait_conversion_complete_polled(data);
193 if (ret < 0)
194 goto fn_exit;
195
196 /* Read data */
197 ret = i2c_smbus_read_word_data(client, ak09911_index_to_reg[index]);
198 if (ret < 0) {
199 dev_err(&client->dev, "Read axis data fails\n");
200 goto fn_exit;
201 }
202
203 mutex_unlock(&data->lock);
204
205 /* Clamp to valid range. */
206 *val = sign_extend32(clamp_t(s16, ret, -8192, 8191), 13);
207
208 return IIO_VAL_INT;
209
210fn_exit:
211 mutex_unlock(&data->lock);
212
213 return ret;
214}
215
216static int ak09911_read_raw(struct iio_dev *indio_dev,
217 struct iio_chan_spec const *chan,
218 int *val, int *val2,
219 long mask)
220{
221 struct ak09911_data *data = iio_priv(indio_dev);
222
223 switch (mask) {
224 case IIO_CHAN_INFO_RAW:
225 return ak09911_read_axis(indio_dev, chan->address, val);
226 case IIO_CHAN_INFO_SCALE:
227 *val = 0;
228 *val2 = data->raw_to_gauss[chan->address];
229 return IIO_VAL_INT_PLUS_MICRO;
230 }
231
232 return -EINVAL;
233}
234
235#define AK09911_CHANNEL(axis, index) \
236 { \
237 .type = IIO_MAGN, \
238 .modified = 1, \
239 .channel2 = IIO_MOD_##axis, \
240 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
241 BIT(IIO_CHAN_INFO_SCALE), \
242 .address = index, \
243 }
244
245static const struct iio_chan_spec ak09911_channels[] = {
246 AK09911_CHANNEL(X, 0), AK09911_CHANNEL(Y, 1), AK09911_CHANNEL(Z, 2),
247};
248
249static const struct iio_info ak09911_info = {
250 .read_raw = &ak09911_read_raw,
251 .driver_module = THIS_MODULE,
252};
253
254static const struct acpi_device_id ak_acpi_match[] = {
255 {"AK009911", 0},
256 { },
257};
258MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
259
260static int ak09911_probe(struct i2c_client *client,
261 const struct i2c_device_id *id)
262{
263 struct iio_dev *indio_dev;
264 struct ak09911_data *data;
265 const char *name;
266 int ret;
267
268 ret = ak09911_verify_chip_id(client);
269 if (ret) {
270 dev_err(&client->dev, "AK00911 not detected\n");
271 return -ENODEV;
272 }
273
274 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
275 if (indio_dev == NULL)
276 return -ENOMEM;
277
278 data = iio_priv(indio_dev);
279 i2c_set_clientdata(client, indio_dev);
280
281 data->client = client;
282 mutex_init(&data->lock);
283
284 ret = ak09911_get_asa(client);
285 if (ret)
286 return ret;
287
288 if (id)
289 name = id->name;
290 else if (ACPI_HANDLE(&client->dev))
291 name = dev_name(&client->dev);
292 else
293 return -ENODEV;
294
295 dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
296
297 indio_dev->dev.parent = &client->dev;
298 indio_dev->channels = ak09911_channels;
299 indio_dev->num_channels = ARRAY_SIZE(ak09911_channels);
300 indio_dev->info = &ak09911_info;
301 indio_dev->modes = INDIO_DIRECT_MODE;
302 indio_dev->name = name;
303
304 return devm_iio_device_register(&client->dev, indio_dev);
305}
306
307static const struct i2c_device_id ak09911_id[] = {
308 {"ak09911", 0},
309 {}
310};
311
312MODULE_DEVICE_TABLE(i2c, ak09911_id);
313
314static struct i2c_driver ak09911_driver = {
315 .driver = {
316 .name = "ak09911",
317 .acpi_match_table = ACPI_PTR(ak_acpi_match),
318 },
319 .probe = ak09911_probe,
320 .id_table = ak09911_id,
321};
322module_i2c_driver(ak09911_driver);
323
324MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
325MODULE_LICENSE("GPL v2");
326MODULE_DESCRIPTION("AK09911 Compass driver");
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index bf5ef077e791..b13936dacc78 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -64,10 +64,10 @@
64#define AK8975_REG_CNTL 0x0A 64#define AK8975_REG_CNTL 0x0A
65#define AK8975_REG_CNTL_MODE_SHIFT 0 65#define AK8975_REG_CNTL_MODE_SHIFT 0
66#define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT) 66#define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT)
67#define AK8975_REG_CNTL_MODE_POWER_DOWN 0 67#define AK8975_REG_CNTL_MODE_POWER_DOWN 0x00
68#define AK8975_REG_CNTL_MODE_ONCE 1 68#define AK8975_REG_CNTL_MODE_ONCE 0x01
69#define AK8975_REG_CNTL_MODE_SELF_TEST 8 69#define AK8975_REG_CNTL_MODE_SELF_TEST 0x08
70#define AK8975_REG_CNTL_MODE_FUSE_ROM 0xF 70#define AK8975_REG_CNTL_MODE_FUSE_ROM 0x0F
71 71
72#define AK8975_REG_RSVC 0x0B 72#define AK8975_REG_RSVC 0x0B
73#define AK8975_REG_ASTC 0x0C 73#define AK8975_REG_ASTC 0x0C
@@ -81,18 +81,278 @@
81#define AK8975_MAX_REGS AK8975_REG_ASAZ 81#define AK8975_MAX_REGS AK8975_REG_ASAZ
82 82
83/* 83/*
84 * AK09912 Register definitions
85 */
86#define AK09912_REG_WIA1 0x00
87#define AK09912_REG_WIA2 0x01
88#define AK09912_DEVICE_ID 0x04
89#define AK09911_DEVICE_ID 0x05
90
91#define AK09911_REG_INFO1 0x02
92#define AK09911_REG_INFO2 0x03
93
94#define AK09912_REG_ST1 0x10
95
96#define AK09912_REG_ST1_DRDY_SHIFT 0
97#define AK09912_REG_ST1_DRDY_MASK (1 << AK09912_REG_ST1_DRDY_SHIFT)
98
99#define AK09912_REG_HXL 0x11
100#define AK09912_REG_HXH 0x12
101#define AK09912_REG_HYL 0x13
102#define AK09912_REG_HYH 0x14
103#define AK09912_REG_HZL 0x15
104#define AK09912_REG_HZH 0x16
105#define AK09912_REG_TMPS 0x17
106
107#define AK09912_REG_ST2 0x18
108#define AK09912_REG_ST2_HOFL_SHIFT 3
109#define AK09912_REG_ST2_HOFL_MASK (1 << AK09912_REG_ST2_HOFL_SHIFT)
110
111#define AK09912_REG_CNTL1 0x30
112
113#define AK09912_REG_CNTL2 0x31
114#define AK09912_REG_CNTL_MODE_POWER_DOWN 0x00
115#define AK09912_REG_CNTL_MODE_ONCE 0x01
116#define AK09912_REG_CNTL_MODE_SELF_TEST 0x10
117#define AK09912_REG_CNTL_MODE_FUSE_ROM 0x1F
118#define AK09912_REG_CNTL2_MODE_SHIFT 0
119#define AK09912_REG_CNTL2_MODE_MASK (0x1F << AK09912_REG_CNTL2_MODE_SHIFT)
120
121#define AK09912_REG_CNTL3 0x32
122
123#define AK09912_REG_TS1 0x33
124#define AK09912_REG_TS2 0x34
125#define AK09912_REG_TS3 0x35
126#define AK09912_REG_I2CDIS 0x36
127#define AK09912_REG_TS4 0x37
128
129#define AK09912_REG_ASAX 0x60
130#define AK09912_REG_ASAY 0x61
131#define AK09912_REG_ASAZ 0x62
132
133#define AK09912_MAX_REGS AK09912_REG_ASAZ
134
135/*
84 * Miscellaneous values. 136 * Miscellaneous values.
85 */ 137 */
86#define AK8975_MAX_CONVERSION_TIMEOUT 500 138#define AK8975_MAX_CONVERSION_TIMEOUT 500
87#define AK8975_CONVERSION_DONE_POLL_TIME 10 139#define AK8975_CONVERSION_DONE_POLL_TIME 10
88#define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000) 140#define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000)
89#define RAW_TO_GAUSS_8975(asa) ((((asa) + 128) * 3000) / 256) 141
90#define RAW_TO_GAUSS_8963(asa) ((((asa) + 128) * 6000) / 256) 142/*
143 * Precalculate scale factor (in Gauss units) for each axis and
144 * store in the device data.
145 *
146 * This scale factor is axis-dependent, and is derived from 3 calibration
147 * factors ASA(x), ASA(y), and ASA(z).
148 *
149 * These ASA values are read from the sensor device at start of day, and
150 * cached in the device context struct.
151 *
152 * Adjusting the flux value with the sensitivity adjustment value should be
153 * done via the following formula:
154 *
155 * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
156 * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
157 * is the resultant adjusted value.
158 *
159 * We reduce the formula to:
160 *
161 * Hadj = H * (ASA + 128) / 256
162 *
163 * H is in the range of -4096 to 4095. The magnetometer has a range of
164 * +-1229uT. To go from the raw value to uT is:
165 *
166 * HuT = H * 1229/4096, or roughly, 3/10.
167 *
168 * Since 1uT = 0.01 gauss, our final scale factor becomes:
169 *
170 * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
171 * Hadj = H * ((ASA + 128) * 0.003) / 256
172 *
173 * Since ASA doesn't change, we cache the resultant scale factor into the
174 * device context in ak8975_setup().
175 *
176 * Given we use IIO_VAL_INT_PLUS_MICRO bit when displaying the scale, we
177 * multiply the stored scale value by 1e6.
178 */
179static long ak8975_raw_to_gauss(u16 data)
180{
181 return (((long)data + 128) * 3000) / 256;
182}
183
184/*
185 * For AK8963 and AK09911, same calculation, but the device is less sensitive:
186 *
187 * H is in the range of +-8190. The magnetometer has a range of
188 * +-4912uT. To go from the raw value to uT is:
189 *
190 * HuT = H * 4912/8190, or roughly, 6/10, instead of 3/10.
191 */
192
193static long ak8963_09911_raw_to_gauss(u16 data)
194{
195 return (((long)data + 128) * 6000) / 256;
196}
197
198/*
199 * For AK09912, same calculation, except the device is more sensitive:
200 *
201 * H is in the range of -32752 to 32752. The magnetometer has a range of
202 * +-4912uT. To go from the raw value to uT is:
203 *
204 * HuT = H * 4912/32752, or roughly, 3/20, instead of 3/10.
205 */
206static long ak09912_raw_to_gauss(u16 data)
207{
208 return (((long)data + 128) * 1500) / 256;
209}
91 210
92/* Compatible Asahi Kasei Compass parts */ 211/* Compatible Asahi Kasei Compass parts */
93enum asahi_compass_chipset { 212enum asahi_compass_chipset {
94 AK8975, 213 AK8975,
95 AK8963, 214 AK8963,
215 AK09911,
216 AK09912,
217 AK_MAX_TYPE
218};
219
220enum ak_ctrl_reg_addr {
221 ST1,
222 ST2,
223 CNTL,
224 ASA_BASE,
225 MAX_REGS,
226 REGS_END,
227};
228
229enum ak_ctrl_reg_mask {
230 ST1_DRDY,
231 ST2_HOFL,
232 ST2_DERR,
233 CNTL_MODE,
234 MASK_END,
235};
236
237enum ak_ctrl_mode {
238 POWER_DOWN,
239 MODE_ONCE,
240 SELF_TEST,
241 FUSE_ROM,
242 MODE_END,
243};
244
245struct ak_def {
246 enum asahi_compass_chipset type;
247 long (*raw_to_gauss)(u16 data);
248 u16 range;
249 u8 ctrl_regs[REGS_END];
250 u8 ctrl_masks[MASK_END];
251 u8 ctrl_modes[MODE_END];
252 u8 data_regs[3];
253};
254
255static struct ak_def ak_def_array[AK_MAX_TYPE] = {
256 {
257 .type = AK8975,
258 .raw_to_gauss = ak8975_raw_to_gauss,
259 .range = 4096,
260 .ctrl_regs = {
261 AK8975_REG_ST1,
262 AK8975_REG_ST2,
263 AK8975_REG_CNTL,
264 AK8975_REG_ASAX,
265 AK8975_MAX_REGS},
266 .ctrl_masks = {
267 AK8975_REG_ST1_DRDY_MASK,
268 AK8975_REG_ST2_HOFL_MASK,
269 AK8975_REG_ST2_DERR_MASK,
270 AK8975_REG_CNTL_MODE_MASK},
271 .ctrl_modes = {
272 AK8975_REG_CNTL_MODE_POWER_DOWN,
273 AK8975_REG_CNTL_MODE_ONCE,
274 AK8975_REG_CNTL_MODE_SELF_TEST,
275 AK8975_REG_CNTL_MODE_FUSE_ROM},
276 .data_regs = {
277 AK8975_REG_HXL,
278 AK8975_REG_HYL,
279 AK8975_REG_HZL},
280 },
281 {
282 .type = AK8963,
283 .raw_to_gauss = ak8963_09911_raw_to_gauss,
284 .range = 8190,
285 .ctrl_regs = {
286 AK8975_REG_ST1,
287 AK8975_REG_ST2,
288 AK8975_REG_CNTL,
289 AK8975_REG_ASAX,
290 AK8975_MAX_REGS},
291 .ctrl_masks = {
292 AK8975_REG_ST1_DRDY_MASK,
293 AK8975_REG_ST2_HOFL_MASK,
294 0,
295 AK8975_REG_CNTL_MODE_MASK},
296 .ctrl_modes = {
297 AK8975_REG_CNTL_MODE_POWER_DOWN,
298 AK8975_REG_CNTL_MODE_ONCE,
299 AK8975_REG_CNTL_MODE_SELF_TEST,
300 AK8975_REG_CNTL_MODE_FUSE_ROM},
301 .data_regs = {
302 AK8975_REG_HXL,
303 AK8975_REG_HYL,
304 AK8975_REG_HZL},
305 },
306 {
307 .type = AK09911,
308 .raw_to_gauss = ak8963_09911_raw_to_gauss,
309 .range = 8192,
310 .ctrl_regs = {
311 AK09912_REG_ST1,
312 AK09912_REG_ST2,
313 AK09912_REG_CNTL2,
314 AK09912_REG_ASAX,
315 AK09912_MAX_REGS},
316 .ctrl_masks = {
317 AK09912_REG_ST1_DRDY_MASK,
318 AK09912_REG_ST2_HOFL_MASK,
319 0,
320 AK09912_REG_CNTL2_MODE_MASK},
321 .ctrl_modes = {
322 AK09912_REG_CNTL_MODE_POWER_DOWN,
323 AK09912_REG_CNTL_MODE_ONCE,
324 AK09912_REG_CNTL_MODE_SELF_TEST,
325 AK09912_REG_CNTL_MODE_FUSE_ROM},
326 .data_regs = {
327 AK09912_REG_HXL,
328 AK09912_REG_HYL,
329 AK09912_REG_HZL},
330 },
331 {
332 .type = AK09912,
333 .raw_to_gauss = ak09912_raw_to_gauss,
334 .range = 32752,
335 .ctrl_regs = {
336 AK09912_REG_ST1,
337 AK09912_REG_ST2,
338 AK09912_REG_CNTL2,
339 AK09912_REG_ASAX,
340 AK09912_MAX_REGS},
341 .ctrl_masks = {
342 AK09912_REG_ST1_DRDY_MASK,
343 AK09912_REG_ST2_HOFL_MASK,
344 0,
345 AK09912_REG_CNTL2_MODE_MASK},
346 .ctrl_modes = {
347 AK09912_REG_CNTL_MODE_POWER_DOWN,
348 AK09912_REG_CNTL_MODE_ONCE,
349 AK09912_REG_CNTL_MODE_SELF_TEST,
350 AK09912_REG_CNTL_MODE_FUSE_ROM},
351 .data_regs = {
352 AK09912_REG_HXL,
353 AK09912_REG_HYL,
354 AK09912_REG_HZL},
355 }
96}; 356};
97 357
98/* 358/*
@@ -100,40 +360,82 @@ enum asahi_compass_chipset {
100 */ 360 */
101struct ak8975_data { 361struct ak8975_data {
102 struct i2c_client *client; 362 struct i2c_client *client;
363 struct ak_def *def;
103 struct attribute_group attrs; 364 struct attribute_group attrs;
104 struct mutex lock; 365 struct mutex lock;
105 u8 asa[3]; 366 u8 asa[3];
106 long raw_to_gauss[3]; 367 long raw_to_gauss[3];
107 u8 reg_cache[AK8975_MAX_REGS];
108 int eoc_gpio; 368 int eoc_gpio;
109 int eoc_irq; 369 int eoc_irq;
110 wait_queue_head_t data_ready_queue; 370 wait_queue_head_t data_ready_queue;
111 unsigned long flags; 371 unsigned long flags;
112 enum asahi_compass_chipset chipset; 372 u8 cntl_cache;
113}; 373};
114 374
115static const int ak8975_index_to_reg[] = { 375/*
116 AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL, 376 * Return 0 if the i2c device is the one we expect.
117}; 377 * return a negative error number otherwise
378 */
379static int ak8975_who_i_am(struct i2c_client *client,
380 enum asahi_compass_chipset type)
381{
382 u8 wia_val[2];
383 int ret;
384
385 /*
386 * Signature for each device:
387 * Device | WIA1 | WIA2
388 * AK09912 | DEVICE_ID | AK09912_DEVICE_ID
389 * AK09911 | DEVICE_ID | AK09911_DEVICE_ID
390 * AK8975 | DEVICE_ID | NA
391 * AK8963 | DEVICE_ID | NA
392 */
393 ret = i2c_smbus_read_i2c_block_data(client, AK09912_REG_WIA1,
394 2, wia_val);
395 if (ret < 0) {
396 dev_err(&client->dev, "Error reading WIA\n");
397 return ret;
398 }
399
400 if (wia_val[0] != AK8975_DEVICE_ID)
401 return -ENODEV;
402
403 switch (type) {
404 case AK8975:
405 case AK8963:
406 return 0;
407 case AK09911:
408 if (wia_val[1] == AK09911_DEVICE_ID)
409 return 0;
410 break;
411 case AK09912:
412 if (wia_val[1] == AK09912_DEVICE_ID)
413 return 0;
414 break;
415 default:
416 dev_err(&client->dev, "Type %d unknown\n", type);
417 }
418 return -ENODEV;
419}
118 420
119/* 421/*
120 * Helper function to write to the I2C device's registers. 422 * Helper function to write to CNTL register.
121 */ 423 */
122static int ak8975_write_data(struct i2c_client *client, 424static int ak8975_set_mode(struct ak8975_data *data, enum ak_ctrl_mode mode)
123 u8 reg, u8 val, u8 mask, u8 shift)
124{ 425{
125 struct iio_dev *indio_dev = i2c_get_clientdata(client);
126 struct ak8975_data *data = iio_priv(indio_dev);
127 u8 regval; 426 u8 regval;
128 int ret; 427 int ret;
129 428
130 regval = (data->reg_cache[reg] & ~mask) | (val << shift); 429 regval = (data->cntl_cache & ~data->def->ctrl_masks[CNTL_MODE]) |
131 ret = i2c_smbus_write_byte_data(client, reg, regval); 430 data->def->ctrl_modes[mode];
431 ret = i2c_smbus_write_byte_data(data->client,
432 data->def->ctrl_regs[CNTL], regval);
132 if (ret < 0) { 433 if (ret < 0) {
133 dev_err(&client->dev, "Write to device fails status %x\n", ret);
134 return ret; 434 return ret;
135 } 435 }
136 data->reg_cache[reg] = regval; 436 data->cntl_cache = regval;
437 /* After mode change wait atleast 100us */
438 usleep_range(100, 500);
137 439
138 return 0; 440 return 0;
139} 441}
@@ -166,8 +468,8 @@ static int ak8975_setup_irq(struct ak8975_data *data)
166 irq = gpio_to_irq(data->eoc_gpio); 468 irq = gpio_to_irq(data->eoc_gpio);
167 469
168 rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler, 470 rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler,
169 IRQF_TRIGGER_RISING | IRQF_ONESHOT, 471 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
170 dev_name(&client->dev), data); 472 dev_name(&client->dev), data);
171 if (rc < 0) { 473 if (rc < 0) {
172 dev_err(&client->dev, 474 dev_err(&client->dev,
173 "irq %d request failed, (gpio %d): %d\n", 475 "irq %d request failed, (gpio %d): %d\n",
@@ -191,34 +493,18 @@ static int ak8975_setup(struct i2c_client *client)
191{ 493{
192 struct iio_dev *indio_dev = i2c_get_clientdata(client); 494 struct iio_dev *indio_dev = i2c_get_clientdata(client);
193 struct ak8975_data *data = iio_priv(indio_dev); 495 struct ak8975_data *data = iio_priv(indio_dev);
194 u8 device_id;
195 int ret; 496 int ret;
196 497
197 /* Confirm that the device we're talking to is really an AK8975. */
198 ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
199 if (ret < 0) {
200 dev_err(&client->dev, "Error reading WIA\n");
201 return ret;
202 }
203 device_id = ret;
204 if (device_id != AK8975_DEVICE_ID) {
205 dev_err(&client->dev, "Device ak8975 not found\n");
206 return -ENODEV;
207 }
208
209 /* Write the fused rom access mode. */ 498 /* Write the fused rom access mode. */
210 ret = ak8975_write_data(client, 499 ret = ak8975_set_mode(data, FUSE_ROM);
211 AK8975_REG_CNTL,
212 AK8975_REG_CNTL_MODE_FUSE_ROM,
213 AK8975_REG_CNTL_MODE_MASK,
214 AK8975_REG_CNTL_MODE_SHIFT);
215 if (ret < 0) { 500 if (ret < 0) {
216 dev_err(&client->dev, "Error in setting fuse access mode\n"); 501 dev_err(&client->dev, "Error in setting fuse access mode\n");
217 return ret; 502 return ret;
218 } 503 }
219 504
220 /* Get asa data and store in the device data. */ 505 /* Get asa data and store in the device data. */
221 ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX, 506 ret = i2c_smbus_read_i2c_block_data(client,
507 data->def->ctrl_regs[ASA_BASE],
222 3, data->asa); 508 3, data->asa);
223 if (ret < 0) { 509 if (ret < 0) {
224 dev_err(&client->dev, "Not able to read asa data\n"); 510 dev_err(&client->dev, "Not able to read asa data\n");
@@ -226,13 +512,13 @@ static int ak8975_setup(struct i2c_client *client)
226 } 512 }
227 513
228 /* After reading fuse ROM data set power-down mode */ 514 /* After reading fuse ROM data set power-down mode */
229 ret = ak8975_write_data(client, 515 ret = ak8975_set_mode(data, POWER_DOWN);
230 AK8975_REG_CNTL, 516 if (ret < 0) {
231 AK8975_REG_CNTL_MODE_POWER_DOWN, 517 dev_err(&client->dev, "Error in setting power-down mode\n");
232 AK8975_REG_CNTL_MODE_MASK, 518 return ret;
233 AK8975_REG_CNTL_MODE_SHIFT); 519 }
234 520
235 if (data->eoc_gpio > 0 || client->irq) { 521 if (data->eoc_gpio > 0 || client->irq > 0) {
236 ret = ak8975_setup_irq(data); 522 ret = ak8975_setup_irq(data);
237 if (ret < 0) { 523 if (ret < 0) {
238 dev_err(&client->dev, 524 dev_err(&client->dev,
@@ -241,61 +527,9 @@ static int ak8975_setup(struct i2c_client *client)
241 } 527 }
242 } 528 }
243 529
244 if (ret < 0) { 530 data->raw_to_gauss[0] = data->def->raw_to_gauss(data->asa[0]);
245 dev_err(&client->dev, "Error in setting power-down mode\n"); 531 data->raw_to_gauss[1] = data->def->raw_to_gauss(data->asa[1]);
246 return ret; 532 data->raw_to_gauss[2] = data->def->raw_to_gauss(data->asa[2]);
247 }
248
249/*
250 * Precalculate scale factor (in Gauss units) for each axis and
251 * store in the device data.
252 *
253 * This scale factor is axis-dependent, and is derived from 3 calibration
254 * factors ASA(x), ASA(y), and ASA(z).
255 *
256 * These ASA values are read from the sensor device at start of day, and
257 * cached in the device context struct.
258 *
259 * Adjusting the flux value with the sensitivity adjustment value should be
260 * done via the following formula:
261 *
262 * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
263 *
264 * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
265 * is the resultant adjusted value.
266 *
267 * We reduce the formula to:
268 *
269 * Hadj = H * (ASA + 128) / 256
270 *
271 * H is in the range of -4096 to 4095. The magnetometer has a range of
272 * +-1229uT. To go from the raw value to uT is:
273 *
274 * HuT = H * 1229/4096, or roughly, 3/10.
275 *
276 * Since 1uT = 0.01 gauss, our final scale factor becomes:
277 *
278 * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
279 * Hadj = H * ((ASA + 128) * 0.003) / 256
280 *
281 * Since ASA doesn't change, we cache the resultant scale factor into the
282 * device context in ak8975_setup().
283 */
284 if (data->chipset == AK8963) {
285 /*
286 * H range is +-8190 and magnetometer range is +-4912.
287 * So HuT using the above explanation for 8975,
288 * 4912/8190 = ~ 6/10.
289 * So the Hadj should use 6/10 instead of 3/10.
290 */
291 data->raw_to_gauss[0] = RAW_TO_GAUSS_8963(data->asa[0]);
292 data->raw_to_gauss[1] = RAW_TO_GAUSS_8963(data->asa[1]);
293 data->raw_to_gauss[2] = RAW_TO_GAUSS_8963(data->asa[2]);
294 } else {
295 data->raw_to_gauss[0] = RAW_TO_GAUSS_8975(data->asa[0]);
296 data->raw_to_gauss[1] = RAW_TO_GAUSS_8975(data->asa[1]);
297 data->raw_to_gauss[2] = RAW_TO_GAUSS_8975(data->asa[2]);
298 }
299 533
300 return 0; 534 return 0;
301} 535}
@@ -318,7 +552,7 @@ static int wait_conversion_complete_gpio(struct ak8975_data *data)
318 return -EINVAL; 552 return -EINVAL;
319 } 553 }
320 554
321 ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1); 555 ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST1]);
322 if (ret < 0) 556 if (ret < 0)
323 dev_err(&client->dev, "Error in reading ST1\n"); 557 dev_err(&client->dev, "Error in reading ST1\n");
324 558
@@ -335,7 +569,8 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
335 /* Wait for the conversion to complete. */ 569 /* Wait for the conversion to complete. */
336 while (timeout_ms) { 570 while (timeout_ms) {
337 msleep(AK8975_CONVERSION_DONE_POLL_TIME); 571 msleep(AK8975_CONVERSION_DONE_POLL_TIME);
338 ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1); 572 ret = i2c_smbus_read_byte_data(client,
573 data->def->ctrl_regs[ST1]);
339 if (ret < 0) { 574 if (ret < 0) {
340 dev_err(&client->dev, "Error in reading ST1\n"); 575 dev_err(&client->dev, "Error in reading ST1\n");
341 return ret; 576 return ret;
@@ -378,11 +613,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
378 mutex_lock(&data->lock); 613 mutex_lock(&data->lock);
379 614
380 /* Set up the device for taking a sample. */ 615 /* Set up the device for taking a sample. */
381 ret = ak8975_write_data(client, 616 ret = ak8975_set_mode(data, MODE_ONCE);
382 AK8975_REG_CNTL,
383 AK8975_REG_CNTL_MODE_ONCE,
384 AK8975_REG_CNTL_MODE_MASK,
385 AK8975_REG_CNTL_MODE_SHIFT);
386 if (ret < 0) { 617 if (ret < 0) {
387 dev_err(&client->dev, "Error in setting operating mode\n"); 618 dev_err(&client->dev, "Error in setting operating mode\n");
388 goto exit; 619 goto exit;
@@ -399,14 +630,15 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
399 goto exit; 630 goto exit;
400 631
401 /* This will be executed only for non-interrupt based waiting case */ 632 /* This will be executed only for non-interrupt based waiting case */
402 if (ret & AK8975_REG_ST1_DRDY_MASK) { 633 if (ret & data->def->ctrl_masks[ST1_DRDY]) {
403 ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2); 634 ret = i2c_smbus_read_byte_data(client,
635 data->def->ctrl_regs[ST2]);
404 if (ret < 0) { 636 if (ret < 0) {
405 dev_err(&client->dev, "Error in reading ST2\n"); 637 dev_err(&client->dev, "Error in reading ST2\n");
406 goto exit; 638 goto exit;
407 } 639 }
408 if (ret & (AK8975_REG_ST2_DERR_MASK | 640 if (ret & (data->def->ctrl_masks[ST2_DERR] |
409 AK8975_REG_ST2_HOFL_MASK)) { 641 data->def->ctrl_masks[ST2_HOFL])) {
410 dev_err(&client->dev, "ST2 status error 0x%x\n", ret); 642 dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
411 ret = -EINVAL; 643 ret = -EINVAL;
412 goto exit; 644 goto exit;
@@ -415,7 +647,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
415 647
416 /* Read the flux value from the appropriate register 648 /* Read the flux value from the appropriate register
417 (the register is specified in the iio device attributes). */ 649 (the register is specified in the iio device attributes). */
418 ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]); 650 ret = i2c_smbus_read_word_data(client, data->def->data_regs[index]);
419 if (ret < 0) { 651 if (ret < 0) {
420 dev_err(&client->dev, "Read axis data fails\n"); 652 dev_err(&client->dev, "Read axis data fails\n");
421 goto exit; 653 goto exit;
@@ -424,7 +656,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
424 mutex_unlock(&data->lock); 656 mutex_unlock(&data->lock);
425 657
426 /* Clamp to valid range. */ 658 /* Clamp to valid range. */
427 *val = clamp_t(s16, ret, -4096, 4095); 659 *val = clamp_t(s16, ret, -data->def->range, data->def->range);
428 return IIO_VAL_INT; 660 return IIO_VAL_INT;
429 661
430exit: 662exit:
@@ -473,6 +705,8 @@ static const struct acpi_device_id ak_acpi_match[] = {
473 {"AK8975", AK8975}, 705 {"AK8975", AK8975},
474 {"AK8963", AK8963}, 706 {"AK8963", AK8963},
475 {"INVN6500", AK8963}, 707 {"INVN6500", AK8963},
708 {"AK09911", AK09911},
709 {"AK09912", AK09912},
476 { }, 710 { },
477}; 711};
478MODULE_DEVICE_TABLE(acpi, ak_acpi_match); 712MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
@@ -498,6 +732,7 @@ static int ak8975_probe(struct i2c_client *client,
498 int eoc_gpio; 732 int eoc_gpio;
499 int err; 733 int err;
500 const char *name = NULL; 734 const char *name = NULL;
735 enum asahi_compass_chipset chipset;
501 736
502 /* Grab and set up the supplied GPIO. */ 737 /* Grab and set up the supplied GPIO. */
503 if (client->dev.platform_data) 738 if (client->dev.platform_data)
@@ -537,42 +772,50 @@ static int ak8975_probe(struct i2c_client *client,
537 772
538 /* id will be NULL when enumerated via ACPI */ 773 /* id will be NULL when enumerated via ACPI */
539 if (id) { 774 if (id) {
540 data->chipset = 775 chipset = (enum asahi_compass_chipset)(id->driver_data);
541 (enum asahi_compass_chipset)(id->driver_data);
542 name = id->name; 776 name = id->name;
543 } else if (ACPI_HANDLE(&client->dev)) 777 } else if (ACPI_HANDLE(&client->dev))
544 name = ak8975_match_acpi_device(&client->dev, &data->chipset); 778 name = ak8975_match_acpi_device(&client->dev, &chipset);
545 else 779 else
546 return -ENOSYS; 780 return -ENOSYS;
547 781
782 if (chipset >= AK_MAX_TYPE) {
783 dev_err(&client->dev, "AKM device type unsupported: %d\n",
784 chipset);
785 return -ENODEV;
786 }
787
788 data->def = &ak_def_array[chipset];
789 err = ak8975_who_i_am(client, data->def->type);
790 if (err < 0) {
791 dev_err(&client->dev, "Unexpected device\n");
792 return err;
793 }
548 dev_dbg(&client->dev, "Asahi compass chip %s\n", name); 794 dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
549 795
550 /* Perform some basic start-of-day setup of the device. */ 796 /* Perform some basic start-of-day setup of the device. */
551 err = ak8975_setup(client); 797 err = ak8975_setup(client);
552 if (err < 0) { 798 if (err < 0) {
553 dev_err(&client->dev, "AK8975 initialization fails\n"); 799 dev_err(&client->dev, "%s initialization fails\n", name);
554 return err; 800 return err;
555 } 801 }
556 802
557 data->client = client;
558 mutex_init(&data->lock); 803 mutex_init(&data->lock);
559 data->eoc_gpio = eoc_gpio;
560 indio_dev->dev.parent = &client->dev; 804 indio_dev->dev.parent = &client->dev;
561 indio_dev->channels = ak8975_channels; 805 indio_dev->channels = ak8975_channels;
562 indio_dev->num_channels = ARRAY_SIZE(ak8975_channels); 806 indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
563 indio_dev->info = &ak8975_info; 807 indio_dev->info = &ak8975_info;
564 indio_dev->modes = INDIO_DIRECT_MODE; 808 indio_dev->modes = INDIO_DIRECT_MODE;
565 indio_dev->name = name; 809 indio_dev->name = name;
566 err = devm_iio_device_register(&client->dev, indio_dev); 810 return devm_iio_device_register(&client->dev, indio_dev);
567 if (err < 0)
568 return err;
569
570 return 0;
571} 811}
572 812
573static const struct i2c_device_id ak8975_id[] = { 813static const struct i2c_device_id ak8975_id[] = {
574 {"ak8975", AK8975}, 814 {"ak8975", AK8975},
575 {"ak8963", AK8963}, 815 {"ak8963", AK8963},
816 {"AK8963", AK8963},
817 {"ak09911", AK09911},
818 {"ak09912", AK09912},
576 {} 819 {}
577}; 820};
578 821
@@ -581,14 +824,20 @@ MODULE_DEVICE_TABLE(i2c, ak8975_id);
581static const struct of_device_id ak8975_of_match[] = { 824static const struct of_device_id ak8975_of_match[] = {
582 { .compatible = "asahi-kasei,ak8975", }, 825 { .compatible = "asahi-kasei,ak8975", },
583 { .compatible = "ak8975", }, 826 { .compatible = "ak8975", },
584 { } 827 { .compatible = "asahi-kasei,ak8963", },
828 { .compatible = "ak8963", },
829 { .compatible = "asahi-kasei,ak09911", },
830 { .compatible = "ak09911", },
831 { .compatible = "asahi-kasei,ak09912", },
832 { .compatible = "ak09912", },
833 {}
585}; 834};
586MODULE_DEVICE_TABLE(of, ak8975_of_match); 835MODULE_DEVICE_TABLE(of, ak8975_of_match);
587 836
588static struct i2c_driver ak8975_driver = { 837static struct i2c_driver ak8975_driver = {
589 .driver = { 838 .driver = {
590 .name = "ak8975", 839 .name = "ak8975",
591 .of_match_table = ak8975_of_match, 840 .of_match_table = of_match_ptr(ak8975_of_match),
592 .acpi_match_table = ACPI_PTR(ak_acpi_match), 841 .acpi_match_table = ACPI_PTR(ak_acpi_match),
593 }, 842 },
594 .probe = ak8975_probe, 843 .probe = ak8975_probe,
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 6294575d2777..d22993b4066a 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -157,20 +157,12 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
157 int report_id = -1; 157 int report_id = -1;
158 u32 address; 158 u32 address;
159 int ret_type; 159 int ret_type;
160 s32 poll_value;
161 160
162 *val = 0; 161 *val = 0;
163 *val2 = 0; 162 *val2 = 0;
164 switch (mask) { 163 switch (mask) {
165 case 0: 164 case 0:
166 poll_value = hid_sensor_read_poll_value(
167 &magn_state->common_attributes);
168 if (poll_value < 0)
169 return -EINVAL;
170
171 hid_sensor_power_state(&magn_state->common_attributes, true); 165 hid_sensor_power_state(&magn_state->common_attributes, true);
172 msleep_interruptible(poll_value * 2);
173
174 report_id = 166 report_id =
175 magn_state->magn[chan->address].report_id; 167 magn_state->magn[chan->address].report_id;
176 address = magn_3d_addresses[chan->address]; 168 address = magn_3d_addresses[chan->address];
@@ -530,6 +522,7 @@ static struct platform_driver hid_magn_3d_platform_driver = {
530 .id_table = hid_magn_3d_ids, 522 .id_table = hid_magn_3d_ids,
531 .driver = { 523 .driver = {
532 .name = KBUILD_MODNAME, 524 .name = KBUILD_MODNAME,
525 .pm = &hid_sensor_pm_ops,
533 }, 526 },
534 .probe = hid_magn_3d_probe, 527 .probe = hid_magn_3d_probe,
535 .remove = hid_magn_3d_remove, 528 .remove = hid_magn_3d_remove,
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index 1ff181bbbcef..73854460bb2c 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -111,20 +111,12 @@ static int incl_3d_read_raw(struct iio_dev *indio_dev,
111 int report_id = -1; 111 int report_id = -1;
112 u32 address; 112 u32 address;
113 int ret_type; 113 int ret_type;
114 s32 poll_value;
115 114
116 *val = 0; 115 *val = 0;
117 *val2 = 0; 116 *val2 = 0;
118 switch (mask) { 117 switch (mask) {
119 case IIO_CHAN_INFO_RAW: 118 case IIO_CHAN_INFO_RAW:
120 poll_value = hid_sensor_read_poll_value(
121 &incl_state->common_attributes);
122 if (poll_value < 0)
123 return -EINVAL;
124
125 hid_sensor_power_state(&incl_state->common_attributes, true); 119 hid_sensor_power_state(&incl_state->common_attributes, true);
126 msleep_interruptible(poll_value * 2);
127
128 report_id = 120 report_id =
129 incl_state->incl[chan->scan_index].report_id; 121 incl_state->incl[chan->scan_index].report_id;
130 address = incl_3d_addresses[chan->scan_index]; 122 address = incl_3d_addresses[chan->scan_index];
@@ -437,6 +429,7 @@ static struct platform_driver hid_incl_3d_platform_driver = {
437 .id_table = hid_incl_3d_ids, 429 .id_table = hid_incl_3d_ids,
438 .driver = { 430 .driver = {
439 .name = KBUILD_MODNAME, 431 .name = KBUILD_MODNAME,
432 .pm = &hid_sensor_pm_ops,
440 }, 433 },
441 .probe = hid_incl_3d_probe, 434 .probe = hid_incl_3d_probe,
442 .remove = hid_incl_3d_remove, 435 .remove = hid_incl_3d_remove,
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index 75038dacfff1..7c623e2bd633 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -80,16 +80,12 @@ struct bmp280_data {
80 s32 t_fine; 80 s32 t_fine;
81}; 81};
82 82
83/* Compensation parameters. */ 83/*
84struct bmp280_comp_temp { 84 * These enums are used for indexing into the array of compensation
85 u16 dig_t1; 85 * parameters.
86 s16 dig_t2, dig_t3; 86 */
87}; 87enum { T1, T2, T3 };
88 88enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
89struct bmp280_comp_press {
90 u16 dig_p1;
91 s16 dig_p2, dig_p3, dig_p4, dig_p5, dig_p6, dig_p7, dig_p8, dig_p9;
92};
93 89
94static const struct iio_chan_spec bmp280_channels[] = { 90static const struct iio_chan_spec bmp280_channels[] = {
95 { 91 {
@@ -141,54 +137,6 @@ static const struct regmap_config bmp280_regmap_config = {
141 .volatile_reg = bmp280_is_volatile_reg, 137 .volatile_reg = bmp280_is_volatile_reg,
142}; 138};
143 139
144static int bmp280_read_compensation_temp(struct bmp280_data *data,
145 struct bmp280_comp_temp *comp)
146{
147 int ret;
148 __le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
149
150 ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
151 buf, BMP280_COMP_TEMP_REG_COUNT);
152 if (ret < 0) {
153 dev_err(&data->client->dev,
154 "failed to read temperature calibration parameters\n");
155 return ret;
156 }
157
158 comp->dig_t1 = (u16) le16_to_cpu(buf[0]);
159 comp->dig_t2 = (s16) le16_to_cpu(buf[1]);
160 comp->dig_t3 = (s16) le16_to_cpu(buf[2]);
161
162 return 0;
163}
164
165static int bmp280_read_compensation_press(struct bmp280_data *data,
166 struct bmp280_comp_press *comp)
167{
168 int ret;
169 __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
170
171 ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
172 buf, BMP280_COMP_PRESS_REG_COUNT);
173 if (ret < 0) {
174 dev_err(&data->client->dev,
175 "failed to read pressure calibration parameters\n");
176 return ret;
177 }
178
179 comp->dig_p1 = (u16) le16_to_cpu(buf[0]);
180 comp->dig_p2 = (s16) le16_to_cpu(buf[1]);
181 comp->dig_p3 = (s16) le16_to_cpu(buf[2]);
182 comp->dig_p4 = (s16) le16_to_cpu(buf[3]);
183 comp->dig_p5 = (s16) le16_to_cpu(buf[4]);
184 comp->dig_p6 = (s16) le16_to_cpu(buf[5]);
185 comp->dig_p7 = (s16) le16_to_cpu(buf[6]);
186 comp->dig_p8 = (s16) le16_to_cpu(buf[7]);
187 comp->dig_p9 = (s16) le16_to_cpu(buf[8]);
188
189 return 0;
190}
191
192/* 140/*
193 * Returns temperature in DegC, resolution is 0.01 DegC. Output value of 141 * Returns temperature in DegC, resolution is 0.01 DegC. Output value of
194 * "5123" equals 51.23 DegC. t_fine carries fine temperature as global 142 * "5123" equals 51.23 DegC. t_fine carries fine temperature as global
@@ -197,21 +145,35 @@ static int bmp280_read_compensation_press(struct bmp280_data *data,
197 * Taken from datasheet, Section 3.11.3, "Compensation formula". 145 * Taken from datasheet, Section 3.11.3, "Compensation formula".
198 */ 146 */
199static s32 bmp280_compensate_temp(struct bmp280_data *data, 147static s32 bmp280_compensate_temp(struct bmp280_data *data,
200 struct bmp280_comp_temp *comp,
201 s32 adc_temp) 148 s32 adc_temp)
202{ 149{
203 s32 var1, var2, t; 150 int ret;
151 s32 var1, var2;
152 __le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
204 153
205 var1 = (((adc_temp >> 3) - ((s32) comp->dig_t1 << 1)) * 154 ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
206 ((s32) comp->dig_t2)) >> 11; 155 buf, BMP280_COMP_TEMP_REG_COUNT);
207 var2 = (((((adc_temp >> 4) - ((s32) comp->dig_t1)) * 156 if (ret < 0) {
208 ((adc_temp >> 4) - ((s32) comp->dig_t1))) >> 12) * 157 dev_err(&data->client->dev,
209 ((s32) comp->dig_t3)) >> 14; 158 "failed to read temperature calibration parameters\n");
159 return ret;
160 }
210 161
211 data->t_fine = var1 + var2; 162 /*
212 t = (data->t_fine * 5 + 128) >> 8; 163 * The double casts are necessary because le16_to_cpu returns an
164 * unsigned 16-bit value. Casting that value directly to a
165 * signed 32-bit will not do proper sign extension.
166 *
167 * Conversely, T1 and P1 are unsigned values, so they can be
168 * cast straight to the larger type.
169 */
170 var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
171 ((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
172 var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
173 ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
174 ((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
213 175
214 return t; 176 return (data->t_fine * 5 + 128) >> 8;
215} 177}
216 178
217/* 179/*
@@ -222,29 +184,38 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
222 * Taken from datasheet, Section 3.11.3, "Compensation formula". 184 * Taken from datasheet, Section 3.11.3, "Compensation formula".
223 */ 185 */
224static u32 bmp280_compensate_press(struct bmp280_data *data, 186static u32 bmp280_compensate_press(struct bmp280_data *data,
225 struct bmp280_comp_press *comp,
226 s32 adc_press) 187 s32 adc_press)
227{ 188{
189 int ret;
228 s64 var1, var2, p; 190 s64 var1, var2, p;
191 __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
192
193 ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
194 buf, BMP280_COMP_PRESS_REG_COUNT);
195 if (ret < 0) {
196 dev_err(&data->client->dev,
197 "failed to read pressure calibration parameters\n");
198 return ret;
199 }
229 200
230 var1 = ((s64) data->t_fine) - 128000; 201 var1 = ((s64)data->t_fine) - 128000;
231 var2 = var1 * var1 * (s64) comp->dig_p6; 202 var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
232 var2 = var2 + ((var1 * (s64) comp->dig_p5) << 17); 203 var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
233 var2 = var2 + (((s64) comp->dig_p4) << 35); 204 var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
234 var1 = ((var1 * var1 * (s64) comp->dig_p3) >> 8) + 205 var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
235 ((var1 * (s64) comp->dig_p2) << 12); 206 ((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
236 var1 = (((((s64) 1) << 47) + var1)) * ((s64) comp->dig_p1) >> 33; 207 var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33;
237 208
238 if (var1 == 0) 209 if (var1 == 0)
239 return 0; 210 return 0;
240 211
241 p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125; 212 p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
242 p = div64_s64(p, var1); 213 p = div64_s64(p, var1);
243 var1 = (((s64) comp->dig_p9) * (p >> 13) * (p >> 13)) >> 25; 214 var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25;
244 var2 = (((s64) comp->dig_p8) * p) >> 19; 215 var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
245 p = ((p + var1 + var2) >> 8) + (((s64) comp->dig_p7) << 4); 216 p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4);
246 217
247 return (u32) p; 218 return (u32)p;
248} 219}
249 220
250static int bmp280_read_temp(struct bmp280_data *data, 221static int bmp280_read_temp(struct bmp280_data *data,
@@ -253,11 +224,6 @@ static int bmp280_read_temp(struct bmp280_data *data,
253 int ret; 224 int ret;
254 __be32 tmp = 0; 225 __be32 tmp = 0;
255 s32 adc_temp, comp_temp; 226 s32 adc_temp, comp_temp;
256 struct bmp280_comp_temp comp;
257
258 ret = bmp280_read_compensation_temp(data, &comp);
259 if (ret < 0)
260 return ret;
261 227
262 ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, 228 ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
263 (u8 *) &tmp, 3); 229 (u8 *) &tmp, 3);
@@ -267,7 +233,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
267 } 233 }
268 234
269 adc_temp = be32_to_cpu(tmp) >> 12; 235 adc_temp = be32_to_cpu(tmp) >> 12;
270 comp_temp = bmp280_compensate_temp(data, &comp, adc_temp); 236 comp_temp = bmp280_compensate_temp(data, adc_temp);
271 237
272 /* 238 /*
273 * val might be NULL if we're called by the read_press routine, 239 * val might be NULL if we're called by the read_press routine,
@@ -288,11 +254,6 @@ static int bmp280_read_press(struct bmp280_data *data,
288 __be32 tmp = 0; 254 __be32 tmp = 0;
289 s32 adc_press; 255 s32 adc_press;
290 u32 comp_press; 256 u32 comp_press;
291 struct bmp280_comp_press comp;
292
293 ret = bmp280_read_compensation_press(data, &comp);
294 if (ret < 0)
295 return ret;
296 257
297 /* Read and compensate temperature so we get a reading of t_fine. */ 258 /* Read and compensate temperature so we get a reading of t_fine. */
298 ret = bmp280_read_temp(data, NULL); 259 ret = bmp280_read_temp(data, NULL);
@@ -307,7 +268,7 @@ static int bmp280_read_press(struct bmp280_data *data,
307 } 268 }
308 269
309 adc_press = be32_to_cpu(tmp) >> 12; 270 adc_press = be32_to_cpu(tmp) >> 12;
310 comp_press = bmp280_compensate_press(data, &comp, adc_press); 271 comp_press = bmp280_compensate_press(data, adc_press);
311 272
312 *val = comp_press; 273 *val = comp_press;
313 *val2 = 256000; 274 *val2 = 256000;
@@ -366,7 +327,7 @@ static int bmp280_chip_init(struct bmp280_data *data)
366 BMP280_MODE_NORMAL); 327 BMP280_MODE_NORMAL);
367 if (ret < 0) { 328 if (ret < 0) {
368 dev_err(&data->client->dev, 329 dev_err(&data->client->dev,
369 "failed to write config register\n"); 330 "failed to write ctrl_meas register\n");
370 return ret; 331 return ret;
371 } 332 }
372 333
@@ -394,7 +355,6 @@ static int bmp280_probe(struct i2c_client *client,
394 if (!indio_dev) 355 if (!indio_dev)
395 return -ENOMEM; 356 return -ENOMEM;
396 357
397 i2c_set_clientdata(client, indio_dev);
398 data = iio_priv(indio_dev); 358 data = iio_priv(indio_dev);
399 mutex_init(&data->lock); 359 mutex_init(&data->lock);
400 data->client = client; 360 data->client = client;
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 764928682df2..1af314926ebd 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -79,7 +79,6 @@ static int press_read_raw(struct iio_dev *indio_dev,
79 int report_id = -1; 79 int report_id = -1;
80 u32 address; 80 u32 address;
81 int ret_type; 81 int ret_type;
82 s32 poll_value;
83 82
84 *val = 0; 83 *val = 0;
85 *val2 = 0; 84 *val2 = 0;
@@ -96,15 +95,8 @@ static int press_read_raw(struct iio_dev *indio_dev,
96 break; 95 break;
97 } 96 }
98 if (report_id >= 0) { 97 if (report_id >= 0) {
99 poll_value = hid_sensor_read_poll_value(
100 &press_state->common_attributes);
101 if (poll_value < 0)
102 return -EINVAL;
103 hid_sensor_power_state(&press_state->common_attributes, 98 hid_sensor_power_state(&press_state->common_attributes,
104 true); 99 true);
105
106 msleep_interruptible(poll_value * 2);
107
108 *val = sensor_hub_input_attr_get_raw_value( 100 *val = sensor_hub_input_attr_get_raw_value(
109 press_state->common_attributes.hsdev, 101 press_state->common_attributes.hsdev,
110 HID_USAGE_SENSOR_PRESSURE, address, 102 HID_USAGE_SENSOR_PRESSURE, address,
@@ -382,6 +374,7 @@ static struct platform_driver hid_press_platform_driver = {
382 .id_table = hid_press_ids, 374 .id_table = hid_press_ids,
383 .driver = { 375 .driver = {
384 .name = KBUILD_MODNAME, 376 .name = KBUILD_MODNAME,
377 .pm = &hid_sensor_pm_ops,
385 }, 378 },
386 .probe = hid_press_probe, 379 .probe = hid_press_probe,
387 .remove = hid_press_remove, 380 .remove = hid_press_remove,
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index 0c8cdf58f6a1..41a8d8ffa0de 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -17,3 +17,20 @@ config AS3935
17 module will be called as3935 17 module will be called as3935
18 18
19endmenu 19endmenu
20
21menu "Proximity sensors"
22
23config SX9500
24 tristate "SX9500 Semtech proximity sensor"
25 select IIO_BUFFER
26 select IIO_TRIGGERED_BUFFER
27 select REGMAP_I2C
28 depends on I2C
29 help
30 Say Y here to build a driver for Semtech's SX9500 capacitive
31 proximity/button sensor.
32
33 To compile this driver as a module, choose M here: the
34 module will be called sx9500.
35
36endmenu
diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
index 743adee1c8bf..9818dc562abd 100644
--- a/drivers/iio/proximity/Makefile
+++ b/drivers/iio/proximity/Makefile
@@ -4,3 +4,4 @@
4 4
5# When adding new entries keep the list in alphabetical order 5# When adding new entries keep the list in alphabetical order
6obj-$(CONFIG_AS3935) += as3935.o 6obj-$(CONFIG_AS3935) += as3935.o
7obj-$(CONFIG_SX9500) += sx9500.o
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
index 466aa4314667..bc0d68efd455 100644
--- a/drivers/iio/proximity/as3935.c
+++ b/drivers/iio/proximity/as3935.c
@@ -273,9 +273,9 @@ static void calibrate_as3935(struct as3935_state *st)
273} 273}
274 274
275#ifdef CONFIG_PM_SLEEP 275#ifdef CONFIG_PM_SLEEP
276static int as3935_suspend(struct spi_device *spi, pm_message_t msg) 276static int as3935_suspend(struct device *dev)
277{ 277{
278 struct iio_dev *indio_dev = spi_get_drvdata(spi); 278 struct iio_dev *indio_dev = dev_get_drvdata(dev);
279 struct as3935_state *st = iio_priv(indio_dev); 279 struct as3935_state *st = iio_priv(indio_dev);
280 int val, ret; 280 int val, ret;
281 281
@@ -293,9 +293,9 @@ err_suspend:
293 return ret; 293 return ret;
294} 294}
295 295
296static int as3935_resume(struct spi_device *spi) 296static int as3935_resume(struct device *dev)
297{ 297{
298 struct iio_dev *indio_dev = spi_get_drvdata(spi); 298 struct iio_dev *indio_dev = dev_get_drvdata(dev);
299 struct as3935_state *st = iio_priv(indio_dev); 299 struct as3935_state *st = iio_priv(indio_dev);
300 int val, ret; 300 int val, ret;
301 301
@@ -311,9 +311,12 @@ err_resume:
311 311
312 return ret; 312 return ret;
313} 313}
314
315static SIMPLE_DEV_PM_OPS(as3935_pm_ops, as3935_suspend, as3935_resume);
316#define AS3935_PM_OPS (&as3935_pm_ops)
317
314#else 318#else
315#define as3935_suspend NULL 319#define AS3935_PM_OPS NULL
316#define as3935_resume NULL
317#endif 320#endif
318 321
319static int as3935_probe(struct spi_device *spi) 322static int as3935_probe(struct spi_device *spi)
@@ -441,12 +444,11 @@ static struct spi_driver as3935_driver = {
441 .driver = { 444 .driver = {
442 .name = "as3935", 445 .name = "as3935",
443 .owner = THIS_MODULE, 446 .owner = THIS_MODULE,
447 .pm = AS3935_PM_OPS,
444 }, 448 },
445 .probe = as3935_probe, 449 .probe = as3935_probe,
446 .remove = as3935_remove, 450 .remove = as3935_remove,
447 .id_table = as3935_id, 451 .id_table = as3935_id,
448 .suspend = as3935_suspend,
449 .resume = as3935_resume,
450}; 452};
451module_spi_driver(as3935_driver); 453module_spi_driver(as3935_driver);
452 454
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
new file mode 100644
index 000000000000..74dff4e4a11a
--- /dev/null
+++ b/drivers/iio/proximity/sx9500.c
@@ -0,0 +1,752 @@
1/*
2 * Copyright (c) 2014 Intel Corporation
3 *
4 * Driver for Semtech's SX9500 capacitive proximity/button solution.
5 * Datasheet available at
6 * <http://www.semtech.com/images/datasheet/sx9500.pdf>.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/module.h>
16#include <linux/i2c.h>
17#include <linux/irq.h>
18#include <linux/acpi.h>
19#include <linux/gpio/consumer.h>
20#include <linux/regmap.h>
21
22#include <linux/iio/iio.h>
23#include <linux/iio/buffer.h>
24#include <linux/iio/sysfs.h>
25#include <linux/iio/events.h>
26#include <linux/iio/trigger.h>
27#include <linux/iio/triggered_buffer.h>
28#include <linux/iio/trigger_consumer.h>
29
30#define SX9500_DRIVER_NAME "sx9500"
31#define SX9500_IRQ_NAME "sx9500_event"
32#define SX9500_GPIO_NAME "sx9500_gpio"
33
34/* Register definitions. */
35#define SX9500_REG_IRQ_SRC 0x00
36#define SX9500_REG_STAT 0x01
37#define SX9500_REG_IRQ_MSK 0x03
38
39#define SX9500_REG_PROX_CTRL0 0x06
40#define SX9500_REG_PROX_CTRL1 0x07
41#define SX9500_REG_PROX_CTRL2 0x08
42#define SX9500_REG_PROX_CTRL3 0x09
43#define SX9500_REG_PROX_CTRL4 0x0a
44#define SX9500_REG_PROX_CTRL5 0x0b
45#define SX9500_REG_PROX_CTRL6 0x0c
46#define SX9500_REG_PROX_CTRL7 0x0d
47#define SX9500_REG_PROX_CTRL8 0x0e
48
49#define SX9500_REG_SENSOR_SEL 0x20
50#define SX9500_REG_USE_MSB 0x21
51#define SX9500_REG_USE_LSB 0x22
52#define SX9500_REG_AVG_MSB 0x23
53#define SX9500_REG_AVG_LSB 0x24
54#define SX9500_REG_DIFF_MSB 0x25
55#define SX9500_REG_DIFF_LSB 0x26
56#define SX9500_REG_OFFSET_MSB 0x27
57#define SX9500_REG_OFFSET_LSB 0x28
58
59#define SX9500_REG_RESET 0x7f
60
61/* Write this to REG_RESET to do a soft reset. */
62#define SX9500_SOFT_RESET 0xde
63
64#define SX9500_SCAN_PERIOD_MASK GENMASK(6, 4)
65#define SX9500_SCAN_PERIOD_SHIFT 4
66
67/*
68 * These serve for identifying IRQ source in the IRQ_SRC register, and
69 * also for masking the IRQs in the IRQ_MSK register.
70 */
71#define SX9500_CLOSE_IRQ BIT(6)
72#define SX9500_FAR_IRQ BIT(5)
73#define SX9500_CONVDONE_IRQ BIT(3)
74
75#define SX9500_PROXSTAT_SHIFT 4
76
77#define SX9500_NUM_CHANNELS 4
78
79struct sx9500_data {
80 struct mutex mutex;
81 struct i2c_client *client;
82 struct iio_trigger *trig;
83 struct regmap *regmap;
84 /*
85 * Last reading of the proximity status for each channel. We
86 * only send an event to user space when this changes.
87 */
88 bool prox_stat[SX9500_NUM_CHANNELS];
89 bool event_enabled[SX9500_NUM_CHANNELS];
90 bool trigger_enabled;
91 u16 *buffer;
92};
93
94static const struct iio_event_spec sx9500_events[] = {
95 {
96 .type = IIO_EV_TYPE_THRESH,
97 .dir = IIO_EV_DIR_EITHER,
98 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
99 },
100};
101
102#define SX9500_CHANNEL(idx) \
103 { \
104 .type = IIO_PROXIMITY, \
105 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
106 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
107 .indexed = 1, \
108 .channel = idx, \
109 .event_spec = sx9500_events, \
110 .num_event_specs = ARRAY_SIZE(sx9500_events), \
111 .scan_index = idx, \
112 .scan_type = { \
113 .sign = 'u', \
114 .realbits = 16, \
115 .storagebits = 16, \
116 .shift = 0, \
117 }, \
118 }
119
120static const struct iio_chan_spec sx9500_channels[] = {
121 SX9500_CHANNEL(0),
122 SX9500_CHANNEL(1),
123 SX9500_CHANNEL(2),
124 SX9500_CHANNEL(3),
125 IIO_CHAN_SOFT_TIMESTAMP(4),
126};
127
128static const struct {
129 int val;
130 int val2;
131} sx9500_samp_freq_table[] = {
132 {33, 333333},
133 {16, 666666},
134 {11, 111111},
135 {8, 333333},
136 {6, 666666},
137 {5, 0},
138 {3, 333333},
139 {2, 500000},
140};
141
142static const struct regmap_range sx9500_writable_reg_ranges[] = {
143 regmap_reg_range(SX9500_REG_IRQ_MSK, SX9500_REG_IRQ_MSK),
144 regmap_reg_range(SX9500_REG_PROX_CTRL0, SX9500_REG_PROX_CTRL8),
145 regmap_reg_range(SX9500_REG_SENSOR_SEL, SX9500_REG_SENSOR_SEL),
146 regmap_reg_range(SX9500_REG_OFFSET_MSB, SX9500_REG_OFFSET_LSB),
147 regmap_reg_range(SX9500_REG_RESET, SX9500_REG_RESET),
148};
149
150static const struct regmap_access_table sx9500_writeable_regs = {
151 .yes_ranges = sx9500_writable_reg_ranges,
152 .n_yes_ranges = ARRAY_SIZE(sx9500_writable_reg_ranges),
153};
154
155/*
156 * All allocated registers are readable, so we just list unallocated
157 * ones.
158 */
159static const struct regmap_range sx9500_non_readable_reg_ranges[] = {
160 regmap_reg_range(SX9500_REG_STAT + 1, SX9500_REG_STAT + 1),
161 regmap_reg_range(SX9500_REG_IRQ_MSK + 1, SX9500_REG_PROX_CTRL0 - 1),
162 regmap_reg_range(SX9500_REG_PROX_CTRL8 + 1, SX9500_REG_SENSOR_SEL - 1),
163 regmap_reg_range(SX9500_REG_OFFSET_LSB + 1, SX9500_REG_RESET - 1),
164};
165
166static const struct regmap_access_table sx9500_readable_regs = {
167 .no_ranges = sx9500_non_readable_reg_ranges,
168 .n_no_ranges = ARRAY_SIZE(sx9500_non_readable_reg_ranges),
169};
170
171static const struct regmap_range sx9500_volatile_reg_ranges[] = {
172 regmap_reg_range(SX9500_REG_IRQ_SRC, SX9500_REG_STAT),
173 regmap_reg_range(SX9500_REG_USE_MSB, SX9500_REG_OFFSET_LSB),
174 regmap_reg_range(SX9500_REG_RESET, SX9500_REG_RESET),
175};
176
177static const struct regmap_access_table sx9500_volatile_regs = {
178 .yes_ranges = sx9500_volatile_reg_ranges,
179 .n_yes_ranges = ARRAY_SIZE(sx9500_volatile_reg_ranges),
180};
181
182static const struct regmap_config sx9500_regmap_config = {
183 .reg_bits = 8,
184 .val_bits = 8,
185
186 .max_register = SX9500_REG_RESET,
187 .cache_type = REGCACHE_RBTREE,
188
189 .wr_table = &sx9500_writeable_regs,
190 .rd_table = &sx9500_readable_regs,
191 .volatile_table = &sx9500_volatile_regs,
192};
193
194static int sx9500_read_proximity(struct sx9500_data *data,
195 const struct iio_chan_spec *chan,
196 int *val)
197{
198 int ret;
199 __be16 regval;
200
201 ret = regmap_write(data->regmap, SX9500_REG_SENSOR_SEL, chan->channel);
202 if (ret < 0)
203 return ret;
204
205 ret = regmap_bulk_read(data->regmap, SX9500_REG_USE_MSB, &regval, 2);
206 if (ret < 0)
207 return ret;
208
209 *val = 32767 - (s16)be16_to_cpu(regval);
210
211 return IIO_VAL_INT;
212}
213
214static int sx9500_read_samp_freq(struct sx9500_data *data,
215 int *val, int *val2)
216{
217 int ret;
218 unsigned int regval;
219
220 mutex_lock(&data->mutex);
221 ret = regmap_read(data->regmap, SX9500_REG_PROX_CTRL0, &regval);
222 mutex_unlock(&data->mutex);
223
224 if (ret < 0)
225 return ret;
226
227 regval = (regval & SX9500_SCAN_PERIOD_MASK) >> SX9500_SCAN_PERIOD_SHIFT;
228 *val = sx9500_samp_freq_table[regval].val;
229 *val2 = sx9500_samp_freq_table[regval].val2;
230
231 return IIO_VAL_INT_PLUS_MICRO;
232}
233
234static int sx9500_read_raw(struct iio_dev *indio_dev,
235 const struct iio_chan_spec *chan,
236 int *val, int *val2, long mask)
237{
238 struct sx9500_data *data = iio_priv(indio_dev);
239 int ret;
240
241 switch (chan->type) {
242 case IIO_PROXIMITY:
243 switch (mask) {
244 case IIO_CHAN_INFO_RAW:
245 if (iio_buffer_enabled(indio_dev))
246 return -EBUSY;
247 mutex_lock(&data->mutex);
248 ret = sx9500_read_proximity(data, chan, val);
249 mutex_unlock(&data->mutex);
250 return ret;
251 case IIO_CHAN_INFO_SAMP_FREQ:
252 return sx9500_read_samp_freq(data, val, val2);
253 default:
254 return -EINVAL;
255 }
256 default:
257 return -EINVAL;
258 }
259}
260
261static int sx9500_set_samp_freq(struct sx9500_data *data,
262 int val, int val2)
263{
264 int i, ret;
265
266 for (i = 0; i < ARRAY_SIZE(sx9500_samp_freq_table); i++)
267 if (val == sx9500_samp_freq_table[i].val &&
268 val2 == sx9500_samp_freq_table[i].val2)
269 break;
270
271 if (i == ARRAY_SIZE(sx9500_samp_freq_table))
272 return -EINVAL;
273
274 mutex_lock(&data->mutex);
275
276 ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
277 SX9500_SCAN_PERIOD_MASK,
278 i << SX9500_SCAN_PERIOD_SHIFT);
279
280 mutex_unlock(&data->mutex);
281
282 return ret;
283}
284
285static int sx9500_write_raw(struct iio_dev *indio_dev,
286 const struct iio_chan_spec *chan,
287 int val, int val2, long mask)
288{
289 struct sx9500_data *data = iio_priv(indio_dev);
290
291 switch (chan->type) {
292 case IIO_PROXIMITY:
293 switch (mask) {
294 case IIO_CHAN_INFO_SAMP_FREQ:
295 return sx9500_set_samp_freq(data, val, val2);
296 default:
297 return -EINVAL;
298 }
299 default:
300 return -EINVAL;
301 }
302}
303
304static irqreturn_t sx9500_irq_handler(int irq, void *private)
305{
306 struct iio_dev *indio_dev = private;
307 struct sx9500_data *data = iio_priv(indio_dev);
308
309 if (data->trigger_enabled)
310 iio_trigger_poll(data->trig);
311
312 /*
313 * Even if no event is enabled, we need to wake the thread to
314 * clear the interrupt state by reading SX9500_REG_IRQ_SRC. It
315 * is not possible to do that here because regmap_read takes a
316 * mutex.
317 */
318 return IRQ_WAKE_THREAD;
319}
320
321static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
322{
323 struct iio_dev *indio_dev = private;
324 struct sx9500_data *data = iio_priv(indio_dev);
325 int ret;
326 unsigned int val, chan;
327
328 mutex_lock(&data->mutex);
329
330 ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
331 if (ret < 0) {
332 dev_err(&data->client->dev, "i2c transfer error in irq\n");
333 goto out;
334 }
335
336 if (!(val & (SX9500_CLOSE_IRQ | SX9500_FAR_IRQ)))
337 goto out;
338
339 ret = regmap_read(data->regmap, SX9500_REG_STAT, &val);
340 if (ret < 0) {
341 dev_err(&data->client->dev, "i2c transfer error in irq\n");
342 goto out;
343 }
344
345 val >>= SX9500_PROXSTAT_SHIFT;
346 for (chan = 0; chan < SX9500_NUM_CHANNELS; chan++) {
347 int dir;
348 u64 ev;
349 bool new_prox = val & BIT(chan);
350
351 if (!data->event_enabled[chan])
352 continue;
353 if (new_prox == data->prox_stat[chan])
354 /* No change on this channel. */
355 continue;
356
357 dir = new_prox ? IIO_EV_DIR_FALLING :
358 IIO_EV_DIR_RISING;
359 ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
360 chan,
361 IIO_EV_TYPE_THRESH,
362 dir);
363 iio_push_event(indio_dev, ev, iio_get_time_ns());
364 data->prox_stat[chan] = new_prox;
365 }
366
367out:
368 mutex_unlock(&data->mutex);
369
370 return IRQ_HANDLED;
371}
372
373static int sx9500_read_event_config(struct iio_dev *indio_dev,
374 const struct iio_chan_spec *chan,
375 enum iio_event_type type,
376 enum iio_event_direction dir)
377{
378 struct sx9500_data *data = iio_priv(indio_dev);
379
380 if (chan->type != IIO_PROXIMITY || type != IIO_EV_TYPE_THRESH ||
381 dir != IIO_EV_DIR_EITHER)
382 return -EINVAL;
383
384 return data->event_enabled[chan->channel];
385}
386
387static int sx9500_write_event_config(struct iio_dev *indio_dev,
388 const struct iio_chan_spec *chan,
389 enum iio_event_type type,
390 enum iio_event_direction dir,
391 int state)
392{
393 struct sx9500_data *data = iio_priv(indio_dev);
394 int ret, i;
395 bool any_active = false;
396 unsigned int irqmask;
397
398 if (chan->type != IIO_PROXIMITY || type != IIO_EV_TYPE_THRESH ||
399 dir != IIO_EV_DIR_EITHER)
400 return -EINVAL;
401
402 mutex_lock(&data->mutex);
403
404 data->event_enabled[chan->channel] = state;
405
406 for (i = 0; i < SX9500_NUM_CHANNELS; i++)
407 if (data->event_enabled[i]) {
408 any_active = true;
409 break;
410 }
411
412 irqmask = SX9500_CLOSE_IRQ | SX9500_FAR_IRQ;
413 if (any_active)
414 ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
415 irqmask, irqmask);
416 else
417 ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
418 irqmask, 0);
419
420 mutex_unlock(&data->mutex);
421
422 return ret;
423}
424
425static int sx9500_update_scan_mode(struct iio_dev *indio_dev,
426 const unsigned long *scan_mask)
427{
428 struct sx9500_data *data = iio_priv(indio_dev);
429
430 mutex_lock(&data->mutex);
431 kfree(data->buffer);
432 data->buffer = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
433 mutex_unlock(&data->mutex);
434
435 if (data->buffer == NULL)
436 return -ENOMEM;
437
438 return 0;
439}
440
441static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
442 "2.500000 3.333333 5 6.666666 8.333333 11.111111 16.666666 33.333333");
443
444static struct attribute *sx9500_attributes[] = {
445 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
446 NULL,
447};
448
449static const struct attribute_group sx9500_attribute_group = {
450 .attrs = sx9500_attributes,
451};
452
453static const struct iio_info sx9500_info = {
454 .driver_module = THIS_MODULE,
455 .attrs = &sx9500_attribute_group,
456 .read_raw = &sx9500_read_raw,
457 .write_raw = &sx9500_write_raw,
458 .read_event_config = &sx9500_read_event_config,
459 .write_event_config = &sx9500_write_event_config,
460 .update_scan_mode = &sx9500_update_scan_mode,
461};
462
463static int sx9500_set_trigger_state(struct iio_trigger *trig,
464 bool state)
465{
466 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
467 struct sx9500_data *data = iio_priv(indio_dev);
468 int ret;
469
470 mutex_lock(&data->mutex);
471
472 ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
473 SX9500_CONVDONE_IRQ,
474 state ? SX9500_CONVDONE_IRQ : 0);
475 if (ret == 0)
476 data->trigger_enabled = state;
477
478 mutex_unlock(&data->mutex);
479
480 return ret;
481}
482
483static const struct iio_trigger_ops sx9500_trigger_ops = {
484 .set_trigger_state = sx9500_set_trigger_state,
485 .owner = THIS_MODULE,
486};
487
488static irqreturn_t sx9500_trigger_handler(int irq, void *private)
489{
490 struct iio_poll_func *pf = private;
491 struct iio_dev *indio_dev = pf->indio_dev;
492 struct sx9500_data *data = iio_priv(indio_dev);
493 int val, bit, ret, i = 0;
494
495 mutex_lock(&data->mutex);
496
497 for_each_set_bit(bit, indio_dev->buffer->scan_mask,
498 indio_dev->masklength) {
499 ret = sx9500_read_proximity(data, &indio_dev->channels[bit],
500 &val);
501 if (ret < 0)
502 goto out;
503
504 data->buffer[i++] = val;
505 }
506
507 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
508 iio_get_time_ns());
509
510out:
511 mutex_unlock(&data->mutex);
512
513 iio_trigger_notify_done(indio_dev->trig);
514
515 return IRQ_HANDLED;
516}
517
518struct sx9500_reg_default {
519 u8 reg;
520 u8 def;
521};
522
523static const struct sx9500_reg_default sx9500_default_regs[] = {
524 {
525 .reg = SX9500_REG_PROX_CTRL1,
526 /* Shield enabled, small range. */
527 .def = 0x43,
528 },
529 {
530 .reg = SX9500_REG_PROX_CTRL2,
531 /* x8 gain, 167kHz frequency, finest resolution. */
532 .def = 0x77,
533 },
534 {
535 .reg = SX9500_REG_PROX_CTRL3,
536 /* Doze enabled, 2x scan period doze, no raw filter. */
537 .def = 0x40,
538 },
539 {
540 .reg = SX9500_REG_PROX_CTRL4,
541 /* Average threshold. */
542 .def = 0x30,
543 },
544 {
545 .reg = SX9500_REG_PROX_CTRL5,
546 /*
547 * Debouncer off, lowest average negative filter,
548 * highest average postive filter.
549 */
550 .def = 0x0f,
551 },
552 {
553 .reg = SX9500_REG_PROX_CTRL6,
554 /* Proximity detection threshold: 280 */
555 .def = 0x0e,
556 },
557 {
558 .reg = SX9500_REG_PROX_CTRL7,
559 /*
560 * No automatic compensation, compensate each pin
561 * independently, proximity hysteresis: 32, close
562 * debouncer off, far debouncer off.
563 */
564 .def = 0x00,
565 },
566 {
567 .reg = SX9500_REG_PROX_CTRL8,
568 /* No stuck timeout, no periodic compensation. */
569 .def = 0x00,
570 },
571 {
572 .reg = SX9500_REG_PROX_CTRL0,
573 /* Scan period: 30ms, all sensors enabled. */
574 .def = 0x0f,
575 },
576};
577
578static int sx9500_init_device(struct iio_dev *indio_dev)
579{
580 struct sx9500_data *data = iio_priv(indio_dev);
581 int ret, i;
582 unsigned int val;
583
584 ret = regmap_write(data->regmap, SX9500_REG_IRQ_MSK, 0);
585 if (ret < 0)
586 return ret;
587
588 ret = regmap_write(data->regmap, SX9500_REG_RESET,
589 SX9500_SOFT_RESET);
590 if (ret < 0)
591 return ret;
592
593 ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
594 if (ret < 0)
595 return ret;
596
597 for (i = 0; i < ARRAY_SIZE(sx9500_default_regs); i++) {
598 ret = regmap_write(data->regmap,
599 sx9500_default_regs[i].reg,
600 sx9500_default_regs[i].def);
601 if (ret < 0)
602 return ret;
603 }
604
605 return 0;
606}
607
608static int sx9500_gpio_probe(struct i2c_client *client,
609 struct sx9500_data *data)
610{
611 struct device *dev;
612 struct gpio_desc *gpio;
613 int ret;
614
615 if (!client)
616 return -EINVAL;
617
618 dev = &client->dev;
619
620 /* data ready gpio interrupt pin */
621 gpio = devm_gpiod_get_index(dev, SX9500_GPIO_NAME, 0);
622 if (IS_ERR(gpio)) {
623 dev_err(dev, "acpi gpio get index failed\n");
624 return PTR_ERR(gpio);
625 }
626
627 ret = gpiod_direction_input(gpio);
628 if (ret)
629 return ret;
630
631 ret = gpiod_to_irq(gpio);
632
633 dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
634
635 return ret;
636}
637
638static int sx9500_probe(struct i2c_client *client,
639 const struct i2c_device_id *id)
640{
641 int ret;
642 struct iio_dev *indio_dev;
643 struct sx9500_data *data;
644
645 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
646 if (indio_dev == NULL)
647 return -ENOMEM;
648
649 data = iio_priv(indio_dev);
650 data->client = client;
651 mutex_init(&data->mutex);
652 data->trigger_enabled = false;
653
654 data->regmap = devm_regmap_init_i2c(client, &sx9500_regmap_config);
655 if (IS_ERR(data->regmap))
656 return PTR_ERR(data->regmap);
657
658 sx9500_init_device(indio_dev);
659
660 indio_dev->dev.parent = &client->dev;
661 indio_dev->name = SX9500_DRIVER_NAME;
662 indio_dev->channels = sx9500_channels;
663 indio_dev->num_channels = ARRAY_SIZE(sx9500_channels);
664 indio_dev->info = &sx9500_info;
665 indio_dev->modes = INDIO_DIRECT_MODE;
666 i2c_set_clientdata(client, indio_dev);
667
668 if (client->irq <= 0)
669 client->irq = sx9500_gpio_probe(client, data);
670
671 if (client->irq > 0) {
672 ret = devm_request_threaded_irq(&client->dev, client->irq,
673 sx9500_irq_handler, sx9500_irq_thread_handler,
674 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
675 SX9500_IRQ_NAME, indio_dev);
676 if (ret < 0)
677 return ret;
678
679 data->trig = devm_iio_trigger_alloc(&client->dev,
680 "%s-dev%d", indio_dev->name, indio_dev->id);
681 if (!data->trig)
682 return -ENOMEM;
683
684 data->trig->dev.parent = &client->dev;
685 data->trig->ops = &sx9500_trigger_ops;
686 iio_trigger_set_drvdata(data->trig, indio_dev);
687
688 ret = iio_trigger_register(data->trig);
689 if (ret)
690 return ret;
691 }
692
693 ret = iio_triggered_buffer_setup(indio_dev, NULL,
694 sx9500_trigger_handler, NULL);
695 if (ret < 0)
696 goto out_trigger_unregister;
697
698 ret = iio_device_register(indio_dev);
699 if (ret < 0)
700 goto out_buffer_cleanup;
701
702 return 0;
703
704out_buffer_cleanup:
705 iio_triggered_buffer_cleanup(indio_dev);
706out_trigger_unregister:
707 if (client->irq > 0)
708 iio_trigger_unregister(data->trig);
709
710 return ret;
711}
712
713static int sx9500_remove(struct i2c_client *client)
714{
715 struct iio_dev *indio_dev = i2c_get_clientdata(client);
716 struct sx9500_data *data = iio_priv(indio_dev);
717
718 iio_device_unregister(indio_dev);
719 iio_triggered_buffer_cleanup(indio_dev);
720 if (client->irq > 0)
721 iio_trigger_unregister(data->trig);
722 kfree(data->buffer);
723
724 return 0;
725}
726
727static const struct acpi_device_id sx9500_acpi_match[] = {
728 {"SSX9500", 0},
729 { },
730};
731MODULE_DEVICE_TABLE(acpi, sx9500_acpi_match);
732
733static const struct i2c_device_id sx9500_id[] = {
734 {"sx9500", 0},
735 {}
736};
737MODULE_DEVICE_TABLE(i2c, sx9500_id);
738
739static struct i2c_driver sx9500_driver = {
740 .driver = {
741 .name = SX9500_DRIVER_NAME,
742 .acpi_match_table = ACPI_PTR(sx9500_acpi_match),
743 },
744 .probe = sx9500_probe,
745 .remove = sx9500_remove,
746 .id_table = sx9500_id,
747};
748module_i2c_driver(sx9500_driver);
749
750MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
751MODULE_DESCRIPTION("Driver for Semtech SX9500 proximity sensor");
752MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c
index 254c7e906127..3dfab2bc6d69 100644
--- a/drivers/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/iio/trigger/iio-trig-sysfs.c
@@ -135,6 +135,7 @@ static int iio_sysfs_trigger_probe(int id)
135 struct iio_sysfs_trig *t; 135 struct iio_sysfs_trig *t;
136 int ret; 136 int ret;
137 bool foundit = false; 137 bool foundit = false;
138
138 mutex_lock(&iio_sysfs_trig_list_mut); 139 mutex_lock(&iio_sysfs_trig_list_mut);
139 list_for_each_entry(t, &iio_sysfs_trig_list, l) 140 list_for_each_entry(t, &iio_sysfs_trig_list, l)
140 if (id == t->id) { 141 if (id == t->id) {
@@ -185,6 +186,7 @@ static int iio_sysfs_trigger_remove(int id)
185{ 186{
186 bool foundit = false; 187 bool foundit = false;
187 struct iio_sysfs_trig *t; 188 struct iio_sysfs_trig *t;
189
188 mutex_lock(&iio_sysfs_trig_list_mut); 190 mutex_lock(&iio_sysfs_trig_list_mut);
189 list_for_each_entry(t, &iio_sysfs_trig_list, l) 191 list_for_each_entry(t, &iio_sysfs_trig_list, l)
190 if (id == t->id) { 192 if (id == t->id) {
diff --git a/drivers/message/Makefile b/drivers/message/Makefile
index 97ef5a01ad11..755676ded67c 100644
--- a/drivers/message/Makefile
+++ b/drivers/message/Makefile
@@ -2,5 +2,4 @@
2# Makefile for MPT based block devices 2# Makefile for MPT based block devices
3# 3#
4 4
5obj-$(CONFIG_I2O) += i2o/
6obj-$(CONFIG_FUSION) += fusion/ 5obj-$(CONFIG_FUSION) += fusion/
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 9049dd91b569..45baa83be7ce 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -56,6 +56,8 @@ source "drivers/staging/vt6656/Kconfig"
56 56
57source "drivers/staging/iio/Kconfig" 57source "drivers/staging/iio/Kconfig"
58 58
59source "drivers/staging/sm7xxfb/Kconfig"
60
59source "drivers/staging/xgifb/Kconfig" 61source "drivers/staging/xgifb/Kconfig"
60 62
61source "drivers/staging/emxx_udc/Kconfig" 63source "drivers/staging/emxx_udc/Kconfig"
@@ -64,8 +66,6 @@ source "drivers/staging/ft1000/Kconfig"
64 66
65source "drivers/staging/speakup/Kconfig" 67source "drivers/staging/speakup/Kconfig"
66 68
67source "drivers/staging/cptm1217/Kconfig"
68
69source "drivers/staging/ste_rmi4/Kconfig" 69source "drivers/staging/ste_rmi4/Kconfig"
70 70
71source "drivers/staging/nvec/Kconfig" 71source "drivers/staging/nvec/Kconfig"
@@ -104,4 +104,8 @@ source "drivers/staging/unisys/Kconfig"
104 104
105source "drivers/staging/clocking-wizard/Kconfig" 105source "drivers/staging/clocking-wizard/Kconfig"
106 106
107source "drivers/staging/fbtft/Kconfig"
108
109source "drivers/staging/i2o/Kconfig"
110
107endif # STAGING 111endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index fe26ff162b42..29160790841f 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -22,11 +22,11 @@ obj-$(CONFIG_VT6655) += vt6655/
22obj-$(CONFIG_VT6656) += vt6656/ 22obj-$(CONFIG_VT6656) += vt6656/
23obj-$(CONFIG_VME_BUS) += vme/ 23obj-$(CONFIG_VME_BUS) += vme/
24obj-$(CONFIG_IIO) += iio/ 24obj-$(CONFIG_IIO) += iio/
25obj-$(CONFIG_FB_SM7XX) += sm7xxfb/
25obj-$(CONFIG_FB_XGI) += xgifb/ 26obj-$(CONFIG_FB_XGI) += xgifb/
26obj-$(CONFIG_USB_EMXX) += emxx_udc/ 27obj-$(CONFIG_USB_EMXX) += emxx_udc/
27obj-$(CONFIG_FT1000) += ft1000/ 28obj-$(CONFIG_FT1000) += ft1000/
28obj-$(CONFIG_SPEAKUP) += speakup/ 29obj-$(CONFIG_SPEAKUP) += speakup/
29obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
30obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ 30obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
31obj-$(CONFIG_MFD_NVEC) += nvec/ 31obj-$(CONFIG_MFD_NVEC) += nvec/
32obj-$(CONFIG_ANDROID) += android/ 32obj-$(CONFIG_ANDROID) += android/
@@ -44,3 +44,5 @@ obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/
44obj-$(CONFIG_CRYPTO_SKEIN) += skein/ 44obj-$(CONFIG_CRYPTO_SKEIN) += skein/
45obj-$(CONFIG_UNISYSSPAR) += unisys/ 45obj-$(CONFIG_UNISYSSPAR) += unisys/
46obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ 46obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
47obj-$(CONFIG_FB_TFT) += fbtft/
48obj-$(CONFIG_I2O) += i2o/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 7e012f37792b..8feb9048e62f 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -14,23 +14,6 @@ config ASHMEM
14 It is, in theory, a good memory allocator for low-memory devices, 14 It is, in theory, a good memory allocator for low-memory devices,
15 because it can discard shared memory units when under memory pressure. 15 because it can discard shared memory units when under memory pressure.
16 16
17config ANDROID_LOGGER
18 tristate "Android log driver"
19 default n
20 ---help---
21 This adds support for system-wide logging using four log buffers.
22
23 These are:
24
25 1: main
26 2: events
27 3: radio
28 4: system
29
30 Log reading and writing is performed via normal Linux reads and
31 optimized writes. This optimization avoids logging having too
32 much overhead in the system.
33
34config ANDROID_TIMED_OUTPUT 17config ANDROID_TIMED_OUTPUT
35 bool "Timed output class driver" 18 bool "Timed output class driver"
36 default y 19 default y
@@ -45,15 +28,6 @@ config ANDROID_LOW_MEMORY_KILLER
45 ---help--- 28 ---help---
46 Registers processes to be killed when memory is low 29 Registers processes to be killed when memory is low
47 30
48config ANDROID_INTF_ALARM_DEV
49 tristate "Android alarm driver"
50 depends on RTC_CLASS
51 default n
52 ---help---
53 Provides non-wakeup and rtc backed wakeup alarms based on rtc or
54 elapsed realtime, and a non-wakeup alarm on the monotonic clock.
55 Also exports the alarm interface to user-space.
56
57config SYNC 31config SYNC
58 bool "Synchronization framework" 32 bool "Synchronization framework"
59 default n 33 default n
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 479b2b86f8c8..c7b6c99cc5ce 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -3,10 +3,8 @@ ccflags-y += -I$(src) # needed for trace events
3obj-y += ion/ 3obj-y += ion/
4 4
5obj-$(CONFIG_ASHMEM) += ashmem.o 5obj-$(CONFIG_ASHMEM) += ashmem.o
6obj-$(CONFIG_ANDROID_LOGGER) += logger.o
7obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o 6obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o
8obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o 7obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
9obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o 8obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
10obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
11obj-$(CONFIG_SYNC) += sync.o sync_debug.o 9obj-$(CONFIG_SYNC) += sync.o sync_debug.o
12obj-$(CONFIG_SW_SYNC) += sw_sync.o 10obj-$(CONFIG_SW_SYNC) += sw_sync.o
diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c
deleted file mode 100644
index ff4b3e8758a7..000000000000
--- a/drivers/staging/android/alarm-dev.c
+++ /dev/null
@@ -1,446 +0,0 @@
1/* drivers/rtc/alarm-dev.c
2 *
3 * Copyright (C) 2007-2009 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/time.h>
17#include <linux/module.h>
18#include <linux/device.h>
19#include <linux/miscdevice.h>
20#include <linux/fs.h>
21#include <linux/platform_device.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/uaccess.h>
25#include <linux/alarmtimer.h>
26#include "android_alarm.h"
27
28#define ANDROID_ALARM_PRINT_INFO (1U << 0)
29#define ANDROID_ALARM_PRINT_IO (1U << 1)
30#define ANDROID_ALARM_PRINT_INT (1U << 2)
31
32static int debug_mask = ANDROID_ALARM_PRINT_INFO;
33module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
34
35#define alarm_dbg(debug_level_mask, fmt, ...) \
36do { \
37 if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) \
38 pr_info(fmt, ##__VA_ARGS__); \
39} while (0)
40
41#define ANDROID_ALARM_WAKEUP_MASK ( \
42 ANDROID_ALARM_RTC_WAKEUP_MASK | \
43 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
44
45static int alarm_opened;
46static DEFINE_SPINLOCK(alarm_slock);
47static struct wakeup_source alarm_wake_lock;
48static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
49static uint32_t alarm_pending;
50static uint32_t alarm_enabled;
51static uint32_t wait_pending;
52
53struct devalarm {
54 union {
55 struct hrtimer hrt;
56 struct alarm alrm;
57 } u;
58 enum android_alarm_type type;
59};
60
61static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
62
63/**
64 * is_wakeup() - Checks to see if this alarm can wake the device
65 * @type: The type of alarm being checked
66 *
67 * Return: 1 if this is a wakeup alarm, otherwise 0
68 */
69static int is_wakeup(enum android_alarm_type type)
70{
71 return type == ANDROID_ALARM_RTC_WAKEUP ||
72 type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP;
73}
74
75static void devalarm_start(struct devalarm *alrm, ktime_t exp)
76{
77 if (is_wakeup(alrm->type))
78 alarm_start(&alrm->u.alrm, exp);
79 else
80 hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
81}
82
83static int devalarm_try_to_cancel(struct devalarm *alrm)
84{
85 if (is_wakeup(alrm->type))
86 return alarm_try_to_cancel(&alrm->u.alrm);
87 return hrtimer_try_to_cancel(&alrm->u.hrt);
88}
89
90static void devalarm_cancel(struct devalarm *alrm)
91{
92 if (is_wakeup(alrm->type))
93 alarm_cancel(&alrm->u.alrm);
94 else
95 hrtimer_cancel(&alrm->u.hrt);
96}
97
98static void alarm_clear(enum android_alarm_type alarm_type)
99{
100 uint32_t alarm_type_mask = 1U << alarm_type;
101 unsigned long flags;
102
103 spin_lock_irqsave(&alarm_slock, flags);
104 alarm_dbg(IO, "alarm %d clear\n", alarm_type);
105 devalarm_try_to_cancel(&alarms[alarm_type]);
106 if (alarm_pending) {
107 alarm_pending &= ~alarm_type_mask;
108 if (!alarm_pending && !wait_pending)
109 __pm_relax(&alarm_wake_lock);
110 }
111 alarm_enabled &= ~alarm_type_mask;
112 spin_unlock_irqrestore(&alarm_slock, flags);
113}
114
115static void alarm_set(enum android_alarm_type alarm_type,
116 struct timespec *ts)
117{
118 uint32_t alarm_type_mask = 1U << alarm_type;
119 unsigned long flags;
120
121 spin_lock_irqsave(&alarm_slock, flags);
122 alarm_dbg(IO, "alarm %d set %ld.%09ld\n",
123 alarm_type, ts->tv_sec, ts->tv_nsec);
124 alarm_enabled |= alarm_type_mask;
125 devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
126 spin_unlock_irqrestore(&alarm_slock, flags);
127}
128
129static int alarm_wait(void)
130{
131 unsigned long flags;
132 int rv = 0;
133
134 spin_lock_irqsave(&alarm_slock, flags);
135 alarm_dbg(IO, "alarm wait\n");
136 if (!alarm_pending && wait_pending) {
137 __pm_relax(&alarm_wake_lock);
138 wait_pending = 0;
139 }
140 spin_unlock_irqrestore(&alarm_slock, flags);
141
142 rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
143 if (rv)
144 return rv;
145
146 spin_lock_irqsave(&alarm_slock, flags);
147 rv = alarm_pending;
148 wait_pending = 1;
149 alarm_pending = 0;
150 spin_unlock_irqrestore(&alarm_slock, flags);
151
152 return rv;
153}
154
155static int alarm_set_rtc(struct timespec *ts)
156{
157 struct rtc_time new_rtc_tm;
158 struct rtc_device *rtc_dev;
159 unsigned long flags;
160 int rv = 0;
161
162 rtc_time_to_tm(ts->tv_sec, &new_rtc_tm);
163 rtc_dev = alarmtimer_get_rtcdev();
164 rv = do_settimeofday(ts);
165 if (rv < 0)
166 return rv;
167 if (rtc_dev)
168 rv = rtc_set_time(rtc_dev, &new_rtc_tm);
169
170 spin_lock_irqsave(&alarm_slock, flags);
171 alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
172 wake_up(&alarm_wait_queue);
173 spin_unlock_irqrestore(&alarm_slock, flags);
174
175 return rv;
176}
177
178static int alarm_get_time(enum android_alarm_type alarm_type,
179 struct timespec *ts)
180{
181 int rv = 0;
182
183 switch (alarm_type) {
184 case ANDROID_ALARM_RTC_WAKEUP:
185 case ANDROID_ALARM_RTC:
186 getnstimeofday(ts);
187 break;
188 case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
189 case ANDROID_ALARM_ELAPSED_REALTIME:
190 get_monotonic_boottime(ts);
191 break;
192 case ANDROID_ALARM_SYSTEMTIME:
193 ktime_get_ts(ts);
194 break;
195 default:
196 rv = -EINVAL;
197 }
198 return rv;
199}
200
201static long alarm_do_ioctl(struct file *file, unsigned int cmd,
202 struct timespec *ts)
203{
204 int rv = 0;
205 unsigned long flags;
206 enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
207
208 if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
209 return -EINVAL;
210
211 if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
212 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
213 return -EPERM;
214 if (file->private_data == NULL &&
215 cmd != ANDROID_ALARM_SET_RTC) {
216 spin_lock_irqsave(&alarm_slock, flags);
217 if (alarm_opened) {
218 spin_unlock_irqrestore(&alarm_slock, flags);
219 return -EBUSY;
220 }
221 alarm_opened = 1;
222 file->private_data = (void *)1;
223 spin_unlock_irqrestore(&alarm_slock, flags);
224 }
225 }
226
227 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
228 case ANDROID_ALARM_CLEAR(0):
229 alarm_clear(alarm_type);
230 break;
231 case ANDROID_ALARM_SET(0):
232 alarm_set(alarm_type, ts);
233 break;
234 case ANDROID_ALARM_SET_AND_WAIT(0):
235 alarm_set(alarm_type, ts);
236 /* fall though */
237 case ANDROID_ALARM_WAIT:
238 rv = alarm_wait();
239 break;
240 case ANDROID_ALARM_SET_RTC:
241 rv = alarm_set_rtc(ts);
242 break;
243 case ANDROID_ALARM_GET_TIME(0):
244 rv = alarm_get_time(alarm_type, ts);
245 break;
246
247 default:
248 rv = -EINVAL;
249 }
250 return rv;
251}
252
253static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
254{
255
256 struct timespec ts;
257 int rv;
258
259 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
260 case ANDROID_ALARM_SET_AND_WAIT(0):
261 case ANDROID_ALARM_SET(0):
262 case ANDROID_ALARM_SET_RTC:
263 if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
264 return -EFAULT;
265 break;
266 }
267
268 rv = alarm_do_ioctl(file, cmd, &ts);
269 if (rv)
270 return rv;
271
272 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
273 case ANDROID_ALARM_GET_TIME(0):
274 if (copy_to_user((void __user *)arg, &ts, sizeof(ts)))
275 return -EFAULT;
276 break;
277 }
278
279 return 0;
280}
281
282#ifdef CONFIG_COMPAT
283static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
284 unsigned long arg)
285{
286
287 struct timespec ts;
288 int rv;
289
290 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
291 case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0):
292 case ANDROID_ALARM_SET_COMPAT(0):
293 case ANDROID_ALARM_SET_RTC_COMPAT:
294 if (compat_get_timespec(&ts, (void __user *)arg))
295 return -EFAULT;
296 /* fall through */
297 case ANDROID_ALARM_GET_TIME_COMPAT(0):
298 cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd);
299 break;
300 }
301
302 rv = alarm_do_ioctl(file, cmd, &ts);
303 if (rv)
304 return rv;
305
306 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
307 case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
308 if (compat_put_timespec(&ts, (void __user *)arg))
309 return -EFAULT;
310 break;
311 }
312
313 return 0;
314}
315#endif
316
317static int alarm_open(struct inode *inode, struct file *file)
318{
319 file->private_data = NULL;
320 return 0;
321}
322
323static int alarm_release(struct inode *inode, struct file *file)
324{
325 int i;
326 unsigned long flags;
327
328 spin_lock_irqsave(&alarm_slock, flags);
329 if (file->private_data) {
330 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
331 uint32_t alarm_type_mask = 1U << i;
332
333 if (alarm_enabled & alarm_type_mask) {
334 alarm_dbg(INFO,
335 "%s: clear alarm, pending %d\n",
336 __func__,
337 !!(alarm_pending & alarm_type_mask));
338 alarm_enabled &= ~alarm_type_mask;
339 }
340 spin_unlock_irqrestore(&alarm_slock, flags);
341 devalarm_cancel(&alarms[i]);
342 spin_lock_irqsave(&alarm_slock, flags);
343 }
344 if (alarm_pending | wait_pending) {
345 if (alarm_pending)
346 alarm_dbg(INFO, "%s: clear pending alarms %x\n",
347 __func__, alarm_pending);
348 __pm_relax(&alarm_wake_lock);
349 wait_pending = 0;
350 alarm_pending = 0;
351 }
352 alarm_opened = 0;
353 }
354 spin_unlock_irqrestore(&alarm_slock, flags);
355 return 0;
356}
357
358static void devalarm_triggered(struct devalarm *alarm)
359{
360 unsigned long flags;
361 uint32_t alarm_type_mask = 1U << alarm->type;
362
363 alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type);
364 spin_lock_irqsave(&alarm_slock, flags);
365 if (alarm_enabled & alarm_type_mask) {
366 __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */
367 alarm_enabled &= ~alarm_type_mask;
368 alarm_pending |= alarm_type_mask;
369 wake_up(&alarm_wait_queue);
370 }
371 spin_unlock_irqrestore(&alarm_slock, flags);
372}
373
374static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt)
375{
376 struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt);
377
378 devalarm_triggered(devalrm);
379 return HRTIMER_NORESTART;
380}
381
382static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm,
383 ktime_t now)
384{
385 struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm);
386
387 devalarm_triggered(devalrm);
388 return ALARMTIMER_NORESTART;
389}
390
391
392static const struct file_operations alarm_fops = {
393 .owner = THIS_MODULE,
394 .unlocked_ioctl = alarm_ioctl,
395 .open = alarm_open,
396 .release = alarm_release,
397#ifdef CONFIG_COMPAT
398 .compat_ioctl = alarm_compat_ioctl,
399#endif
400};
401
402static struct miscdevice alarm_device = {
403 .minor = MISC_DYNAMIC_MINOR,
404 .name = "alarm",
405 .fops = &alarm_fops,
406};
407
408static int __init alarm_dev_init(void)
409{
410 int err;
411 int i;
412
413 err = misc_register(&alarm_device);
414 if (err)
415 return err;
416
417 alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
418 ALARM_REALTIME, devalarm_alarmhandler);
419 hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
420 CLOCK_REALTIME, HRTIMER_MODE_ABS);
421 alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
422 ALARM_BOOTTIME, devalarm_alarmhandler);
423 hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
424 CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
425 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
426 CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
427
428 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
429 alarms[i].type = i;
430 if (!is_wakeup(i))
431 alarms[i].u.hrt.function = devalarm_hrthandler;
432 }
433
434 wakeup_source_init(&alarm_wake_lock, "alarm");
435 return 0;
436}
437
438static void __exit alarm_dev_exit(void)
439{
440 misc_deregister(&alarm_device);
441 wakeup_source_trash(&alarm_wake_lock);
442}
443
444module_init(alarm_dev_init);
445module_exit(alarm_dev_exit);
446MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
deleted file mode 100644
index 495b20cf3bf6..000000000000
--- a/drivers/staging/android/android_alarm.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/* include/linux/android_alarm.h
2 *
3 * Copyright (C) 2006-2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _LINUX_ANDROID_ALARM_H
17#define _LINUX_ANDROID_ALARM_H
18
19#include <linux/compat.h>
20#include <linux/ioctl.h>
21
22#include "uapi/android_alarm.h"
23
24#ifdef CONFIG_COMPAT
25#define ANDROID_ALARM_SET_COMPAT(type) ALARM_IOW(2, type, \
26 struct compat_timespec)
27#define ANDROID_ALARM_SET_AND_WAIT_COMPAT(type) ALARM_IOW(3, type, \
28 struct compat_timespec)
29#define ANDROID_ALARM_GET_TIME_COMPAT(type) ALARM_IOW(4, type, \
30 struct compat_timespec)
31#define ANDROID_ALARM_SET_RTC_COMPAT _IOW('a', 5, \
32 struct compat_timespec)
33#define ANDROID_ALARM_IOCTL_NR(cmd) (_IOC_NR(cmd) & ((1<<4)-1))
34#define ANDROID_ALARM_COMPAT_TO_NORM(cmd) \
35 ALARM_IOW(ANDROID_ALARM_IOCTL_NR(cmd), \
36 ANDROID_ALARM_IOCTL_TO_TYPE(cmd), \
37 struct timespec)
38
39#endif
40
41#endif
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 8c7852742f4b..d140b733940c 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -447,8 +447,8 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
447 loff_t end = (range->pgend + 1) * PAGE_SIZE; 447 loff_t end = (range->pgend + 1) * PAGE_SIZE;
448 448
449 vfs_fallocate(range->asma->file, 449 vfs_fallocate(range->asma->file,
450 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 450 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
451 start, end - start); 451 start, end - start);
452 range->purged = ASHMEM_WAS_PURGED; 452 range->purged = ASHMEM_WAS_PURGED;
453 lru_del(range); 453 lru_del(range);
454 454
@@ -549,7 +549,6 @@ static int get_name(struct ashmem_area *asma, void __user *name)
549 549
550 mutex_lock(&ashmem_mutex); 550 mutex_lock(&ashmem_mutex);
551 if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') { 551 if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') {
552
553 /* 552 /*
554 * Copying only `len', instead of ASHMEM_NAME_LEN, bytes 553 * Copying only `len', instead of ASHMEM_NAME_LEN, bytes
555 * prevents us from revealing one user's stack to another. 554 * prevents us from revealing one user's stack to another.
@@ -751,10 +750,10 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
751 750
752 switch (cmd) { 751 switch (cmd) {
753 case ASHMEM_SET_NAME: 752 case ASHMEM_SET_NAME:
754 ret = set_name(asma, (void __user *) arg); 753 ret = set_name(asma, (void __user *)arg);
755 break; 754 break;
756 case ASHMEM_GET_NAME: 755 case ASHMEM_GET_NAME:
757 ret = get_name(asma, (void __user *) arg); 756 ret = get_name(asma, (void __user *)arg);
758 break; 757 break;
759 case ASHMEM_SET_SIZE: 758 case ASHMEM_SET_SIZE:
760 ret = -EINVAL; 759 ret = -EINVAL;
@@ -775,7 +774,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
775 case ASHMEM_PIN: 774 case ASHMEM_PIN:
776 case ASHMEM_UNPIN: 775 case ASHMEM_UNPIN:
777 case ASHMEM_GET_PIN_STATUS: 776 case ASHMEM_GET_PIN_STATUS:
778 ret = ashmem_pin_unpin(asma, cmd, (void __user *) arg); 777 ret = ashmem_pin_unpin(asma, cmd, (void __user *)arg);
779 break; 778 break;
780 case ASHMEM_PURGE_ALL_CACHES: 779 case ASHMEM_PURGE_ALL_CACHES:
781 ret = -EPERM; 780 ret = -EPERM;
@@ -798,7 +797,6 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
798static long compat_ashmem_ioctl(struct file *file, unsigned int cmd, 797static long compat_ashmem_ioctl(struct file *file, unsigned int cmd,
799 unsigned long arg) 798 unsigned long arg)
800{ 799{
801
802 switch (cmd) { 800 switch (cmd) {
803 case COMPAT_ASHMEM_SET_SIZE: 801 case COMPAT_ASHMEM_SET_SIZE:
804 cmd = ASHMEM_SET_SIZE; 802 cmd = ASHMEM_SET_SIZE;
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 296d347660fc..b8f1c491553e 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1508,6 +1508,9 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
1508 pr_err("%s: can not add heap with invalid ops struct.\n", 1508 pr_err("%s: can not add heap with invalid ops struct.\n",
1509 __func__); 1509 __func__);
1510 1510
1511 spin_lock_init(&heap->free_lock);
1512 heap->free_list_size = 0;
1513
1511 if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) 1514 if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
1512 ion_heap_init_deferred_free(heap); 1515 ion_heap_init_deferred_free(heap);
1513 1516
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index f8cabcbc39e5..f4211f1be488 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -39,24 +39,6 @@ struct ion_cma_buffer_info {
39 struct sg_table *table; 39 struct sg_table *table;
40}; 40};
41 41
42/*
43 * Create scatter-list for the already allocated DMA buffer.
44 * This function could be replaced by dma_common_get_sgtable
45 * as soon as it will avalaible.
46 */
47static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
48 void *cpu_addr, dma_addr_t handle, size_t size)
49{
50 struct page *page = virt_to_page(cpu_addr);
51 int ret;
52
53 ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
54 if (unlikely(ret))
55 return ret;
56
57 sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
58 return 0;
59}
60 42
61/* ION CMA heap operations functions */ 43/* ION CMA heap operations functions */
62static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, 44static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
@@ -91,7 +73,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
91 if (!info->table) 73 if (!info->table)
92 goto free_mem; 74 goto free_mem;
93 75
94 if (ion_cma_get_sgtable 76 if (dma_common_get_sgtable
95 (dev, info->table, info->cpu_addr, info->handle, len)) 77 (dev, info->table, info->cpu_addr, info->handle, len))
96 goto free_table; 78 goto free_table;
97 /* keep this for memory release */ 79 /* keep this for memory release */
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index 4605e04712aa..fd13d05b538a 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -253,8 +253,6 @@ int ion_heap_init_deferred_free(struct ion_heap *heap)
253 struct sched_param param = { .sched_priority = 0 }; 253 struct sched_param param = { .sched_priority = 0 };
254 254
255 INIT_LIST_HEAD(&heap->free_list); 255 INIT_LIST_HEAD(&heap->free_list);
256 heap->free_list_size = 0;
257 spin_lock_init(&heap->free_lock);
258 init_waitqueue_head(&heap->waitqueue); 256 init_waitqueue_head(&heap->waitqueue);
259 heap->task = kthread_run(ion_heap_deferred_free, heap, 257 heap->task = kthread_run(ion_heap_deferred_free, heap,
260 "%s", heap->name); 258 "%s", heap->name);
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
deleted file mode 100644
index a673ffa34aa3..000000000000
--- a/drivers/staging/android/logger.c
+++ /dev/null
@@ -1,808 +0,0 @@
1/*
2 * drivers/misc/logger.c
3 *
4 * A Logging Subsystem
5 *
6 * Copyright (C) 2007-2008 Google, Inc.
7 *
8 * Robert Love <rlove@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#define pr_fmt(fmt) "logger: " fmt
21
22#include <linux/sched.h>
23#include <linux/module.h>
24#include <linux/fs.h>
25#include <linux/miscdevice.h>
26#include <linux/uaccess.h>
27#include <linux/poll.h>
28#include <linux/slab.h>
29#include <linux/time.h>
30#include <linux/vmalloc.h>
31#include <linux/aio.h>
32#include "logger.h"
33
34#include <asm/ioctls.h>
35
36/**
37 * struct logger_log - represents a specific log, such as 'main' or 'radio'
38 * @buffer: The actual ring buffer
39 * @misc: The "misc" device representing the log
40 * @wq: The wait queue for @readers
41 * @readers: This log's readers
42 * @mutex: The mutex that protects the @buffer
43 * @w_off: The current write head offset
44 * @head: The head, or location that readers start reading at.
45 * @size: The size of the log
46 * @logs: The list of log channels
47 *
48 * This structure lives from module insertion until module removal, so it does
49 * not need additional reference counting. The structure is protected by the
50 * mutex 'mutex'.
51 */
52struct logger_log {
53 unsigned char *buffer;
54 struct miscdevice misc;
55 wait_queue_head_t wq;
56 struct list_head readers;
57 struct mutex mutex;
58 size_t w_off;
59 size_t head;
60 size_t size;
61 struct list_head logs;
62};
63
64static LIST_HEAD(log_list);
65
66
67/**
68 * struct logger_reader - a logging device open for reading
69 * @log: The associated log
70 * @list: The associated entry in @logger_log's list
71 * @r_off: The current read head offset.
72 * @r_all: Reader can read all entries
73 * @r_ver: Reader ABI version
74 *
75 * This object lives from open to release, so we don't need additional
76 * reference counting. The structure is protected by log->mutex.
77 */
78struct logger_reader {
79 struct logger_log *log;
80 struct list_head list;
81 size_t r_off;
82 bool r_all;
83 int r_ver;
84};
85
86/* logger_offset - returns index 'n' into the log via (optimized) modulus */
87static size_t logger_offset(struct logger_log *log, size_t n)
88{
89 return n & (log->size - 1);
90}
91
92
93/*
94 * file_get_log - Given a file structure, return the associated log
95 *
96 * This isn't aesthetic. We have several goals:
97 *
98 * 1) Need to quickly obtain the associated log during an I/O operation
99 * 2) Readers need to maintain state (logger_reader)
100 * 3) Writers need to be very fast (open() should be a near no-op)
101 *
102 * In the reader case, we can trivially go file->logger_reader->logger_log.
103 * For a writer, we don't want to maintain a logger_reader, so we just go
104 * file->logger_log. Thus what file->private_data points at depends on whether
105 * or not the file was opened for reading. This function hides that dirtiness.
106 */
107static inline struct logger_log *file_get_log(struct file *file)
108{
109 if (file->f_mode & FMODE_READ) {
110 struct logger_reader *reader = file->private_data;
111
112 return reader->log;
113 }
114 return file->private_data;
115}
116
117/*
118 * get_entry_header - returns a pointer to the logger_entry header within
119 * 'log' starting at offset 'off'. A temporary logger_entry 'scratch' must
120 * be provided. Typically the return value will be a pointer within
121 * 'logger->buf'. However, a pointer to 'scratch' may be returned if
122 * the log entry spans the end and beginning of the circular buffer.
123 */
124static struct logger_entry *get_entry_header(struct logger_log *log,
125 size_t off, struct logger_entry *scratch)
126{
127 size_t len = min(sizeof(struct logger_entry), log->size - off);
128
129 if (len != sizeof(struct logger_entry)) {
130 memcpy(((void *) scratch), log->buffer + off, len);
131 memcpy(((void *) scratch) + len, log->buffer,
132 sizeof(struct logger_entry) - len);
133 return scratch;
134 }
135
136 return (struct logger_entry *) (log->buffer + off);
137}
138
139/*
140 * get_entry_msg_len - Grabs the length of the message of the entry
141 * starting from from 'off'.
142 *
143 * An entry length is 2 bytes (16 bits) in host endian order.
144 * In the log, the length does not include the size of the log entry structure.
145 * This function returns the size including the log entry structure.
146 *
147 * Caller needs to hold log->mutex.
148 */
149static __u32 get_entry_msg_len(struct logger_log *log, size_t off)
150{
151 struct logger_entry scratch;
152 struct logger_entry *entry;
153
154 entry = get_entry_header(log, off, &scratch);
155 return entry->len;
156}
157
158static size_t get_user_hdr_len(int ver)
159{
160 if (ver < 2)
161 return sizeof(struct user_logger_entry_compat);
162 return sizeof(struct logger_entry);
163}
164
165static ssize_t copy_header_to_user(int ver, struct logger_entry *entry,
166 char __user *buf)
167{
168 void *hdr;
169 size_t hdr_len;
170 struct user_logger_entry_compat v1;
171
172 if (ver < 2) {
173 v1.len = entry->len;
174 v1.__pad = 0;
175 v1.pid = entry->pid;
176 v1.tid = entry->tid;
177 v1.sec = entry->sec;
178 v1.nsec = entry->nsec;
179 hdr = &v1;
180 hdr_len = sizeof(struct user_logger_entry_compat);
181 } else {
182 hdr = entry;
183 hdr_len = sizeof(struct logger_entry);
184 }
185
186 return copy_to_user(buf, hdr, hdr_len);
187}
188
189/*
190 * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the
191 * user-space buffer 'buf'. Returns 'count' on success.
192 *
193 * Caller must hold log->mutex.
194 */
195static ssize_t do_read_log_to_user(struct logger_log *log,
196 struct logger_reader *reader,
197 char __user *buf,
198 size_t count)
199{
200 struct logger_entry scratch;
201 struct logger_entry *entry;
202 size_t len;
203 size_t msg_start;
204
205 /*
206 * First, copy the header to userspace, using the version of
207 * the header requested
208 */
209 entry = get_entry_header(log, reader->r_off, &scratch);
210 if (copy_header_to_user(reader->r_ver, entry, buf))
211 return -EFAULT;
212
213 count -= get_user_hdr_len(reader->r_ver);
214 buf += get_user_hdr_len(reader->r_ver);
215 msg_start = logger_offset(log,
216 reader->r_off + sizeof(struct logger_entry));
217
218 /*
219 * We read from the msg in two disjoint operations. First, we read from
220 * the current msg head offset up to 'count' bytes or to the end of
221 * the log, whichever comes first.
222 */
223 len = min(count, log->size - msg_start);
224 if (copy_to_user(buf, log->buffer + msg_start, len))
225 return -EFAULT;
226
227 /*
228 * Second, we read any remaining bytes, starting back at the head of
229 * the log.
230 */
231 if (count != len)
232 if (copy_to_user(buf + len, log->buffer, count - len))
233 return -EFAULT;
234
235 reader->r_off = logger_offset(log, reader->r_off +
236 sizeof(struct logger_entry) + count);
237
238 return count + get_user_hdr_len(reader->r_ver);
239}
240
241/*
242 * get_next_entry_by_uid - Starting at 'off', returns an offset into
243 * 'log->buffer' which contains the first entry readable by 'euid'
244 */
245static size_t get_next_entry_by_uid(struct logger_log *log,
246 size_t off, kuid_t euid)
247{
248 while (off != log->w_off) {
249 struct logger_entry *entry;
250 struct logger_entry scratch;
251 size_t next_len;
252
253 entry = get_entry_header(log, off, &scratch);
254
255 if (uid_eq(entry->euid, euid))
256 return off;
257
258 next_len = sizeof(struct logger_entry) + entry->len;
259 off = logger_offset(log, off + next_len);
260 }
261
262 return off;
263}
264
265/*
266 * logger_read - our log's read() method
267 *
268 * Behavior:
269 *
270 * - O_NONBLOCK works
271 * - If there are no log entries to read, blocks until log is written to
272 * - Atomically reads exactly one log entry
273 *
274 * Will set errno to EINVAL if read
275 * buffer is insufficient to hold next entry.
276 */
277static ssize_t logger_read(struct file *file, char __user *buf,
278 size_t count, loff_t *pos)
279{
280 struct logger_reader *reader = file->private_data;
281 struct logger_log *log = reader->log;
282 ssize_t ret;
283 DEFINE_WAIT(wait);
284
285start:
286 while (1) {
287 mutex_lock(&log->mutex);
288
289 prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE);
290
291 ret = (log->w_off == reader->r_off);
292 mutex_unlock(&log->mutex);
293 if (!ret)
294 break;
295
296 if (file->f_flags & O_NONBLOCK) {
297 ret = -EAGAIN;
298 break;
299 }
300
301 if (signal_pending(current)) {
302 ret = -EINTR;
303 break;
304 }
305
306 schedule();
307 }
308
309 finish_wait(&log->wq, &wait);
310 if (ret)
311 return ret;
312
313 mutex_lock(&log->mutex);
314
315 if (!reader->r_all)
316 reader->r_off = get_next_entry_by_uid(log,
317 reader->r_off, current_euid());
318
319 /* is there still something to read or did we race? */
320 if (unlikely(log->w_off == reader->r_off)) {
321 mutex_unlock(&log->mutex);
322 goto start;
323 }
324
325 /* get the size of the next entry */
326 ret = get_user_hdr_len(reader->r_ver) +
327 get_entry_msg_len(log, reader->r_off);
328 if (count < ret) {
329 ret = -EINVAL;
330 goto out;
331 }
332
333 /* get exactly one entry from the log */
334 ret = do_read_log_to_user(log, reader, buf, ret);
335
336out:
337 mutex_unlock(&log->mutex);
338
339 return ret;
340}
341
342/*
343 * get_next_entry - return the offset of the first valid entry at least 'len'
344 * bytes after 'off'.
345 *
346 * Caller must hold log->mutex.
347 */
348static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
349{
350 size_t count = 0;
351
352 do {
353 size_t nr = sizeof(struct logger_entry) +
354 get_entry_msg_len(log, off);
355 off = logger_offset(log, off + nr);
356 count += nr;
357 } while (count < len);
358
359 return off;
360}
361
362/*
363 * is_between - is a < c < b, accounting for wrapping of a, b, and c
364 * positions in the buffer
365 *
366 * That is, if a<b, check for c between a and b
367 * and if a>b, check for c outside (not between) a and b
368 *
369 * |------- a xxxxxxxx b --------|
370 * c^
371 *
372 * |xxxxx b --------- a xxxxxxxxx|
373 * c^
374 * or c^
375 */
376static inline int is_between(size_t a, size_t b, size_t c)
377{
378 if (a < b) {
379 /* is c between a and b? */
380 if (a < c && c <= b)
381 return 1;
382 } else {
383 /* is c outside of b through a? */
384 if (c <= b || a < c)
385 return 1;
386 }
387
388 return 0;
389}
390
391/*
392 * fix_up_readers - walk the list of all readers and "fix up" any who were
393 * lapped by the writer; also do the same for the default "start head".
394 * We do this by "pulling forward" the readers and start head to the first
395 * entry after the new write head.
396 *
397 * The caller needs to hold log->mutex.
398 */
399static void fix_up_readers(struct logger_log *log, size_t len)
400{
401 size_t old = log->w_off;
402 size_t new = logger_offset(log, old + len);
403 struct logger_reader *reader;
404
405 if (is_between(old, new, log->head))
406 log->head = get_next_entry(log, log->head, len);
407
408 list_for_each_entry(reader, &log->readers, list)
409 if (is_between(old, new, reader->r_off))
410 reader->r_off = get_next_entry(log, reader->r_off, len);
411}
412
413/*
414 * logger_write_iter - our write method, implementing support for write(),
415 * writev(), and aio_write(). Writes are our fast path, and we try to optimize
416 * them above all else.
417 */
418static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from)
419{
420 struct logger_log *log = file_get_log(iocb->ki_filp);
421 struct logger_entry header;
422 struct timespec now;
423 size_t len, count, w_off;
424
425 count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
426
427 now = current_kernel_time();
428
429 header.pid = current->tgid;
430 header.tid = current->pid;
431 header.sec = now.tv_sec;
432 header.nsec = now.tv_nsec;
433 header.euid = current_euid();
434 header.len = count;
435 header.hdr_size = sizeof(struct logger_entry);
436
437 /* null writes succeed, return zero */
438 if (unlikely(!header.len))
439 return 0;
440
441 mutex_lock(&log->mutex);
442
443 /*
444 * Fix up any readers, pulling them forward to the first readable
445 * entry after (what will be) the new write offset. We do this now
446 * because if we partially fail, we can end up with clobbered log
447 * entries that encroach on readable buffer.
448 */
449 fix_up_readers(log, sizeof(struct logger_entry) + header.len);
450
451 len = min(sizeof(header), log->size - log->w_off);
452 memcpy(log->buffer + log->w_off, &header, len);
453 memcpy(log->buffer, (char *)&header + len, sizeof(header) - len);
454
455 /* Work with a copy until we are ready to commit the whole entry */
456 w_off = logger_offset(log, log->w_off + sizeof(struct logger_entry));
457
458 len = min(count, log->size - w_off);
459
460 if (copy_from_iter(log->buffer + w_off, len, from) != len) {
461 /*
462 * Note that by not updating log->w_off, this abandons the
463 * portion of the new entry that *was* successfully
464 * copied, just above. This is intentional to avoid
465 * message corruption from missing fragments.
466 */
467 mutex_unlock(&log->mutex);
468 return -EFAULT;
469 }
470
471 if (copy_from_iter(log->buffer, count - len, from) != count - len) {
472 mutex_unlock(&log->mutex);
473 return -EFAULT;
474 }
475
476 log->w_off = logger_offset(log, w_off + count);
477 mutex_unlock(&log->mutex);
478
479 /* wake up any blocked readers */
480 wake_up_interruptible(&log->wq);
481
482 return len;
483}
484
485static struct logger_log *get_log_from_minor(int minor)
486{
487 struct logger_log *log;
488
489 list_for_each_entry(log, &log_list, logs)
490 if (log->misc.minor == minor)
491 return log;
492 return NULL;
493}
494
495/*
496 * logger_open - the log's open() file operation
497 *
498 * Note how near a no-op this is in the write-only case. Keep it that way!
499 */
500static int logger_open(struct inode *inode, struct file *file)
501{
502 struct logger_log *log;
503 int ret;
504
505 ret = nonseekable_open(inode, file);
506 if (ret)
507 return ret;
508
509 log = get_log_from_minor(MINOR(inode->i_rdev));
510 if (!log)
511 return -ENODEV;
512
513 if (file->f_mode & FMODE_READ) {
514 struct logger_reader *reader;
515
516 reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL);
517 if (!reader)
518 return -ENOMEM;
519
520 reader->log = log;
521 reader->r_ver = 1;
522 reader->r_all = in_egroup_p(inode->i_gid) ||
523 capable(CAP_SYSLOG);
524
525 INIT_LIST_HEAD(&reader->list);
526
527 mutex_lock(&log->mutex);
528 reader->r_off = log->head;
529 list_add_tail(&reader->list, &log->readers);
530 mutex_unlock(&log->mutex);
531
532 file->private_data = reader;
533 } else
534 file->private_data = log;
535
536 return 0;
537}
538
539/*
540 * logger_release - the log's release file operation
541 *
542 * Note this is a total no-op in the write-only case. Keep it that way!
543 */
544static int logger_release(struct inode *ignored, struct file *file)
545{
546 if (file->f_mode & FMODE_READ) {
547 struct logger_reader *reader = file->private_data;
548 struct logger_log *log = reader->log;
549
550 mutex_lock(&log->mutex);
551 list_del(&reader->list);
552 mutex_unlock(&log->mutex);
553
554 kfree(reader);
555 }
556
557 return 0;
558}
559
560/*
561 * logger_poll - the log's poll file operation, for poll/select/epoll
562 *
563 * Note we always return POLLOUT, because you can always write() to the log.
564 * Note also that, strictly speaking, a return value of POLLIN does not
565 * guarantee that the log is readable without blocking, as there is a small
566 * chance that the writer can lap the reader in the interim between poll()
567 * returning and the read() request.
568 */
569static unsigned int logger_poll(struct file *file, poll_table *wait)
570{
571 struct logger_reader *reader;
572 struct logger_log *log;
573 unsigned int ret = POLLOUT | POLLWRNORM;
574
575 if (!(file->f_mode & FMODE_READ))
576 return ret;
577
578 reader = file->private_data;
579 log = reader->log;
580
581 poll_wait(file, &log->wq, wait);
582
583 mutex_lock(&log->mutex);
584 if (!reader->r_all)
585 reader->r_off = get_next_entry_by_uid(log,
586 reader->r_off, current_euid());
587
588 if (log->w_off != reader->r_off)
589 ret |= POLLIN | POLLRDNORM;
590 mutex_unlock(&log->mutex);
591
592 return ret;
593}
594
595static long logger_set_version(struct logger_reader *reader, void __user *arg)
596{
597 int version;
598
599 if (copy_from_user(&version, arg, sizeof(int)))
600 return -EFAULT;
601
602 if ((version < 1) || (version > 2))
603 return -EINVAL;
604
605 reader->r_ver = version;
606 return 0;
607}
608
609static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
610{
611 struct logger_log *log = file_get_log(file);
612 struct logger_reader *reader;
613 long ret = -EINVAL;
614 void __user *argp = (void __user *) arg;
615
616 mutex_lock(&log->mutex);
617
618 switch (cmd) {
619 case LOGGER_GET_LOG_BUF_SIZE:
620 ret = log->size;
621 break;
622 case LOGGER_GET_LOG_LEN:
623 if (!(file->f_mode & FMODE_READ)) {
624 ret = -EBADF;
625 break;
626 }
627 reader = file->private_data;
628 if (log->w_off >= reader->r_off)
629 ret = log->w_off - reader->r_off;
630 else
631 ret = (log->size - reader->r_off) + log->w_off;
632 break;
633 case LOGGER_GET_NEXT_ENTRY_LEN:
634 if (!(file->f_mode & FMODE_READ)) {
635 ret = -EBADF;
636 break;
637 }
638 reader = file->private_data;
639
640 if (!reader->r_all)
641 reader->r_off = get_next_entry_by_uid(log,
642 reader->r_off, current_euid());
643
644 if (log->w_off != reader->r_off)
645 ret = get_user_hdr_len(reader->r_ver) +
646 get_entry_msg_len(log, reader->r_off);
647 else
648 ret = 0;
649 break;
650 case LOGGER_FLUSH_LOG:
651 if (!(file->f_mode & FMODE_WRITE)) {
652 ret = -EBADF;
653 break;
654 }
655 if (!(in_egroup_p(file_inode(file)->i_gid) ||
656 capable(CAP_SYSLOG))) {
657 ret = -EPERM;
658 break;
659 }
660 list_for_each_entry(reader, &log->readers, list)
661 reader->r_off = log->w_off;
662 log->head = log->w_off;
663 ret = 0;
664 break;
665 case LOGGER_GET_VERSION:
666 if (!(file->f_mode & FMODE_READ)) {
667 ret = -EBADF;
668 break;
669 }
670 reader = file->private_data;
671 ret = reader->r_ver;
672 break;
673 case LOGGER_SET_VERSION:
674 if (!(file->f_mode & FMODE_READ)) {
675 ret = -EBADF;
676 break;
677 }
678 reader = file->private_data;
679 ret = logger_set_version(reader, argp);
680 break;
681 }
682
683 mutex_unlock(&log->mutex);
684
685 return ret;
686}
687
688static const struct file_operations logger_fops = {
689 .owner = THIS_MODULE,
690 .read = logger_read,
691 .write_iter = logger_write_iter,
692 .poll = logger_poll,
693 .unlocked_ioctl = logger_ioctl,
694 .compat_ioctl = logger_ioctl,
695 .open = logger_open,
696 .release = logger_release,
697};
698
699/*
700 * Log size must must be a power of two, and greater than
701 * (LOGGER_ENTRY_MAX_PAYLOAD + sizeof(struct logger_entry)).
702 */
703static int __init create_log(char *log_name, int size)
704{
705 int ret = 0;
706 struct logger_log *log;
707 unsigned char *buffer;
708
709 buffer = vmalloc(size);
710 if (buffer == NULL)
711 return -ENOMEM;
712
713 log = kzalloc(sizeof(struct logger_log), GFP_KERNEL);
714 if (log == NULL) {
715 ret = -ENOMEM;
716 goto out_free_buffer;
717 }
718 log->buffer = buffer;
719
720 log->misc.minor = MISC_DYNAMIC_MINOR;
721 log->misc.name = kstrdup(log_name, GFP_KERNEL);
722 if (log->misc.name == NULL) {
723 ret = -ENOMEM;
724 goto out_free_log;
725 }
726
727 log->misc.fops = &logger_fops;
728 log->misc.parent = NULL;
729
730 init_waitqueue_head(&log->wq);
731 INIT_LIST_HEAD(&log->readers);
732 mutex_init(&log->mutex);
733 log->w_off = 0;
734 log->head = 0;
735 log->size = size;
736
737 INIT_LIST_HEAD(&log->logs);
738 list_add_tail(&log->logs, &log_list);
739
740 /* finally, initialize the misc device for this log */
741 ret = misc_register(&log->misc);
742 if (unlikely(ret)) {
743 pr_err("failed to register misc device for log '%s'!\n",
744 log->misc.name);
745 goto out_free_misc_name;
746 }
747
748 pr_info("created %luK log '%s'\n",
749 (unsigned long) log->size >> 10, log->misc.name);
750
751 return 0;
752
753out_free_misc_name:
754 kfree(log->misc.name);
755
756out_free_log:
757 kfree(log);
758
759out_free_buffer:
760 vfree(buffer);
761 return ret;
762}
763
764static int __init logger_init(void)
765{
766 int ret;
767
768 ret = create_log(LOGGER_LOG_MAIN, 256*1024);
769 if (unlikely(ret))
770 goto out;
771
772 ret = create_log(LOGGER_LOG_EVENTS, 256*1024);
773 if (unlikely(ret))
774 goto out;
775
776 ret = create_log(LOGGER_LOG_RADIO, 256*1024);
777 if (unlikely(ret))
778 goto out;
779
780 ret = create_log(LOGGER_LOG_SYSTEM, 256*1024);
781 if (unlikely(ret))
782 goto out;
783
784out:
785 return ret;
786}
787
788static void __exit logger_exit(void)
789{
790 struct logger_log *current_log, *next_log;
791
792 list_for_each_entry_safe(current_log, next_log, &log_list, logs) {
793 /* we have to delete all the entry inside log_list */
794 misc_deregister(&current_log->misc);
795 vfree(current_log->buffer);
796 kfree(current_log->misc.name);
797 list_del(&current_log->logs);
798 kfree(current_log);
799 }
800}
801
802
803device_initcall(logger_init);
804module_exit(logger_exit);
805
806MODULE_LICENSE("GPL");
807MODULE_AUTHOR("Robert Love, <rlove@google.com>");
808MODULE_DESCRIPTION("Android Logger");
diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h
deleted file mode 100644
index 70af7d805dff..000000000000
--- a/drivers/staging/android/logger.h
+++ /dev/null
@@ -1,89 +0,0 @@
1/* include/linux/logger.h
2 *
3 * Copyright (C) 2007-2008 Google, Inc.
4 * Author: Robert Love <rlove@android.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _LINUX_LOGGER_H
18#define _LINUX_LOGGER_H
19
20#include <linux/types.h>
21#include <linux/ioctl.h>
22
23/**
24 * struct user_logger_entry_compat - defines a single entry that is given to a logger
25 * @len: The length of the payload
26 * @__pad: Two bytes of padding that appear to be required
27 * @pid: The generating process' process ID
28 * @tid: The generating process' thread ID
29 * @sec: The number of seconds that have elapsed since the Epoch
30 * @nsec: The number of nanoseconds that have elapsed since @sec
31 * @msg: The message that is to be logged
32 *
33 * The userspace structure for version 1 of the logger_entry ABI.
34 * This structure is returned to userspace unless the caller requests
35 * an upgrade to a newer ABI version.
36 */
37struct user_logger_entry_compat {
38 __u16 len;
39 __u16 __pad;
40 __s32 pid;
41 __s32 tid;
42 __s32 sec;
43 __s32 nsec;
44 char msg[0];
45};
46
47/**
48 * struct logger_entry - defines a single entry that is given to a logger
49 * @len: The length of the payload
50 * @hdr_size: sizeof(struct logger_entry_v2)
51 * @pid: The generating process' process ID
52 * @tid: The generating process' thread ID
53 * @sec: The number of seconds that have elapsed since the Epoch
54 * @nsec: The number of nanoseconds that have elapsed since @sec
55 * @euid: Effective UID of logger
56 * @msg: The message that is to be logged
57 *
58 * The structure for version 2 of the logger_entry ABI.
59 * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
60 * is called with version >= 2
61 */
62struct logger_entry {
63 __u16 len;
64 __u16 hdr_size;
65 __s32 pid;
66 __s32 tid;
67 __s32 sec;
68 __s32 nsec;
69 kuid_t euid;
70 char msg[0];
71};
72
73#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */
74#define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */
75#define LOGGER_LOG_SYSTEM "log_system" /* system/framework messages */
76#define LOGGER_LOG_MAIN "log_main" /* everything else */
77
78#define LOGGER_ENTRY_MAX_PAYLOAD 4076
79
80#define __LOGGERIO 0xAE
81
82#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */
83#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */
84#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */
85#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */
86#define LOGGER_GET_VERSION _IO(__LOGGERIO, 5) /* abi version */
87#define LOGGER_SET_VERSION _IO(__LOGGERIO, 6) /* abi version */
88
89#endif /* _LINUX_LOGGER_H */
diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c
index 1532a86404be..91ed2c4cff45 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/staging/android/sync_debug.c
@@ -96,7 +96,8 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
96 sync_status_str(status)); 96 sync_status_str(status));
97 97
98 if (status <= 0) { 98 if (status <= 0) {
99 struct timespec64 ts64 = ktime_to_timespec64(pt->base.timestamp); 99 struct timespec64 ts64 =
100 ktime_to_timespec64(pt->base.timestamp);
100 101
101 seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); 102 seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
102 } 103 }
diff --git a/drivers/staging/android/uapi/android_alarm.h b/drivers/staging/android/uapi/android_alarm.h
deleted file mode 100644
index aa013f6f5f3a..000000000000
--- a/drivers/staging/android/uapi/android_alarm.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/* drivers/staging/android/uapi/android_alarm.h
2 *
3 * Copyright (C) 2006-2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _UAPI_LINUX_ANDROID_ALARM_H
17#define _UAPI_LINUX_ANDROID_ALARM_H
18
19#include <linux/ioctl.h>
20#include <linux/time.h>
21
22enum android_alarm_type {
23 /* return code bit numbers or set alarm arg */
24 ANDROID_ALARM_RTC_WAKEUP,
25 ANDROID_ALARM_RTC,
26 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
27 ANDROID_ALARM_ELAPSED_REALTIME,
28 ANDROID_ALARM_SYSTEMTIME,
29
30 ANDROID_ALARM_TYPE_COUNT,
31
32 /* return code bit numbers */
33 /* ANDROID_ALARM_TIME_CHANGE = 16 */
34};
35
36enum android_alarm_return_flags {
37 ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
38 ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
39 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
40 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
41 ANDROID_ALARM_ELAPSED_REALTIME_MASK =
42 1U << ANDROID_ALARM_ELAPSED_REALTIME,
43 ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
44 ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
45};
46
47/* Disable alarm */
48#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4))
49
50/* Ack last alarm and wait for next */
51#define ANDROID_ALARM_WAIT _IO('a', 1)
52
53#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
54/* Set alarm */
55#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
56#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
57#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
58#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
59#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
60#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
61
62#endif
diff --git a/drivers/staging/board/board.c b/drivers/staging/board/board.c
index 6050fbdfd31f..d5a6abc84519 100644
--- a/drivers/staging/board/board.c
+++ b/drivers/staging/board/board.c
@@ -11,8 +11,7 @@ static bool find_by_address(u64 base_address)
11 struct resource res; 11 struct resource res;
12 12
13 while (dn) { 13 while (dn) {
14 if (of_can_translate_address(dn) 14 if (!of_address_to_resource(dn, 0, &res)) {
15 && !of_address_to_resource(dn, 0, &res)) {
16 if (res.start == base_address) { 15 if (res.start == base_address) {
17 of_node_put(dn); 16 of_node_put(dn);
18 return true; 17 return true;
diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
index 471d0877f382..5455bf3d5a91 100644
--- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
+++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
@@ -91,8 +91,10 @@ static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event,
91 91
92 if (ndata->clk == clk_wzrd->clk_in1) 92 if (ndata->clk == clk_wzrd->clk_in1)
93 max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1]; 93 max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1];
94 if (ndata->clk == clk_wzrd->axi_clk) 94 else if (ndata->clk == clk_wzrd->axi_clk)
95 max = WZRD_ACLK_MAX_FREQ; 95 max = WZRD_ACLK_MAX_FREQ;
96 else
97 return NOTIFY_DONE; /* should never happen */
96 98
97 switch (event) { 99 switch (event) {
98 case PRE_RATE_CHANGE: 100 case PRE_RATE_CHANGE:
@@ -239,6 +241,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
239 /* register div per output */ 241 /* register div per output */
240 for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) { 242 for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
241 const char *clkout_name; 243 const char *clkout_name;
244
242 if (of_property_read_string_index(np, "clock-output-names", i, 245 if (of_property_read_string_index(np, "clock-output-names", i,
243 &clkout_name)) { 246 &clkout_name)) {
244 dev_err(&pdev->dev, 247 dev_err(&pdev->dev,
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index a8201fe87512..593fcb1783b4 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -168,7 +168,7 @@ config COMEDI_PCL730
168 168
169config COMEDI_PCL812 169config COMEDI_PCL812
170 tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" 170 tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216"
171 depends on VIRT_TO_BUS && ISA_DMA_API 171 select COMEDI_ISADMA if ISA_DMA_API
172 ---help--- 172 ---help---
173 Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink 173 Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink
174 ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, 174 ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA,
@@ -179,7 +179,7 @@ config COMEDI_PCL812
179 179
180config COMEDI_PCL816 180config COMEDI_PCL816
181 tristate "Advantech PCL-814 and PCL-816 ISA card support" 181 tristate "Advantech PCL-814 and PCL-816 ISA card support"
182 depends on VIRT_TO_BUS && ISA_DMA_API 182 select COMEDI_ISADMA if ISA_DMA_API
183 ---help--- 183 ---help---
184 Enable support for Advantech PCL-814 and PCL-816 ISA cards 184 Enable support for Advantech PCL-814 and PCL-816 ISA cards
185 185
@@ -188,7 +188,7 @@ config COMEDI_PCL816
188 188
189config COMEDI_PCL818 189config COMEDI_PCL818
190 tristate "Advantech PCL-718 and PCL-818 ISA card support" 190 tristate "Advantech PCL-718 and PCL-818 ISA card support"
191 depends on VIRT_TO_BUS && ISA_DMA_API 191 select COMEDI_ISADMA if ISA_DMA_API
192 ---help--- 192 ---help---
193 Enable support for Advantech PCL-818 ISA cards 193 Enable support for Advantech PCL-818 ISA cards
194 PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718 194 PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718
@@ -281,7 +281,7 @@ config COMEDI_DAS08_ISA
281 281
282config COMEDI_DAS16 282config COMEDI_DAS16
283 tristate "DAS-16 compatible ISA and PC/104 card support" 283 tristate "DAS-16 compatible ISA and PC/104 card support"
284 depends on ISA_DMA_API 284 select COMEDI_ISADMA if ISA_DMA_API
285 select COMEDI_8255 285 select COMEDI_8255
286 ---help--- 286 ---help---
287 Enable support for Keithley Metrabyte/ComputerBoards DAS16 287 Enable support for Keithley Metrabyte/ComputerBoards DAS16
@@ -309,7 +309,7 @@ config COMEDI_DAS800
309 309
310config COMEDI_DAS1800 310config COMEDI_DAS1800
311 tristate "DAS1800 and compatible ISA card support" 311 tristate "DAS1800 and compatible ISA card support"
312 depends on VIRT_TO_BUS && ISA_DMA_API 312 select COMEDI_ISADMA if ISA_DMA_API
313 ---help--- 313 ---help---
314 Enable support for DAS1800 and compatible ISA cards 314 Enable support for DAS1800 and compatible ISA cards
315 Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO, 315 Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO,
@@ -372,7 +372,7 @@ config COMEDI_DT2817
372 372
373config COMEDI_DT282X 373config COMEDI_DT282X
374 tristate "Data Translation DT2821 series and DT-EZ ISA card support" 374 tristate "Data Translation DT2821 series and DT-EZ ISA card support"
375 depends on VIRT_TO_BUS && ISA_DMA_API 375 select COMEDI_ISADMA if ISA_DMA_API
376 ---help--- 376 ---help---
377 Enable support for Data Translation DT2821 series including DT-EZ 377 Enable support for Data Translation DT2821 series including DT-EZ
378 DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI, 378 DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI,
@@ -462,7 +462,7 @@ config COMEDI_ADQ12B
462 462
463config COMEDI_NI_AT_A2150 463config COMEDI_NI_AT_A2150
464 tristate "NI AT-A2150 ISA card support" 464 tristate "NI AT-A2150 ISA card support"
465 depends on VIRT_TO_BUS && ISA_DMA_API 465 select COMEDI_ISADMA if ISA_DMA_API
466 ---help--- 466 ---help---
467 Enable support for National Instruments AT-A2150 cards 467 Enable support for National Instruments AT-A2150 cards
468 468
@@ -502,7 +502,7 @@ config COMEDI_NI_ATMIO16D
502config COMEDI_NI_LABPC_ISA 502config COMEDI_NI_LABPC_ISA
503 tristate "NI Lab-PC and compatibles ISA support" 503 tristate "NI Lab-PC and compatibles ISA support"
504 select COMEDI_NI_LABPC 504 select COMEDI_NI_LABPC
505 select COMEDI_NI_LABPC_ISADMA if ISA_DMA_API && VIRT_TO_BUS 505 select COMEDI_NI_LABPC_ISADMA if ISA_DMA_API
506 ---help--- 506 ---help---
507 Enable support for National Instruments Lab-PC and compatibles 507 Enable support for National Instruments Lab-PC and compatibles
508 Lab-PC-1200, Lab-PC-1200AI, Lab-PC+. 508 Lab-PC-1200, Lab-PC-1200AI, Lab-PC+.
@@ -724,7 +724,6 @@ config COMEDI_ADL_PCI9111
724config COMEDI_ADL_PCI9118 724config COMEDI_ADL_PCI9118
725 tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" 725 tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support"
726 depends on HAS_DMA 726 depends on HAS_DMA
727 depends on VIRT_TO_BUS
728 ---help--- 727 ---help---
729 Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards 728 Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards
730 729
@@ -1263,12 +1262,16 @@ config COMEDI_DAS08
1263 tristate 1262 tristate
1264 select COMEDI_8255 1263 select COMEDI_8255
1265 1264
1265config COMEDI_ISADMA
1266 tristate
1267
1266config COMEDI_NI_LABPC 1268config COMEDI_NI_LABPC
1267 tristate 1269 tristate
1268 select COMEDI_8255 1270 select COMEDI_8255
1269 1271
1270config COMEDI_NI_LABPC_ISADMA 1272config COMEDI_NI_LABPC_ISADMA
1271 tristate 1273 tristate
1274 select COMEDI_ISADMA
1272 1275
1273config COMEDI_NI_TIO 1276config COMEDI_NI_TIO
1274 tristate 1277 tristate
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 5a4c74f703b3..25848244c4b1 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -1,23 +1,23 @@
1/* 1/*
2 comedi/comedi_compat32.c 2 * comedi/comedi_compat32.c
3 32-bit ioctl compatibility for 64-bit comedi kernel module. 3 * 32-bit ioctl compatibility for 64-bit comedi kernel module.
4 4 *
5 Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk> 5 * Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
6 Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/> 6 * Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
7 7 *
8 COMEDI - Linux Control and Measurement Device Interface 8 * COMEDI - Linux Control and Measurement Device Interface
9 Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org> 9 * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
10 10 *
11 This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 * (at your option) any later version.
15 15 *
16 This program is distributed in the hope that it will be useful, 16 * This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 * GNU General Public License for more details.
20*/ 20 */
21 21
22#include <linux/uaccess.h> 22#include <linux/uaccess.h>
23#include <linux/compat.h> 23#include <linux/compat.h>
@@ -27,11 +27,15 @@
27 27
28#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct) 28#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
29#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct) 29#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
30/* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR. 30/*
31 * It's too late to change it now, but it only affects the command number. */ 31 * N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
32 * It's too late to change it now, but it only affects the command number.
33 */
32#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct) 34#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
33/* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR. 35/*
34 * It's too late to change it now, but it only affects the command number. */ 36 * N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
37 * It's too late to change it now, but it only affects the command number.
38 */
35#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct) 39#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
36#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct) 40#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
37#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct) 41#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
@@ -39,7 +43,7 @@
39struct comedi32_chaninfo_struct { 43struct comedi32_chaninfo_struct {
40 unsigned int subdev; 44 unsigned int subdev;
41 compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */ 45 compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
42 compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */ 46 compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
43 compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */ 47 compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
44 unsigned int unused[4]; 48 unsigned int unused[4];
45}; 49};
@@ -62,16 +66,16 @@ struct comedi32_cmd_struct {
62 unsigned int scan_end_arg; 66 unsigned int scan_end_arg;
63 unsigned int stop_src; 67 unsigned int stop_src;
64 unsigned int stop_arg; 68 unsigned int stop_arg;
65 compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */ 69 compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
66 unsigned int chanlist_len; 70 unsigned int chanlist_len;
67 compat_uptr_t data; /* 32-bit 'short *' */ 71 compat_uptr_t data; /* 32-bit 'short *' */
68 unsigned int data_len; 72 unsigned int data_len;
69}; 73};
70 74
71struct comedi32_insn_struct { 75struct comedi32_insn_struct {
72 unsigned int insn; 76 unsigned int insn;
73 unsigned int n; 77 unsigned int n;
74 compat_uptr_t data; /* 32-bit 'unsigned int *' */ 78 compat_uptr_t data; /* 32-bit 'unsigned int *' */
75 unsigned int subdev; 79 unsigned int subdev;
76 unsigned int chanspec; 80 unsigned int chanspec;
77 unsigned int unused[3]; 81 unsigned int unused[3];
@@ -79,7 +83,7 @@ struct comedi32_insn_struct {
79 83
80struct comedi32_insnlist_struct { 84struct comedi32_insnlist_struct {
81 unsigned int n_insns; 85 unsigned int n_insns;
82 compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */ 86 compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
83}; 87};
84 88
85/* Handle translated ioctl. */ 89/* Handle translated ioctl. */
@@ -215,10 +219,12 @@ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
215 int err; 219 int err;
216 unsigned int temp; 220 unsigned int temp;
217 221
218 /* Copy back most of cmd structure. */ 222 /*
219 /* Assume the pointer values are already valid. */ 223 * Copy back most of cmd structure.
220 /* (Could use ptr_to_compat() to set them, but that wasn't implemented 224 *
221 * until kernel version 2.6.11.) */ 225 * Assume the pointer values are already valid.
226 * (Could use ptr_to_compat() to set them.)
227 */
222 if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd)) || 228 if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd)) ||
223 !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) 229 !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32)))
224 return -EFAULT; 230 return -EFAULT;
@@ -262,7 +268,7 @@ static int compat_cmd(struct file *file, unsigned long arg)
262{ 268{
263 struct comedi_cmd __user *cmd; 269 struct comedi_cmd __user *cmd;
264 struct comedi32_cmd_struct __user *cmd32; 270 struct comedi32_cmd_struct __user *cmd32;
265 int rc; 271 int rc, err;
266 272
267 cmd32 = compat_ptr(arg); 273 cmd32 = compat_ptr(arg);
268 cmd = compat_alloc_user_space(sizeof(*cmd)); 274 cmd = compat_alloc_user_space(sizeof(*cmd));
@@ -271,7 +277,15 @@ static int compat_cmd(struct file *file, unsigned long arg)
271 if (rc) 277 if (rc)
272 return rc; 278 return rc;
273 279
274 return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd); 280 rc = translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
281 if (rc == -EAGAIN) {
282 /* Special case: copy cmd back to user. */
283 err = put_compat_cmd(cmd32, cmd);
284 if (err)
285 rc = err;
286 }
287
288 return rc;
275} 289}
276 290
277/* Handle 32-bit COMEDI_CMDTEST ioctl. */ 291/* Handle 32-bit COMEDI_CMDTEST ioctl. */
@@ -395,10 +409,12 @@ static int compat_insn(struct file *file, unsigned long arg)
395 return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn); 409 return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
396} 410}
397 411
398/* Process untranslated ioctl. */ 412/*
399/* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */ 413 * compat_ioctl file operation.
400static inline int raw_ioctl(struct file *file, unsigned int cmd, 414 *
401 unsigned long arg) 415 * Returns -ENOIOCTLCMD for unrecognised ioctl codes.
416 */
417long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
402{ 418{
403 int rc; 419 int rc;
404 420
@@ -445,10 +461,3 @@ static inline int raw_ioctl(struct file *file, unsigned int cmd,
445 } 461 }
446 return rc; 462 return rc;
447} 463}
448
449/* compat_ioctl file operation. */
450/* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
451long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
452{
453 return raw_ioctl(file, cmd, arg);
454}
diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h
index 2d0a6fcf60f3..5ce77f3e8c22 100644
--- a/drivers/staging/comedi/comedi_compat32.h
+++ b/drivers/staging/comedi/comedi_compat32.h
@@ -1,23 +1,23 @@
1/* 1/*
2 comedi/comedi_compat32.h 2 * comedi/comedi_compat32.h
3 32-bit ioctl compatibility for 64-bit comedi kernel module. 3 * 32-bit ioctl compatibility for 64-bit comedi kernel module.
4 4 *
5 Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk> 5 * Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
6 Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/> 6 * Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
7 7 *
8 COMEDI - Linux Control and Measurement Device Interface 8 * COMEDI - Linux Control and Measurement Device Interface
9 Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org> 9 * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
10 10 *
11 This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 * (at your option) any later version.
15 15 *
16 This program is distributed in the hope that it will be useful, 16 * This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 * GNU General Public License for more details.
20*/ 20 */
21 21
22#ifndef _COMEDI_COMPAT32_H 22#ifndef _COMEDI_COMPAT32_H
23#define _COMEDI_COMPAT32_H 23#define _COMEDI_COMPAT32_H
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index f143cb64d69e..727640e89c73 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1,20 +1,20 @@
1/* 1/*
2 comedi/comedi_fops.c 2 * comedi/comedi_fops.c
3 comedi kernel module 3 * comedi kernel module
4 4 *
5 COMEDI - Linux Control and Measurement Device Interface 5 * COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> 6 * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17*/ 17 */
18 18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 20
@@ -113,6 +113,18 @@ static void comedi_dev_kref_release(struct kref *kref)
113 kfree(dev); 113 kfree(dev);
114} 114}
115 115
116/**
117 * comedi_dev_put - release a use of a comedi device structure
118 * @dev: comedi_device struct
119 *
120 * Must be called when a user of a comedi device is finished with it.
121 * When the last user of the comedi device calls this function, the
122 * comedi device is destroyed.
123 *
124 * Return 1 if the comedi device is destroyed by this call or dev is
125 * NULL, otherwise return 0. Callers must not assume the comedi
126 * device is still valid if this function returns 0.
127 */
116int comedi_dev_put(struct comedi_device *dev) 128int comedi_dev_put(struct comedi_device *dev)
117{ 129{
118 if (dev) 130 if (dev)
@@ -220,6 +232,18 @@ static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor)
220 return dev; 232 return dev;
221} 233}
222 234
235/**
236 * comedi_dev_get_from_minor - get comedi device by minor device number
237 * @minor: minor device number
238 *
239 * Finds the comedi device associated by the minor device number, if any,
240 * and increments its reference count. The comedi device is prevented from
241 * being freed until a matching call is made to comedi_dev_put().
242 *
243 * Return a pointer to the comedi device if it exists, with its usage
244 * reference incremented. Return NULL if no comedi device exists with the
245 * specified minor device number.
246 */
223struct comedi_device *comedi_dev_get_from_minor(unsigned minor) 247struct comedi_device *comedi_dev_get_from_minor(unsigned minor)
224{ 248{
225 if (minor < COMEDI_NUM_BOARD_MINORS) 249 if (minor < COMEDI_NUM_BOARD_MINORS)
@@ -323,8 +347,7 @@ static int resize_async_buffer(struct comedi_device *dev,
323 return -EBUSY; 347 return -EBUSY;
324 } 348 }
325 349
326 /* make sure buffer is an integral number of pages 350 /* make sure buffer is an integral number of pages (we round up) */
327 * (we round up) */
328 new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; 351 new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
329 352
330 retval = comedi_buf_alloc(dev, s, new_size); 353 retval = comedi_buf_alloc(dev, s, new_size);
@@ -600,11 +623,18 @@ static unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
600 return runflags; 623 return runflags;
601} 624}
602 625
626/**
627 * comedi_is_subdevice_running - check if async command running on subdevice
628 * @s: comedi_subdevice struct
629 *
630 * Return true if an asynchronous comedi command is active on the comedi
631 * subdevice, else return false.
632 */
603bool comedi_is_subdevice_running(struct comedi_subdevice *s) 633bool comedi_is_subdevice_running(struct comedi_subdevice *s)
604{ 634{
605 unsigned runflags = comedi_get_subdevice_runflags(s); 635 unsigned runflags = comedi_get_subdevice_runflags(s);
606 636
607 return (runflags & SRF_RUNNING) ? true : false; 637 return (runflags & COMEDI_SRF_RUNNING) ? true : false;
608} 638}
609EXPORT_SYMBOL_GPL(comedi_is_subdevice_running); 639EXPORT_SYMBOL_GPL(comedi_is_subdevice_running);
610 640
@@ -612,14 +642,14 @@ static bool comedi_is_subdevice_in_error(struct comedi_subdevice *s)
612{ 642{
613 unsigned runflags = comedi_get_subdevice_runflags(s); 643 unsigned runflags = comedi_get_subdevice_runflags(s);
614 644
615 return (runflags & SRF_ERROR) ? true : false; 645 return (runflags & COMEDI_SRF_ERROR) ? true : false;
616} 646}
617 647
618static bool comedi_is_subdevice_idle(struct comedi_subdevice *s) 648static bool comedi_is_subdevice_idle(struct comedi_subdevice *s)
619{ 649{
620 unsigned runflags = comedi_get_subdevice_runflags(s); 650 unsigned runflags = comedi_get_subdevice_runflags(s);
621 651
622 return (runflags & (SRF_ERROR | SRF_RUNNING)) ? false : true; 652 return (runflags & COMEDI_SRF_BUSY_MASK) ? false : true;
623} 653}
624 654
625/** 655/**
@@ -634,20 +664,20 @@ void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
634{ 664{
635 s->private = kzalloc(size, GFP_KERNEL); 665 s->private = kzalloc(size, GFP_KERNEL);
636 if (s->private) 666 if (s->private)
637 s->runflags |= SRF_FREE_SPRIV; 667 s->runflags |= COMEDI_SRF_FREE_SPRIV;
638 return s->private; 668 return s->private;
639} 669}
640EXPORT_SYMBOL_GPL(comedi_alloc_spriv); 670EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
641 671
642/* 672/*
643 This function restores a subdevice to an idle state. 673 * This function restores a subdevice to an idle state.
644 */ 674 */
645static void do_become_nonbusy(struct comedi_device *dev, 675static void do_become_nonbusy(struct comedi_device *dev,
646 struct comedi_subdevice *s) 676 struct comedi_subdevice *s)
647{ 677{
648 struct comedi_async *async = s->async; 678 struct comedi_async *async = s->async;
649 679
650 comedi_set_subdevice_runflags(s, SRF_RUNNING, 0); 680 comedi_set_subdevice_runflags(s, COMEDI_SRF_RUNNING, 0);
651 if (async) { 681 if (async) {
652 comedi_buf_reset(s); 682 comedi_buf_reset(s);
653 async->inttrig = NULL; 683 async->inttrig = NULL;
@@ -709,18 +739,18 @@ static int is_device_busy(struct comedi_device *dev)
709} 739}
710 740
711/* 741/*
712 COMEDI_DEVCONFIG 742 * COMEDI_DEVCONFIG ioctl
713 device config ioctl 743 * attaches (and configures) or detaches a legacy device
714 744 *
715 arg: 745 * arg:
716 pointer to devconfig structure 746 * pointer to comedi_devconfig structure (NULL if detaching)
717 747 *
718 reads: 748 * reads:
719 devconfig structure at arg 749 * comedi_devconfig structure (if attaching)
720 750 *
721 writes: 751 * writes:
722 none 752 * nothing
723*/ 753 */
724static int do_devconfig_ioctl(struct comedi_device *dev, 754static int do_devconfig_ioctl(struct comedi_device *dev,
725 struct comedi_devconfig __user *arg) 755 struct comedi_devconfig __user *arg)
726{ 756{
@@ -761,19 +791,18 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
761} 791}
762 792
763/* 793/*
764 COMEDI_BUFCONFIG 794 * COMEDI_BUFCONFIG ioctl
765 buffer configuration ioctl 795 * buffer configuration
766 796 *
767 arg: 797 * arg:
768 pointer to bufconfig structure 798 * pointer to comedi_bufconfig structure
769 799 *
770 reads: 800 * reads:
771 bufconfig at arg 801 * comedi_bufconfig structure
772 802 *
773 writes: 803 * writes:
774 modified bufconfig at arg 804 * modified comedi_bufconfig structure
775 805 */
776*/
777static int do_bufconfig_ioctl(struct comedi_device *dev, 806static int do_bufconfig_ioctl(struct comedi_device *dev,
778 struct comedi_bufconfig __user *arg) 807 struct comedi_bufconfig __user *arg)
779{ 808{
@@ -823,19 +852,18 @@ copyback:
823} 852}
824 853
825/* 854/*
826 COMEDI_DEVINFO 855 * COMEDI_DEVINFO ioctl
827 device info ioctl 856 * device info
828 857 *
829 arg: 858 * arg:
830 pointer to devinfo structure 859 * pointer to comedi_devinfo structure
831 860 *
832 reads: 861 * reads:
833 none 862 * nothing
834 863 *
835 writes: 864 * writes:
836 devinfo structure 865 * comedi_devinfo structure
837 866 */
838*/
839static int do_devinfo_ioctl(struct comedi_device *dev, 867static int do_devinfo_ioctl(struct comedi_device *dev,
840 struct comedi_devinfo __user *arg, 868 struct comedi_devinfo __user *arg,
841 struct file *file) 869 struct file *file)
@@ -870,19 +898,18 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
870} 898}
871 899
872/* 900/*
873 COMEDI_SUBDINFO 901 * COMEDI_SUBDINFO ioctl
874 subdevice info ioctl 902 * subdevices info
875 903 *
876 arg: 904 * arg:
877 pointer to array of subdevice info structures 905 * pointer to array of comedi_subdinfo structures
878 906 *
879 reads: 907 * reads:
880 none 908 * nothing
881 909 *
882 writes: 910 * writes:
883 array of subdevice info structures at arg 911 * array of comedi_subdinfo structures
884 912 */
885*/
886static int do_subdinfo_ioctl(struct comedi_device *dev, 913static int do_subdinfo_ioctl(struct comedi_device *dev,
887 struct comedi_subdinfo __user *arg, void *file) 914 struct comedi_subdinfo __user *arg, void *file)
888{ 915{
@@ -944,19 +971,19 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
944} 971}
945 972
946/* 973/*
947 COMEDI_CHANINFO 974 * COMEDI_CHANINFO ioctl
948 subdevice info ioctl 975 * subdevice channel info
949 976 *
950 arg: 977 * arg:
951 pointer to chaninfo structure 978 * pointer to comedi_chaninfo structure
952 979 *
953 reads: 980 * reads:
954 chaninfo structure at arg 981 * comedi_chaninfo structure
955 982 *
956 writes: 983 * writes:
957 arrays at elements of chaninfo structure 984 * array of maxdata values to chaninfo->maxdata_list if requested
958 985 * array of range table lengths to chaninfo->range_table_list if requested
959*/ 986 */
960static int do_chaninfo_ioctl(struct comedi_device *dev, 987static int do_chaninfo_ioctl(struct comedi_device *dev,
961 struct comedi_chaninfo __user *arg) 988 struct comedi_chaninfo __user *arg)
962{ 989{
@@ -1004,20 +1031,19 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
1004 return 0; 1031 return 0;
1005} 1032}
1006 1033
1007 /* 1034/*
1008 COMEDI_BUFINFO 1035 * COMEDI_BUFINFO ioctl
1009 buffer information ioctl 1036 * buffer information
1010 1037 *
1011 arg: 1038 * arg:
1012 pointer to bufinfo structure 1039 * pointer to comedi_bufinfo structure
1013 1040 *
1014 reads: 1041 * reads:
1015 bufinfo at arg 1042 * comedi_bufinfo structure
1016 1043 *
1017 writes: 1044 * writes:
1018 modified bufinfo at arg 1045 * modified comedi_bufinfo structure
1019 1046 */
1020 */
1021static int do_bufinfo_ioctl(struct comedi_device *dev, 1047static int do_bufinfo_ioctl(struct comedi_device *dev,
1022 struct comedi_bufinfo __user *arg, void *file) 1048 struct comedi_bufinfo __user *arg, void *file)
1023{ 1049{
@@ -1135,8 +1161,10 @@ static int check_insn_config_length(struct comedi_insn *insn,
1135 if (insn->n == 6) 1161 if (insn->n == 6)
1136 return 0; 1162 return 0;
1137 break; 1163 break;
1138 /* by default we allow the insn since we don't have checks for 1164 /*
1139 * all possible cases yet */ 1165 * by default we allow the insn since we don't have checks for
1166 * all possible cases yet
1167 */
1140 default: 1168 default:
1141 pr_warn("No check for data length of config insn id %i is implemented\n", 1169 pr_warn("No check for data length of config insn id %i is implemented\n",
1142 data[0]); 1170 data[0]);
@@ -1287,9 +1315,11 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
1287 if (insn->n != 2) { 1315 if (insn->n != 2) {
1288 ret = -EINVAL; 1316 ret = -EINVAL;
1289 } else { 1317 } else {
1290 /* Most drivers ignore the base channel in 1318 /*
1319 * Most drivers ignore the base channel in
1291 * insn->chanspec. Fix this here if 1320 * insn->chanspec. Fix this here if
1292 * the subdevice has <= 32 channels. */ 1321 * the subdevice has <= 32 channels.
1322 */
1293 unsigned int orig_mask = data[0]; 1323 unsigned int orig_mask = data[0];
1294 unsigned int shift = 0; 1324 unsigned int shift = 0;
1295 1325
@@ -1326,19 +1356,19 @@ out:
1326} 1356}
1327 1357
1328/* 1358/*
1329 * COMEDI_INSNLIST 1359 * COMEDI_INSNLIST ioctl
1330 * synchronous instructions 1360 * synchronous instruction list
1331 * 1361 *
1332 * arg: 1362 * arg:
1333 * pointer to sync cmd structure 1363 * pointer to comedi_insnlist structure
1334 * 1364 *
1335 * reads: 1365 * reads:
1336 * sync cmd struct at arg 1366 * comedi_insnlist structure
1337 * instruction list 1367 * array of comedi_insn structures from insnlist->insns pointer
1338 * data (for writes) 1368 * data (for writes) from insns[].data pointers
1339 * 1369 *
1340 * writes: 1370 * writes:
1341 * data (for reads) 1371 * data (for reads) to insns[].data pointers
1342 */ 1372 */
1343/* arbitrary limits */ 1373/* arbitrary limits */
1344#define MAX_SAMPLES 256 1374#define MAX_SAMPLES 256
@@ -1415,18 +1445,18 @@ error:
1415} 1445}
1416 1446
1417/* 1447/*
1418 * COMEDI_INSN 1448 * COMEDI_INSN ioctl
1419 * synchronous instructions 1449 * synchronous instruction
1420 * 1450 *
1421 * arg: 1451 * arg:
1422 * pointer to insn 1452 * pointer to comedi_insn structure
1423 * 1453 *
1424 * reads: 1454 * reads:
1425 * struct comedi_insn struct at arg 1455 * comedi_insn structure
1426 * data (for writes) 1456 * data (for writes) from insn->data pointer
1427 * 1457 *
1428 * writes: 1458 * writes:
1429 * data (for reads) 1459 * data (for reads) to insn->data pointer
1430 */ 1460 */
1431static int do_insn_ioctl(struct comedi_device *dev, 1461static int do_insn_ioctl(struct comedi_device *dev,
1432 struct comedi_insn __user *arg, void *file) 1462 struct comedi_insn __user *arg, void *file)
@@ -1558,6 +1588,20 @@ static int __comedi_get_user_chanlist(struct comedi_device *dev,
1558 return 0; 1588 return 0;
1559} 1589}
1560 1590
1591/*
1592 * COMEDI_CMD ioctl
1593 * asynchronous acquisition command set-up
1594 *
1595 * arg:
1596 * pointer to comedi_cmd structure
1597 *
1598 * reads:
1599 * comedi_cmd structure
1600 * channel/range list from cmd->chanlist pointer
1601 *
1602 * writes:
1603 * possibly modified comedi_cmd structure (when -EAGAIN returned)
1604 */
1561static int do_cmd_ioctl(struct comedi_device *dev, 1605static int do_cmd_ioctl(struct comedi_device *dev,
1562 struct comedi_cmd __user *arg, void *file) 1606 struct comedi_cmd __user *arg, void *file)
1563{ 1607{
@@ -1634,10 +1678,13 @@ static int do_cmd_ioctl(struct comedi_device *dev,
1634 if (async->cmd.flags & CMDF_WAKE_EOS) 1678 if (async->cmd.flags & CMDF_WAKE_EOS)
1635 async->cb_mask |= COMEDI_CB_EOS; 1679 async->cb_mask |= COMEDI_CB_EOS;
1636 1680
1637 comedi_set_subdevice_runflags(s, SRF_ERROR | SRF_RUNNING, SRF_RUNNING); 1681 comedi_set_subdevice_runflags(s, COMEDI_SRF_BUSY_MASK,
1682 COMEDI_SRF_RUNNING);
1638 1683
1639 /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with 1684 /*
1640 * comedi_read() or comedi_write() */ 1685 * Set s->busy _after_ setting COMEDI_SRF_RUNNING flag to avoid
1686 * race with comedi_read() or comedi_write().
1687 */
1641 s->busy = file; 1688 s->busy = file;
1642 ret = s->do_cmd(dev, s); 1689 ret = s->do_cmd(dev, s);
1643 if (ret == 0) 1690 if (ret == 0)
@@ -1650,20 +1697,19 @@ cleanup:
1650} 1697}
1651 1698
1652/* 1699/*
1653 COMEDI_CMDTEST 1700 * COMEDI_CMDTEST ioctl
1654 command testing ioctl 1701 * asynchronous aquisition command testing
1655 1702 *
1656 arg: 1703 * arg:
1657 pointer to cmd structure 1704 * pointer to comedi_cmd structure
1658 1705 *
1659 reads: 1706 * reads:
1660 cmd structure at arg 1707 * comedi_cmd structure
1661 channel/range list 1708 * channel/range list from cmd->chanlist pointer
1662 1709 *
1663 writes: 1710 * writes:
1664 modified cmd structure at arg 1711 * possibly modified comedi_cmd structure
1665 1712 */
1666*/
1667static int do_cmdtest_ioctl(struct comedi_device *dev, 1713static int do_cmdtest_ioctl(struct comedi_device *dev,
1668 struct comedi_cmd __user *arg, void *file) 1714 struct comedi_cmd __user *arg, void *file)
1669{ 1715{
@@ -1706,20 +1752,18 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
1706} 1752}
1707 1753
1708/* 1754/*
1709 COMEDI_LOCK 1755 * COMEDI_LOCK ioctl
1710 lock subdevice 1756 * lock subdevice
1711 1757 *
1712 arg: 1758 * arg:
1713 subdevice number 1759 * subdevice number
1714 1760 *
1715 reads: 1761 * reads:
1716 none 1762 * nothing
1717 1763 *
1718 writes: 1764 * writes:
1719 none 1765 * nothing
1720 1766 */
1721*/
1722
1723static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg, 1767static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
1724 void *file) 1768 void *file)
1725{ 1769{
@@ -1742,21 +1786,18 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
1742} 1786}
1743 1787
1744/* 1788/*
1745 COMEDI_UNLOCK 1789 * COMEDI_UNLOCK ioctl
1746 unlock subdevice 1790 * unlock subdevice
1747 1791 *
1748 arg: 1792 * arg:
1749 subdevice number 1793 * subdevice number
1750 1794 *
1751 reads: 1795 * reads:
1752 none 1796 * nothing
1753 1797 *
1754 writes: 1798 * writes:
1755 none 1799 * nothing
1756 1800 */
1757 This function isn't protected by the semaphore, since
1758 we already own the lock.
1759*/
1760static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg, 1801static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
1761 void *file) 1802 void *file)
1762{ 1803{
@@ -1779,19 +1820,18 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
1779} 1820}
1780 1821
1781/* 1822/*
1782 COMEDI_CANCEL 1823 * COMEDI_CANCEL ioctl
1783 cancel acquisition ioctl 1824 * cancel asynchronous acquisition
1784 1825 *
1785 arg: 1826 * arg:
1786 subdevice number 1827 * subdevice number
1787 1828 *
1788 reads: 1829 * reads:
1789 nothing 1830 * nothing
1790 1831 *
1791 writes: 1832 * writes:
1792 nothing 1833 * nothing
1793 1834 */
1794*/
1795static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg, 1835static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
1796 void *file) 1836 void *file)
1797{ 1837{
@@ -1813,19 +1853,18 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
1813} 1853}
1814 1854
1815/* 1855/*
1816 COMEDI_POLL ioctl 1856 * COMEDI_POLL ioctl
1817 instructs driver to synchronize buffers 1857 * instructs driver to synchronize buffers
1818 1858 *
1819 arg: 1859 * arg:
1820 subdevice number 1860 * subdevice number
1821 1861 *
1822 reads: 1862 * reads:
1823 nothing 1863 * nothing
1824 1864 *
1825 writes: 1865 * writes:
1826 nothing 1866 * nothing
1827 1867 */
1828*/
1829static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg, 1868static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg,
1830 void *file) 1869 void *file)
1831{ 1870{
@@ -1941,8 +1980,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
1941 1980
1942 mutex_lock(&dev->mutex); 1981 mutex_lock(&dev->mutex);
1943 1982
1944 /* Device config is special, because it must work on 1983 /*
1945 * an unconfigured device. */ 1984 * Device config is special, because it must work on
1985 * an unconfigured device.
1986 */
1946 if (cmd == COMEDI_DEVCONFIG) { 1987 if (cmd == COMEDI_DEVCONFIG) {
1947 if (minor >= COMEDI_NUM_BOARD_MINORS) { 1988 if (minor >= COMEDI_NUM_BOARD_MINORS) {
1948 /* Device config not appropriate on non-board minors. */ 1989 /* Device config not appropriate on non-board minors. */
@@ -1954,8 +1995,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
1954 if (rc == 0) { 1995 if (rc == 0) {
1955 if (arg == 0 && 1996 if (arg == 0 &&
1956 dev->minor >= comedi_num_legacy_minors) { 1997 dev->minor >= comedi_num_legacy_minors) {
1957 /* Successfully unconfigured a dynamically 1998 /*
1958 * allocated device. Try and remove it. */ 1999 * Successfully unconfigured a dynamically
2000 * allocated device. Try and remove it.
2001 */
1959 if (comedi_clear_board_dev(dev)) { 2002 if (comedi_clear_board_dev(dev)) {
1960 mutex_unlock(&dev->mutex); 2003 mutex_unlock(&dev->mutex);
1961 comedi_free_board_dev(dev); 2004 comedi_free_board_dev(dev);
@@ -2581,6 +2624,17 @@ static const struct file_operations comedi_fops = {
2581 .llseek = noop_llseek, 2624 .llseek = noop_llseek,
2582}; 2625};
2583 2626
2627/**
2628 * comedi_event - handle events for asynchronous comedi command
2629 * @dev: comedi_device struct
2630 * @s: comedi_subdevice struct associated with dev
2631 * Context: interrupt (usually), s->spin_lock spin-lock not held
2632 *
2633 * If an asynchronous comedi command is active on the subdevice, process
2634 * any COMEDI_CB_... event flags that have been set, usually by an
2635 * interrupt handler. These may change the run state of the asynchronous
2636 * command, wake a task, and/or send a SIGIO signal.
2637 */
2584void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) 2638void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
2585{ 2639{
2586 struct comedi_async *async = s->async; 2640 struct comedi_async *async = s->async;
@@ -2591,18 +2645,21 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
2591 return; 2645 return;
2592 2646
2593 if (s->async->events & COMEDI_CB_CANCEL_MASK) 2647 if (s->async->events & COMEDI_CB_CANCEL_MASK)
2594 runflags_mask |= SRF_RUNNING; 2648 runflags_mask |= COMEDI_SRF_RUNNING;
2595 2649
2596 /* 2650 /*
2597 * Remember if an error event has occurred, so an error 2651 * Remember if an error event has occurred, so an error
2598 * can be returned the next time the user does a read(). 2652 * can be returned the next time the user does a read().
2599 */ 2653 */
2600 if (s->async->events & COMEDI_CB_ERROR_MASK) { 2654 if (s->async->events & COMEDI_CB_ERROR_MASK) {
2601 runflags_mask |= SRF_ERROR; 2655 runflags_mask |= COMEDI_SRF_ERROR;
2602 runflags |= SRF_ERROR; 2656 runflags |= COMEDI_SRF_ERROR;
2603 } 2657 }
2604 if (runflags_mask) { 2658 if (runflags_mask) {
2605 /*sets SRF_ERROR and SRF_RUNNING together atomically */ 2659 /*
2660 * Sets COMEDI_SRF_ERROR and COMEDI_SRF_RUNNING together
2661 * atomically.
2662 */
2606 comedi_set_subdevice_runflags(s, runflags_mask, runflags); 2663 comedi_set_subdevice_runflags(s, runflags_mask, runflags);
2607 } 2664 }
2608 2665
diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c
index 0529bae8e5ac..7e784399a16f 100644
--- a/drivers/staging/comedi/comedi_pcmcia.c
+++ b/drivers/staging/comedi/comedi_pcmcia.c
@@ -19,10 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21 21
22#include <pcmcia/cistpl.h> 22#include "comedi_pcmcia.h"
23#include <pcmcia/ds.h>
24
25#include "comedidev.h"
26 23
27/** 24/**
28 * comedi_to_pcmcia_dev() - comedi_device pointer to pcmcia_device pointer. 25 * comedi_to_pcmcia_dev() - comedi_device pointer to pcmcia_device pointer.
diff --git a/drivers/staging/comedi/comedi_pcmcia.h b/drivers/staging/comedi/comedi_pcmcia.h
new file mode 100644
index 000000000000..5d3db2b9b4a1
--- /dev/null
+++ b/drivers/staging/comedi/comedi_pcmcia.h
@@ -0,0 +1,55 @@
1/*
2 * comedi_pcmcia.h
3 * header file for Comedi PCMCIA drivers
4 *
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#ifndef _COMEDI_PCMCIA_H
20#define _COMEDI_PCMCIA_H
21
22#include <pcmcia/cistpl.h>
23#include <pcmcia/ds.h>
24
25#include "comedidev.h"
26
27struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *);
28
29int comedi_pcmcia_enable(struct comedi_device *,
30 int (*conf_check)(struct pcmcia_device *, void *));
31void comedi_pcmcia_disable(struct comedi_device *);
32
33int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *);
34void comedi_pcmcia_auto_unconfig(struct pcmcia_device *);
35
36int comedi_pcmcia_driver_register(struct comedi_driver *,
37 struct pcmcia_driver *);
38void comedi_pcmcia_driver_unregister(struct comedi_driver *,
39 struct pcmcia_driver *);
40
41/**
42 * module_comedi_pcmcia_driver() - Helper macro for registering a comedi PCMCIA driver
43 * @__comedi_driver: comedi_driver struct
44 * @__pcmcia_driver: pcmcia_driver struct
45 *
46 * Helper macro for comedi PCMCIA drivers which do not do anything special
47 * in module init/exit. This eliminates a lot of boilerplate. Each
48 * module may only use this macro once, and calling it replaces
49 * module_init() and module_exit()
50 */
51#define module_comedi_pcmcia_driver(__comedi_driver, __pcmcia_driver) \
52 module_driver(__comedi_driver, comedi_pcmcia_driver_register, \
53 comedi_pcmcia_driver_unregister, &(__pcmcia_driver))
54
55#endif /* _COMEDI_PCMCIA_H */
diff --git a/drivers/staging/comedi/comedi_usb.c b/drivers/staging/comedi/comedi_usb.c
index 0b862a64c049..68b75e8feec0 100644
--- a/drivers/staging/comedi/comedi_usb.c
+++ b/drivers/staging/comedi/comedi_usb.c
@@ -17,9 +17,8 @@
17 */ 17 */
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/usb.h>
21 20
22#include "comedidev.h" 21#include "comedi_usb.h"
23 22
24/** 23/**
25 * comedi_to_usb_interface() - comedi_device pointer to usb_interface pointer. 24 * comedi_to_usb_interface() - comedi_device pointer to usb_interface pointer.
diff --git a/drivers/staging/comedi/comedi_usb.h b/drivers/staging/comedi/comedi_usb.h
new file mode 100644
index 000000000000..721128bece3c
--- /dev/null
+++ b/drivers/staging/comedi/comedi_usb.h
@@ -0,0 +1,50 @@
1/*
2 * comedi_usb.h
3 * header file for USB Comedi drivers
4 *
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#ifndef _COMEDI_USB_H
20#define _COMEDI_USB_H
21
22#include <linux/usb.h>
23
24#include "comedidev.h"
25
26struct usb_interface *comedi_to_usb_interface(struct comedi_device *);
27struct usb_device *comedi_to_usb_dev(struct comedi_device *);
28
29int comedi_usb_auto_config(struct usb_interface *, struct comedi_driver *,
30 unsigned long context);
31void comedi_usb_auto_unconfig(struct usb_interface *);
32
33int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *);
34void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *);
35
36/**
37 * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver
38 * @__comedi_driver: comedi_driver struct
39 * @__usb_driver: usb_driver struct
40 *
41 * Helper macro for comedi USB drivers which do not do anything special
42 * in module init/exit. This eliminates a lot of boilerplate. Each
43 * module may only use this macro once, and calling it replaces
44 * module_init() and module_exit()
45 */
46#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \
47 module_driver(__comedi_driver, comedi_usb_driver_register, \
48 comedi_usb_driver_unregister, &(__usb_driver))
49
50#endif /* _COMEDI_USB_H */
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 77be191988ca..e138eb0dc374 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -299,34 +299,25 @@ struct comedi_device {
299 299
300void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s); 300void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
301 301
302/* we can expand the number of bits used to encode devices/subdevices into
303 the minor number soon, after more distros support > 8 bit minor numbers
304 (like after Debian Etch gets released) */
305enum comedi_minor_bits {
306 COMEDI_DEVICE_MINOR_MASK = 0xf,
307 COMEDI_SUBDEVICE_MINOR_MASK = 0xf0
308};
309
310static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
311static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
312
313struct comedi_device *comedi_dev_get_from_minor(unsigned minor); 302struct comedi_device *comedi_dev_get_from_minor(unsigned minor);
314int comedi_dev_put(struct comedi_device *dev); 303int comedi_dev_put(struct comedi_device *dev);
315 304
316void init_polling(void); 305/**
317void cleanup_polling(void); 306 * comedi_subdevice "runflags"
318void start_polling(struct comedi_device *); 307 * @COMEDI_SRF_RT: DEPRECATED: command is running real-time
319void stop_polling(struct comedi_device *); 308 * @COMEDI_SRF_ERROR: indicates an COMEDI_CB_ERROR event has occurred
320 309 * since the last command was started
321/* subdevice runflags */ 310 * @COMEDI_SRF_RUNNING: command is running
322enum subdevice_runflags { 311 * @COMEDI_SRF_FREE_SPRIV: free s->private on detach
323 SRF_RT = 0x00000002, 312 *
324 /* indicates an COMEDI_CB_ERROR event has occurred since the last 313 * @COMEDI_SRF_BUSY_MASK: runflags that indicate the subdevice is "busy"
325 * command was started */ 314 */
326 SRF_ERROR = 0x00000004, 315#define COMEDI_SRF_RT BIT(1)
327 SRF_RUNNING = 0x08000000, 316#define COMEDI_SRF_ERROR BIT(2)
328 SRF_FREE_SPRIV = 0x80000000, /* free s->private on detach */ 317#define COMEDI_SRF_RUNNING BIT(27)
329}; 318#define COMEDI_SRF_FREE_SPRIV BIT(31)
319
320#define COMEDI_SRF_BUSY_MASK (COMEDI_SRF_ERROR | COMEDI_SRF_RUNNING)
330 321
331bool comedi_is_subdevice_running(struct comedi_subdevice *s); 322bool comedi_is_subdevice_running(struct comedi_subdevice *s);
332 323
@@ -605,66 +596,4 @@ void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *);
605 module_driver(__comedi_driver, comedi_pci_driver_register, \ 596 module_driver(__comedi_driver, comedi_pci_driver_register, \
606 comedi_pci_driver_unregister, &(__pci_driver)) 597 comedi_pci_driver_unregister, &(__pci_driver))
607 598
608/* comedi_pcmcia.c - comedi PCMCIA driver specific functions */
609
610struct pcmcia_driver;
611struct pcmcia_device;
612
613struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *);
614
615int comedi_pcmcia_enable(struct comedi_device *,
616 int (*conf_check)(struct pcmcia_device *, void *));
617void comedi_pcmcia_disable(struct comedi_device *);
618
619int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *);
620void comedi_pcmcia_auto_unconfig(struct pcmcia_device *);
621
622int comedi_pcmcia_driver_register(struct comedi_driver *,
623 struct pcmcia_driver *);
624void comedi_pcmcia_driver_unregister(struct comedi_driver *,
625 struct pcmcia_driver *);
626
627/**
628 * module_comedi_pcmcia_driver() - Helper macro for registering a comedi PCMCIA driver
629 * @__comedi_driver: comedi_driver struct
630 * @__pcmcia_driver: pcmcia_driver struct
631 *
632 * Helper macro for comedi PCMCIA drivers which do not do anything special
633 * in module init/exit. This eliminates a lot of boilerplate. Each
634 * module may only use this macro once, and calling it replaces
635 * module_init() and module_exit()
636 */
637#define module_comedi_pcmcia_driver(__comedi_driver, __pcmcia_driver) \
638 module_driver(__comedi_driver, comedi_pcmcia_driver_register, \
639 comedi_pcmcia_driver_unregister, &(__pcmcia_driver))
640
641/* comedi_usb.c - comedi USB driver specific functions */
642
643struct usb_driver;
644struct usb_interface;
645
646struct usb_interface *comedi_to_usb_interface(struct comedi_device *);
647struct usb_device *comedi_to_usb_dev(struct comedi_device *);
648
649int comedi_usb_auto_config(struct usb_interface *, struct comedi_driver *,
650 unsigned long context);
651void comedi_usb_auto_unconfig(struct usb_interface *);
652
653int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *);
654void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *);
655
656/**
657 * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver
658 * @__comedi_driver: comedi_driver struct
659 * @__usb_driver: usb_driver struct
660 *
661 * Helper macro for comedi USB drivers which do not do anything special
662 * in module init/exit. This eliminates a lot of boilerplate. Each
663 * module may only use this macro once, and calling it replaces
664 * module_init() and module_exit()
665 */
666#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \
667 module_driver(__comedi_driver, comedi_usb_driver_register, \
668 comedi_usb_driver_unregister, &(__usb_driver))
669
670#endif /* _COMEDIDEV_H */ 599#endif /* _COMEDIDEV_H */
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 61802d7947ae..f32e71438948 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -125,7 +125,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev)
125 if (dev->subdevices) { 125 if (dev->subdevices) {
126 for (i = 0; i < dev->n_subdevices; i++) { 126 for (i = 0; i < dev->n_subdevices; i++) {
127 s = &dev->subdevices[i]; 127 s = &dev->subdevices[i];
128 if (s->runflags & SRF_FREE_SPRIV) 128 if (s->runflags & COMEDI_SRF_FREE_SPRIV)
129 kfree(s->private); 129 kfree(s->private);
130 comedi_free_subdevice_minor(s); 130 comedi_free_subdevice_minor(s);
131 if (s->async) { 131 if (s->async) {
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
index 9f4c1411719d..51b9c8d279c0 100644
--- a/drivers/staging/comedi/drivers/8253.h
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -1,20 +1,20 @@
1/* 1/*
2 comedi/drivers/8253.h 2 * comedi/drivers/8253.h
3 Header file for 8253 3 * Header file for 8253
4 4 *
5 COMEDI - Linux Control and Measurement Device Interface 5 * COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17*/ 17 */
18 18
19#ifndef _8253_H 19#ifndef _8253_H
20#define _8253_H 20#define _8253_H
@@ -44,9 +44,11 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
44 unsigned int start; 44 unsigned int start;
45 unsigned int ns_low, ns_high; 45 unsigned int ns_low, ns_high;
46 static const unsigned int max_count = 0x10000; 46 static const unsigned int max_count = 0x10000;
47 /* exit early if everything is already correct (this can save time 47 /*
48 * exit early if everything is already correct (this can save time
48 * since this function may be called repeatedly during command tests 49 * since this function may be called repeatedly during command tests
49 * and execution) */ 50 * and execution)
51 */
50 div1 = *d1 ? *d1 : max_count; 52 div1 = *d1 ? *d1 : max_count;
51 div2 = *d2 ? *d2 : max_count; 53 div2 = *d2 ? *d2 : max_count;
52 divider = div1 * div2; 54 divider = div1 * div2;
@@ -114,13 +116,14 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
114 } 116 }
115 117
116 *nanosec = div1 * div2 * i8253_osc_base; 118 *nanosec = div1 * div2 * i8253_osc_base;
117 /* masking is done since counter maps zero to 0x10000 */ 119 /* masking is done since counter maps zero to 0x10000 */
118 *d1 = div1 & 0xffff; 120 *d1 = div1 & 0xffff;
119 *d2 = div2 & 0xffff; 121 *d2 = div2 & 0xffff;
120} 122}
121 123
122#ifndef CMDTEST 124#ifndef CMDTEST
123/* i8254_load programs 8254 counter chip. It should also work for the 8253. 125/*
126 * i8254_load programs 8254 counter chip. It should also work for the 8253.
124 * base_address is the lowest io address 127 * base_address is the lowest io address
125 * for the chip (the address of counter 0). 128 * for the chip (the address of counter 0).
126 * counter_number is the counter you want to load (0,1 or 2) 129 * counter_number is the counter you want to load (0,1 or 2)
@@ -158,12 +161,12 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift,
158 return -1; 161 return -1;
159 162
160 byte = counter_number << 6; 163 byte = counter_number << 6;
161 byte |= 0x30; /* load low then high byte */ 164 byte |= 0x30; /* load low then high byte */
162 byte |= (mode << 1); /* set counter mode */ 165 byte |= (mode << 1); /* set counter mode */
163 outb(byte, base_address + (i8254_control_reg << regshift)); 166 outb(byte, base_address + (i8254_control_reg << regshift));
164 byte = count & 0xff; /* lsb of counter value */ 167 byte = count & 0xff; /* lsb of counter value */
165 outb(byte, base_address + (counter_number << regshift)); 168 outb(byte, base_address + (counter_number << regshift));
166 byte = (count >> 8) & 0xff; /* msb of counter value */ 169 byte = (count >> 8) & 0xff; /* msb of counter value */
167 outb(byte, base_address + (counter_number << regshift)); 170 outb(byte, base_address + (counter_number << regshift));
168 171
169 return 0; 172 return 0;
@@ -187,18 +190,18 @@ static inline int i8254_mm_load(void __iomem *base_address,
187 return -1; 190 return -1;
188 191
189 byte = counter_number << 6; 192 byte = counter_number << 6;
190 byte |= 0x30; /* load low then high byte */ 193 byte |= 0x30; /* load low then high byte */
191 byte |= (mode << 1); /* set counter mode */ 194 byte |= (mode << 1); /* set counter mode */
192 writeb(byte, base_address + (i8254_control_reg << regshift)); 195 writeb(byte, base_address + (i8254_control_reg << regshift));
193 byte = count & 0xff; /* lsb of counter value */ 196 byte = count & 0xff; /* lsb of counter value */
194 writeb(byte, base_address + (counter_number << regshift)); 197 writeb(byte, base_address + (counter_number << regshift));
195 byte = (count >> 8) & 0xff; /* msb of counter value */ 198 byte = (count >> 8) & 0xff; /* msb of counter value */
196 writeb(byte, base_address + (counter_number << regshift)); 199 writeb(byte, base_address + (counter_number << regshift));
197 200
198 return 0; 201 return 0;
199} 202}
200 203
201/* Returns 16 bit counter value, should work for 8253 also.*/ 204/* Returns 16 bit counter value, should work for 8253 also. */
202static inline int i8254_read(unsigned long base_address, unsigned int regshift, 205static inline int i8254_read(unsigned long base_address, unsigned int regshift,
203 unsigned int counter_number) 206 unsigned int counter_number)
204{ 207{
@@ -208,13 +211,13 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift,
208 if (counter_number > 2) 211 if (counter_number > 2)
209 return -1; 212 return -1;
210 213
211 /* latch counter */ 214 /* latch counter */
212 byte = counter_number << 6; 215 byte = counter_number << 6;
213 outb(byte, base_address + (i8254_control_reg << regshift)); 216 outb(byte, base_address + (i8254_control_reg << regshift));
214 217
215 /* read lsb */ 218 /* read lsb */
216 ret = inb(base_address + (counter_number << regshift)); 219 ret = inb(base_address + (counter_number << regshift));
217 /* read msb */ 220 /* read msb */
218 ret += inb(base_address + (counter_number << regshift)) << 8; 221 ret += inb(base_address + (counter_number << regshift)) << 8;
219 222
220 return ret; 223 return ret;
@@ -230,13 +233,13 @@ static inline int i8254_mm_read(void __iomem *base_address,
230 if (counter_number > 2) 233 if (counter_number > 2)
231 return -1; 234 return -1;
232 235
233 /* latch counter */ 236 /* latch counter */
234 byte = counter_number << 6; 237 byte = counter_number << 6;
235 writeb(byte, base_address + (i8254_control_reg << regshift)); 238 writeb(byte, base_address + (i8254_control_reg << regshift));
236 239
237 /* read lsb */ 240 /* read lsb */
238 ret = readb(base_address + (counter_number << regshift)); 241 ret = readb(base_address + (counter_number << regshift));
239 /* read msb */ 242 /* read msb */
240 ret += readb(base_address + (counter_number << regshift)) << 8; 243 ret += readb(base_address + (counter_number << regshift)) << 8;
241 244
242 return ret; 245 return ret;
@@ -252,9 +255,9 @@ static inline void i8254_write(unsigned long base_address,
252 if (counter_number > 2) 255 if (counter_number > 2)
253 return; 256 return;
254 257
255 byte = count & 0xff; /* lsb of counter value */ 258 byte = count & 0xff; /* lsb of counter value */
256 outb(byte, base_address + (counter_number << regshift)); 259 outb(byte, base_address + (counter_number << regshift));
257 byte = (count >> 8) & 0xff; /* msb of counter value */ 260 byte = (count >> 8) & 0xff; /* msb of counter value */
258 outb(byte, base_address + (counter_number << regshift)); 261 outb(byte, base_address + (counter_number << regshift));
259} 262}
260 263
@@ -268,13 +271,14 @@ static inline void i8254_mm_write(void __iomem *base_address,
268 if (counter_number > 2) 271 if (counter_number > 2)
269 return; 272 return;
270 273
271 byte = count & 0xff; /* lsb of counter value */ 274 byte = count & 0xff; /* lsb of counter value */
272 writeb(byte, base_address + (counter_number << regshift)); 275 writeb(byte, base_address + (counter_number << regshift));
273 byte = (count >> 8) & 0xff; /* msb of counter value */ 276 byte = (count >> 8) & 0xff; /* msb of counter value */
274 writeb(byte, base_address + (counter_number << regshift)); 277 writeb(byte, base_address + (counter_number << regshift));
275} 278}
276 279
277/* Set counter mode, should work for 8253 also. 280/*
281 * Set counter mode, should work for 8253 also.
278 * Note: the 'mode' value is different to that for i8254_load() and comes 282 * Note: the 'mode' value is different to that for i8254_load() and comes
279 * from the INSN_CONFIG_8254_SET_MODE command: 283 * from the INSN_CONFIG_8254_SET_MODE command:
280 * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5 284 * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
@@ -293,8 +297,8 @@ static inline int i8254_set_mode(unsigned long base_address,
293 return -1; 297 return -1;
294 298
295 byte = counter_number << 6; 299 byte = counter_number << 6;
296 byte |= 0x30; /* load low then high byte */ 300 byte |= 0x30; /* load low then high byte */
297 byte |= mode; /* set counter mode and BCD|binary */ 301 byte |= mode; /* set counter mode and BCD|binary */
298 outb(byte, base_address + (i8254_control_reg << regshift)); 302 outb(byte, base_address + (i8254_control_reg << regshift));
299 303
300 return 0; 304 return 0;
@@ -313,8 +317,8 @@ static inline int i8254_mm_set_mode(void __iomem *base_address,
313 return -1; 317 return -1;
314 318
315 byte = counter_number << 6; 319 byte = counter_number << 6;
316 byte |= 0x30; /* load low then high byte */ 320 byte |= 0x30; /* load low then high byte */
317 byte |= mode; /* set counter mode and BCD|binary */ 321 byte |= mode; /* set counter mode and BCD|binary */
318 writeb(byte, base_address + (i8254_control_reg << regshift)); 322 writeb(byte, base_address + (i8254_control_reg << regshift));
319 323
320 return 0; 324 return 0;
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index 34d4d8b5f31e..c2f15de6a547 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -1,76 +1,51 @@
1/* 1/*
2 comedi/drivers/8255.c 2 * comedi/drivers/8255.c
3 Driver for 8255 3 * Driver for 8255
4 4 *
5 COMEDI - Linux Control and Measurement Device Interface 5 * COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1998 David A. Schleef <ds@schleef.org> 6 * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17*/ 17 */
18/*
19Driver: 8255
20Description: generic 8255 support
21Devices: [standard] 8255 (8255)
22Author: ds
23Status: works
24Updated: Fri, 7 Jun 2002 12:56:45 -0700
25
26The classic in digital I/O. The 8255 appears in Comedi as a single
27digital I/O subdevice with 24 channels. The channel 0 corresponds
28to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
297. Direction configuration is done in blocks, with channels 0-7,
308-15, 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
31supported is mode 0.
32
33You should enable compilation this driver if you plan to use a board
34that has an 8255 chip. For multifunction boards, the main driver will
35configure the 8255 subdevice automatically.
36
37This driver also works independently with ISA and PCI cards that
38directly map the 8255 registers to I/O ports, including cards with
39multiple 8255 chips. To configure the driver for such a card, the
40option list should be a list of the I/O port bases for each of the
418255 chips. For example,
42
43 comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
44
45Note that most PCI 8255 boards do NOT work with this driver, and
46need a separate driver as a wrapper. For those that do work, the
47I/O port base address can be found in the output of 'lspci -v'.
48
49*/
50 18
51/* 19/*
52 This file contains an exported subdevice for driving an 8255. 20 * Driver: 8255
53 21 * Description: generic 8255 support
54 To use this subdevice as part of another driver, you need to 22 * Devices: [standard] 8255 (8255)
55 set up the subdevice in the attach function of the driver by 23 * Author: ds
56 calling: 24 * Status: works
57 25 * Updated: Fri, 7 Jun 2002 12:56:45 -0700
58 subdev_8255_init(device, subdevice, io_function, iobase) 26 *
59 27 * The classic in digital I/O. The 8255 appears in Comedi as a single
60 device and subdevice are pointers to the device and subdevice 28 * digital I/O subdevice with 24 channels. The channel 0 corresponds
61 structures. io_function will be called to provide the 29 * to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
62 low-level input/output to the device, i.e., actual register 30 * 7. Direction configuration is done in blocks, with channels 0-7,
63 access. io_function will be called with the value of iobase 31 * 8-15, 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
64 as the last parameter. If the 8255 device is mapped as 4 32 * supported is mode 0.
65 consecutive I/O ports, you can use NULL for io_function 33 *
66 and the I/O port base for iobase, and an internal function will 34 * You should enable compilation this driver if you plan to use a board
67 handle the register access. 35 * that has an 8255 chip. For multifunction boards, the main driver will
68 36 * configure the 8255 subdevice automatically.
69 In addition, if the main driver handles interrupts, you can 37 *
70 enable commands on the subdevice by calling subdev_8255_init_irq() 38 * This driver also works independently with ISA and PCI cards that
71 instead. Then, when you get an interrupt that is likely to be 39 * directly map the 8255 registers to I/O ports, including cards with
72 from the 8255, you should call subdev_8255_interrupt(), which 40 * multiple 8255 chips. To configure the driver for such a card, the
73 will copy the latched value to a Comedi buffer. 41 * option list should be a list of the I/O port bases for each of the
42 * 8255 chips. For example,
43 *
44 * comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
45 *
46 * Note that most PCI 8255 boards do NOT work with this driver, and
47 * need a separate driver as a wrapper. For those that do work, the
48 * I/O port base address can be found in the output of 'lspci -v'.
74 */ 49 */
75 50
76#include <linux/module.h> 51#include <linux/module.h>
@@ -218,6 +193,33 @@ static int __subdev_8255_init(struct comedi_device *dev,
218 return 0; 193 return 0;
219} 194}
220 195
196/**
197 * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255
198 * @dev: comedi device owning subdevice
199 * @s: comedi subdevice to initialize
200 * @io: (optional) register I/O call-back function
201 * @regbase: offset of 8255 registers from dev->iobase, or call-back context
202 *
203 * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
204 *
205 * If the optional I/O call-back function is provided, its prototype is of
206 * the following form:
207 *
208 * int my_8255_callback(struct comedi_device *dev,
209 * struct comedi_subdevice *s, int dir, int port,
210 * int data, unsigned long regbase);
211 *
212 * where 'dev', 's', and 'regbase' match the values passed to this function,
213 * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
214 * is the direction (0 for read, 1 for write) and 'data' is the value to be
215 * written. It should return 0 if writing or the value read if reading.
216 *
217 * If the optional I/O call-back function is not provided, an internal
218 * call-back function is used which uses consecutive I/O port addresses
219 * starting at dev->iobase + regbase.
220 *
221 * Return: -ENOMEM if failed to allocate memory, zero on success.
222 */
221int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, 223int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
222 int (*io)(struct comedi_device *, 224 int (*io)(struct comedi_device *,
223 int, int, int, unsigned long), 225 int, int, int, unsigned long),
@@ -227,6 +229,33 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
227} 229}
228EXPORT_SYMBOL_GPL(subdev_8255_init); 230EXPORT_SYMBOL_GPL(subdev_8255_init);
229 231
232/**
233 * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255
234 * @dev: comedi device owning subdevice
235 * @s: comedi subdevice to initialize
236 * @io: (optional) register I/O call-back function
237 * @regbase: offset of 8255 registers from dev->mmio, or call-back context
238 *
239 * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
240 *
241 * If the optional I/O call-back function is provided, its prototype is of
242 * the following form:
243 *
244 * int my_8255_callback(struct comedi_device *dev,
245 * struct comedi_subdevice *s, int dir, int port,
246 * int data, unsigned long regbase);
247 *
248 * where 'dev', 's', and 'regbase' match the values passed to this function,
249 * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
250 * is the direction (0 for read, 1 for write) and 'data' is the value to be
251 * written. It should return 0 if writing or the value read if reading.
252 *
253 * If the optional I/O call-back function is not provided, an internal
254 * call-back function is used which uses consecutive MMIO virtual addresses
255 * starting at dev->mmio + regbase.
256 *
257 * Return: -ENOMEM if failed to allocate memory, zero on success.
258 */
230int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, 259int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
231 int (*io)(struct comedi_device *, 260 int (*io)(struct comedi_device *,
232 int, int, int, unsigned long), 261 int, int, int, unsigned long),
@@ -235,10 +264,9 @@ int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
235 return __subdev_8255_init(dev, s, io, regbase, true); 264 return __subdev_8255_init(dev, s, io, regbase, true);
236} 265}
237EXPORT_SYMBOL_GPL(subdev_8255_mm_init); 266EXPORT_SYMBOL_GPL(subdev_8255_mm_init);
238/*
239
240 Start of the 8255 standalone device
241 267
268/*
269 * Start of the 8255 standalone device
242 */ 270 */
243 271
244static int dev_8255_attach(struct comedi_device *dev, 272static int dev_8255_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
index 5985c8e0330f..934b940ebd3c 100644
--- a/drivers/staging/comedi/drivers/8255.h
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -1,20 +1,20 @@
1/* 1/*
2 module/8255.h 2 * module/8255.h
3 Header file for 8255 3 * Header file for 8255
4 4 *
5 COMEDI - Linux Control and Measurement Device Interface 5 * COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1998 David A. Schleef <ds@schleef.org> 6 * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17*/ 17 */
18 18
19#ifndef _8255_H 19#ifndef _8255_H
20#define _8255_H 20#define _8255_H
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index 8b9589828855..984764211a2d 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -22,33 +22,44 @@
22 */ 22 */
23 23
24/* 24/*
25Driver: 8255_pci 25 * Driver: 8255_pci
26Description: Generic PCI based 8255 Digital I/O boards 26 * Description: Generic PCI based 8255 Digital I/O boards
27Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels 27 * Devices: [ADLink] PCI-7224 (adl_pci-7224), PCI-7248 (adl_pci-7248),
28 (ADLink) PCI-7248 [adl_pci-7248] - 48 channels 28 * PCI-7296 (adl_pci-7296),
29 (ADLink) PCI-7296 [adl_pci-7296] - 96 channels 29 * [Measurement Computing] PCI-DIO24 (cb_pci-dio24),
30 (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels 30 * PCI-DIO24H (cb_pci-dio24h), PCI-DIO48H (cb_pci-dio48h),
31 (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels 31 * PCI-DIO96H (cb_pci-dio96h),
32 (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels 32 * [National Instruments] PCI-DIO-96 (ni_pci-dio-96),
33 (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels 33 * PCI-DIO-96B (ni_pci-dio-96b), PXI-6508 (ni_pxi-6508),
34 (National Instruments) PCI-DIO-96 [ni_pci-dio-96] - 96 channels 34 * PCI-6503 (ni_pci-6503), PCI-6503B (ni_pci-6503b),
35 (National Instruments) PCI-DIO-96B [ni_pci-dio-96b] - 96 channels 35 * PCI-6503X (ni_pci-6503x), PXI-6503 (ni_pxi-6503)
36 (National Instruments) PXI-6508 [ni_pxi-6508] - 96 channels 36 * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
37 (National Instruments) PCI-6503 [ni_pci-6503] - 24 channels 37 * Updated: Wed, 12 Sep 2012 11:52:01 -0700
38 (National Instruments) PCI-6503B [ni_pci-6503b] - 24 channels 38 * Status: untested
39 (National Instruments) PCI-6503X [ni_pci-6503x] - 24 channels 39 *
40 (National Instruments) PXI-6503 [ni_pxi-6503] - 24 channels 40 * These boards have one or more 8255 digital I/O chips, each of which
41Author: H Hartley Sweeten <hsweeten@visionengravers.com> 41 * is supported as a separate 24-channel DIO subdevice.
42Updated: Wed, 12 Sep 2012 11:52:01 -0700 42 *
43Status: untested 43 * Boards with 24 DIO channels (1 DIO subdevice):
44 44 *
45Some of these boards also have an 8254 programmable timer/counter 45 * PCI-7224, PCI-DIO24, PCI-DIO24H, PCI-6503, PCI-6503B, PCI-6503X,
46chip. This chip is not currently supported by this driver. 46 * PXI-6503
47 47 *
48Interrupt support for these boards is also not currently supported. 48 * Boards with 48 DIO channels (2 DIO subdevices):
49 49 *
50Configuration Options: not applicable, uses PCI auto config 50 * PCI-7248, PCI-DIO48H
51*/ 51 *
52 * Boards with 96 DIO channels (4 DIO subdevices):
53 *
54 * PCI-7296, PCI-DIO96H, PCI-DIO-96, PCI-DIO-96B, PXI-6508
55 *
56 * Some of these boards also have an 8254 programmable timer/counter
57 * chip. This chip is not currently supported by this driver.
58 *
59 * Interrupt support for these boards is also not currently supported.
60 *
61 * Configuration Options: not applicable, uses PCI auto config.
62 */
52 63
53#include <linux/module.h> 64#include <linux/module.h>
54#include <linux/pci.h> 65#include <linux/pci.h>
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 84fdf20ca986..7d1fbd53a8ab 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -3,6 +3,7 @@
3ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG 3ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG
4 4
5# Comedi "helper" modules 5# Comedi "helper" modules
6obj-$(CONFIG_COMEDI_ISADMA) += comedi_isadma.o
6 7
7# Comedi misc drivers 8# Comedi misc drivers
8obj-$(CONFIG_COMEDI_BOND) += comedi_bond.o 9obj-$(CONFIG_COMEDI_BOND) += comedi_bond.o
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
deleted file mode 100644
index bfa9228c833f..000000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ /dev/null
@@ -1,2365 +0,0 @@
1/*
2 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
3 *
4 * ADDI-DATA GmbH
5 * Dieselstrasse 3
6 * D-77833 Ottersweier
7 * Tel: +19(0)7223/9493-0
8 * Fax: +49(0)7223/9493-92
9 * http://www.addi-data.com
10 * info@addi-data.com
11 *
12 * This program is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License as published by the Free Software
14 * Foundation; either version 2 of the License, or (at your option) any later
15 * version.
16 *
17 * This program is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20 * details.
21 *
22 */
23
24/* Card Specific information */
25#define APCI1500_ADDRESS_RANGE 4
26
27/* DIGITAL INPUT-OUTPUT DEFINE */
28
29#define APCI1500_DIGITAL_OP 2
30#define APCI1500_DIGITAL_IP 0
31#define APCI1500_AND 2
32#define APCI1500_OR 4
33#define APCI1500_OR_PRIORITY 6
34#define APCI1500_CLK_SELECT 0
35#define COUNTER1 0
36#define COUNTER2 1
37#define COUNTER3 2
38#define APCI1500_COUNTER 0x20
39#define APCI1500_TIMER 0
40#define APCI1500_WATCHDOG 0
41#define APCI1500_SINGLE 0
42#define APCI1500_CONTINUOUS 0x80
43#define APCI1500_DISABLE 0
44#define APCI1500_ENABLE 1
45#define APCI1500_SOFTWARE_TRIGGER 0x4
46#define APCI1500_HARDWARE_TRIGGER 0x10
47#define APCI1500_SOFTWARE_GATE 0
48#define APCI1500_HARDWARE_GATE 0x8
49#define START 0
50#define STOP 1
51#define TRIGGER 2
52
53/*
54 * Zillog I/O enumeration
55 */
56enum {
57 APCI1500_Z8536_PORT_C,
58 APCI1500_Z8536_PORT_B,
59 APCI1500_Z8536_PORT_A,
60 APCI1500_Z8536_CONTROL_REGISTER
61};
62
63/*
64 * Z8536 CIO Internal Address
65 */
66enum {
67 APCI1500_RW_MASTER_INTERRUPT_CONTROL,
68 APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
69 APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
70 APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
71 APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
72 APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
73 APCI1500_RW_PORT_C_DATA_DIRECTION,
74 APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
75
76 APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
77 APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
78 APCI1500_RW_CPT_TMR1_CMD_STATUS,
79 APCI1500_RW_CPT_TMR2_CMD_STATUS,
80 APCI1500_RW_CPT_TMR3_CMD_STATUS,
81 APCI1500_RW_PORT_A_DATA,
82 APCI1500_RW_PORT_B_DATA,
83 APCI1500_RW_PORT_C_DATA,
84
85 APCI1500_R_CPT_TMR1_VALUE_HIGH,
86 APCI1500_R_CPT_TMR1_VALUE_LOW,
87 APCI1500_R_CPT_TMR2_VALUE_HIGH,
88 APCI1500_R_CPT_TMR2_VALUE_LOW,
89 APCI1500_R_CPT_TMR3_VALUE_HIGH,
90 APCI1500_R_CPT_TMR3_VALUE_LOW,
91 APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
92 APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
93 APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
94 APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
95 APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
96 APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
97 APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
98 APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
99 APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
100 APCI1500_R_CURRENT_VECTOR,
101
102 APCI1500_RW_PORT_A_SPECIFICATION,
103 APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
104 APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
105 APCI1500_RW_PORT_A_DATA_DIRECTION,
106 APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
107 APCI1500_RW_PORT_A_PATTERN_POLARITY,
108 APCI1500_RW_PORT_A_PATTERN_TRANSITION,
109 APCI1500_RW_PORT_A_PATTERN_MASK,
110
111 APCI1500_RW_PORT_B_SPECIFICATION,
112 APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
113 APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
114 APCI1500_RW_PORT_B_DATA_DIRECTION,
115 APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
116 APCI1500_RW_PORT_B_PATTERN_POLARITY,
117 APCI1500_RW_PORT_B_PATTERN_TRANSITION,
118 APCI1500_RW_PORT_B_PATTERN_MASK
119};
120
121static int i_TimerCounter1Init;
122static int i_TimerCounter2Init;
123static int i_WatchdogCounter3Init;
124static int i_Event1Status, i_Event2Status;
125static int i_TimerCounterWatchdogInterrupt;
126static int i_Logic, i_CounterLogic;
127static int i_InterruptMask;
128static int i_InputChannel;
129static int i_TimerCounter1Enabled, i_TimerCounter2Enabled,
130 i_WatchdogCounter3Enabled;
131
132/*
133 * An event can be generated for each port. The first event is related to the
134 * first 8 channels (port 1) and the second to the following 6 channels (port 2)
135 * An interrupt is generated when one or both events have occurred.
136 *
137 * data[0] Number of the input port on which the event will take place (1 or 2)
138 * data[1] The event logic for port 1 has three possibilities:
139 * APCI1500_AND This logic links the inputs with an AND logic.
140 * APCI1500_OR This logic links the inputs with a OR logic.
141 * APCI1500_OR_PRIORITY This logic links the inputs with a priority OR
142 * logic. Input 1 has the highest priority level
143 * and input 8 the smallest.
144 * For the second port the user has 1 possibility:
145 * APCI1500_OR This logic links the inputs with a polarity OR logic
146 * data[2] These 8-character word for port1 and 6-character word for port 2
147 * give the mask of the event. Each place gives the state of the input
148 * channels and can have one of these six characters
149 * 0 This input must be on 0
150 * 1 This input must be on 1
151 * 2 This input reacts to a falling edge
152 * 3 This input reacts to a rising edge
153 * 4 This input reacts to both edges
154 * 5 This input is not used for event
155 */
156static int apci1500_di_config(struct comedi_device *dev,
157 struct comedi_subdevice *s,
158 struct comedi_insn *insn,
159 unsigned int *data)
160{
161 struct apci1500_private *devpriv = dev->private;
162 int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
163 int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
164 int i_PatternTransitionCount = 0, i_RegValue;
165 int i;
166
167 /* Selects the master interrupt control register */
168 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
169 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
170 /* Disables the main interrupt on the board */
171 outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
172
173 if (data[0] == 1) {
174 i_MaxChannel = 8;
175 } else {
176 if (data[0] == 2) {
177 i_MaxChannel = 6;
178 } else {
179 dev_warn(dev->class_dev,
180 "The specified port event does not exist\n");
181 return -EINVAL;
182 }
183 }
184 switch (data[1]) {
185 case 0:
186 data[1] = APCI1500_AND;
187 break;
188 case 1:
189 data[1] = APCI1500_OR;
190 break;
191 case 2:
192 data[1] = APCI1500_OR_PRIORITY;
193 break;
194 default:
195 dev_warn(dev->class_dev,
196 "The specified interrupt logic does not exist\n");
197 return -EINVAL;
198 }
199
200 i_Logic = data[1];
201 for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
202 i_EventMask = data[2 + i];
203 switch (i_EventMask) {
204 case 0:
205 i_PatternMask =
206 i_PatternMask | (1 << (i_MaxChannel - i_Count));
207 break;
208 case 1:
209 i_PatternMask =
210 i_PatternMask | (1 << (i_MaxChannel - i_Count));
211 i_PatternPolarity =
212 i_PatternPolarity | (1 << (i_MaxChannel -
213 i_Count));
214 break;
215 case 2:
216 i_PatternMask =
217 i_PatternMask | (1 << (i_MaxChannel - i_Count));
218 i_PatternTransition =
219 i_PatternTransition | (1 << (i_MaxChannel -
220 i_Count));
221 break;
222 case 3:
223 i_PatternMask =
224 i_PatternMask | (1 << (i_MaxChannel - i_Count));
225 i_PatternPolarity =
226 i_PatternPolarity | (1 << (i_MaxChannel -
227 i_Count));
228 i_PatternTransition =
229 i_PatternTransition | (1 << (i_MaxChannel -
230 i_Count));
231 break;
232 case 4:
233 i_PatternTransition =
234 i_PatternTransition | (1 << (i_MaxChannel -
235 i_Count));
236 break;
237 case 5:
238 break;
239 default:
240 dev_warn(dev->class_dev,
241 "The option indicated in the event mask does not exist\n");
242 return -EINVAL;
243 }
244 }
245
246 if (data[0] == 1) {
247 /* Test the interrupt logic */
248
249 if (data[1] == APCI1500_AND ||
250 data[1] == APCI1500_OR ||
251 data[1] == APCI1500_OR_PRIORITY) {
252 /* Tests if a transition was declared */
253 /* for a OR PRIORITY logic */
254
255 if (data[1] == APCI1500_OR_PRIORITY
256 && i_PatternTransition != 0) {
257 dev_warn(dev->class_dev,
258 "Transition error on an OR PRIORITY logic\n");
259 return -EINVAL;
260 }
261
262 /* Tests if more than one transition */
263 /* was declared for an AND logic */
264
265 if (data[1] == APCI1500_AND) {
266 for (i_Count = 0; i_Count < 8; i_Count++) {
267 i_PatternTransitionCount =
268 i_PatternTransitionCount +
269 ((i_PatternTransition >>
270 i_Count) & 0x1);
271
272 }
273
274 if (i_PatternTransitionCount > 1) {
275 dev_warn(dev->class_dev,
276 "Transition error on an AND logic\n");
277 return -EINVAL;
278 }
279 }
280
281 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
282 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
283 devpriv->iobase +
284 APCI1500_Z8536_CONTROL_REGISTER);
285 /* Disable Port A */
286 outb(0xF0,
287 devpriv->iobase +
288 APCI1500_Z8536_CONTROL_REGISTER);
289 /* Selects the polarity register of port 1 */
290 outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
291 devpriv->iobase +
292 APCI1500_Z8536_CONTROL_REGISTER);
293 outb(i_PatternPolarity,
294 devpriv->iobase +
295 APCI1500_Z8536_CONTROL_REGISTER);
296
297 /* Selects the pattern mask register of */
298 /* port 1 */
299 outb(APCI1500_RW_PORT_A_PATTERN_MASK,
300 devpriv->iobase +
301 APCI1500_Z8536_CONTROL_REGISTER);
302 outb(i_PatternMask,
303 devpriv->iobase +
304 APCI1500_Z8536_CONTROL_REGISTER);
305 /* Selects the pattern transition register */
306 /* of port 1 */
307 outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
308 devpriv->iobase +
309 APCI1500_Z8536_CONTROL_REGISTER);
310 outb(i_PatternTransition,
311 devpriv->iobase +
312 APCI1500_Z8536_CONTROL_REGISTER);
313
314 /* Selects the mode specification mask */
315 /* register of port 1 */
316 outb(APCI1500_RW_PORT_A_SPECIFICATION,
317 devpriv->iobase +
318 APCI1500_Z8536_CONTROL_REGISTER);
319 i_RegValue =
320 inb(devpriv->iobase +
321 APCI1500_Z8536_CONTROL_REGISTER);
322
323 /* Selects the mode specification mask */
324 /* register of port 1 */
325 outb(APCI1500_RW_PORT_A_SPECIFICATION,
326 devpriv->iobase +
327 APCI1500_Z8536_CONTROL_REGISTER);
328
329 /* Port A new mode */
330
331 i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
332 outb(i_RegValue,
333 devpriv->iobase +
334 APCI1500_Z8536_CONTROL_REGISTER);
335
336 i_Event1Status = 1;
337
338 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
339
340 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
341 devpriv->iobase +
342 APCI1500_Z8536_CONTROL_REGISTER);
343 /* Enable Port A */
344 outb(0xF4,
345 devpriv->iobase +
346 APCI1500_Z8536_CONTROL_REGISTER);
347
348 } else {
349 dev_warn(dev->class_dev,
350 "The choice for interrupt logic does not exist\n");
351 return -EINVAL;
352 }
353 }
354
355 /* Test if event setting for port 2 */
356
357 if (data[0] == 2) {
358 /* Test the event logic */
359
360 if (data[1] == APCI1500_OR) {
361 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
362 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
363 devpriv->iobase +
364 APCI1500_Z8536_CONTROL_REGISTER);
365 /* Disable Port B */
366 outb(0x74,
367 devpriv->iobase +
368 APCI1500_Z8536_CONTROL_REGISTER);
369 /* Selects the mode specification mask */
370 /* register of port B */
371 outb(APCI1500_RW_PORT_B_SPECIFICATION,
372 devpriv->iobase +
373 APCI1500_Z8536_CONTROL_REGISTER);
374 i_RegValue =
375 inb(devpriv->iobase +
376 APCI1500_Z8536_CONTROL_REGISTER);
377
378 /* Selects the mode specification mask */
379 /* register of port B */
380 outb(APCI1500_RW_PORT_B_SPECIFICATION,
381 devpriv->iobase +
382 APCI1500_Z8536_CONTROL_REGISTER);
383 i_RegValue = i_RegValue & 0xF9;
384 outb(i_RegValue,
385 devpriv->iobase +
386 APCI1500_Z8536_CONTROL_REGISTER);
387
388 /* Selects error channels 1 and 2 */
389
390 i_PatternMask = (i_PatternMask | 0xC0);
391 i_PatternPolarity = (i_PatternPolarity | 0xC0);
392 i_PatternTransition = (i_PatternTransition | 0xC0);
393
394 /* Selects the polarity register of port 2 */
395 outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
396 devpriv->iobase +
397 APCI1500_Z8536_CONTROL_REGISTER);
398 outb(i_PatternPolarity,
399 devpriv->iobase +
400 APCI1500_Z8536_CONTROL_REGISTER);
401 /* Selects the pattern transition register */
402 /* of port 2 */
403 outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
404 devpriv->iobase +
405 APCI1500_Z8536_CONTROL_REGISTER);
406 outb(i_PatternTransition,
407 devpriv->iobase +
408 APCI1500_Z8536_CONTROL_REGISTER);
409 /* Selects the pattern Mask register */
410 /* of port 2 */
411
412 outb(APCI1500_RW_PORT_B_PATTERN_MASK,
413 devpriv->iobase +
414 APCI1500_Z8536_CONTROL_REGISTER);
415 outb(i_PatternMask,
416 devpriv->iobase +
417 APCI1500_Z8536_CONTROL_REGISTER);
418
419 /* Selects the mode specification mask */
420 /* register of port 2 */
421 outb(APCI1500_RW_PORT_B_SPECIFICATION,
422 devpriv->iobase +
423 APCI1500_Z8536_CONTROL_REGISTER);
424 i_RegValue =
425 inb(devpriv->iobase +
426 APCI1500_Z8536_CONTROL_REGISTER);
427 /* Selects the mode specification mask */
428 /* register of port 2 */
429 outb(APCI1500_RW_PORT_B_SPECIFICATION,
430 devpriv->iobase +
431 APCI1500_Z8536_CONTROL_REGISTER);
432 i_RegValue = (i_RegValue & 0xF9) | 4;
433 outb(i_RegValue,
434 devpriv->iobase +
435 APCI1500_Z8536_CONTROL_REGISTER);
436
437 i_Event2Status = 1;
438 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
439
440 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
441 devpriv->iobase +
442 APCI1500_Z8536_CONTROL_REGISTER);
443 /* Enable Port B */
444
445 outb(0xF4,
446 devpriv->iobase +
447 APCI1500_Z8536_CONTROL_REGISTER);
448 } else {
449 dev_warn(dev->class_dev,
450 "The choice for interrupt logic does not exist\n");
451 return -EINVAL;
452 }
453 }
454
455 return insn->n;
456}
457
458/*
459 * Allows or disallows a port event
460 *
461 * data[0] 0 = Start input event, 1 = Stop input event
462 * data[1] Number of port (1 or 2)
463 */
464static int apci1500_di_write(struct comedi_device *dev,
465 struct comedi_subdevice *s,
466 struct comedi_insn *insn,
467 unsigned int *data)
468{
469 struct apci1500_private *devpriv = dev->private;
470 int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
471 0, i_RegValue;
472
473 switch (data[0]) {
474 case START:
475 /* Tests the port number */
476
477 if (data[1] == 1 || data[1] == 2) {
478 /* Test if port 1 selected */
479
480 if (data[1] == 1) {
481 /* Test if event initialised */
482 if (i_Event1Status == 1) {
483 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
484 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
485 /* Disable Port A */
486 outb(0xF0,
487 devpriv->iobase +
488 APCI1500_Z8536_CONTROL_REGISTER);
489 /* Selects the command and status register of */
490 /* port 1 */
491 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
492 /* Allows the pattern interrupt */
493 outb(0xC0,
494 devpriv->iobase +
495 APCI1500_Z8536_CONTROL_REGISTER);
496 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
497 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
498 /* Enable Port A */
499 outb(0xF4,
500 devpriv->iobase +
501 APCI1500_Z8536_CONTROL_REGISTER);
502 i_Event1InterruptStatus = 1;
503 outb(APCI1500_RW_PORT_A_SPECIFICATION,
504 devpriv->iobase +
505 APCI1500_Z8536_CONTROL_REGISTER);
506 i_RegValue =
507 inb(devpriv->iobase +
508 APCI1500_Z8536_CONTROL_REGISTER);
509
510 /* Selects the master interrupt control register */
511 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
512 /* Authorizes the main interrupt on the board */
513 outb(0xD0,
514 devpriv->iobase +
515 APCI1500_Z8536_CONTROL_REGISTER);
516
517 } else {
518 dev_warn(dev->class_dev,
519 "Event 1 not initialised\n");
520 return -EINVAL;
521 }
522 }
523 if (data[1] == 2) {
524
525 if (i_Event2Status == 1) {
526 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
527 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
528 /* Disable Port B */
529 outb(0x74,
530 devpriv->iobase +
531 APCI1500_Z8536_CONTROL_REGISTER);
532 /* Selects the command and status register of */
533 /* port 2 */
534 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
535 /* Allows the pattern interrupt */
536 outb(0xC0,
537 devpriv->iobase +
538 APCI1500_Z8536_CONTROL_REGISTER);
539 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
540 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
541 /* Enable Port B */
542 outb(0xF4,
543 devpriv->iobase +
544 APCI1500_Z8536_CONTROL_REGISTER);
545
546 /* Selects the master interrupt control register */
547 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
548 /* Authorizes the main interrupt on the board */
549 outb(0xD0,
550 devpriv->iobase +
551 APCI1500_Z8536_CONTROL_REGISTER);
552 i_Event2InterruptStatus = 1;
553 } else {
554 dev_warn(dev->class_dev,
555 "Event 2 not initialised\n");
556 return -EINVAL;
557 }
558 }
559 } else {
560 dev_warn(dev->class_dev,
561 "The port parameter is in error\n");
562 return -EINVAL;
563 }
564
565 break;
566
567 case STOP:
568 /* Tests the port number */
569
570 if (data[1] == 1 || data[1] == 2) {
571 /* Test if port 1 selected */
572
573 if (data[1] == 1) {
574 /* Test if event initialised */
575 if (i_Event1Status == 1) {
576 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
577 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
578 /* Disable Port A */
579 outb(0xF0,
580 devpriv->iobase +
581 APCI1500_Z8536_CONTROL_REGISTER);
582 /* Selects the command and status register of */
583 /* port 1 */
584 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
585 /* Inhibits the pattern interrupt */
586 outb(0xE0,
587 devpriv->iobase +
588 APCI1500_Z8536_CONTROL_REGISTER);
589 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
590 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
591 /* Enable Port A */
592 outb(0xF4,
593 devpriv->iobase +
594 APCI1500_Z8536_CONTROL_REGISTER);
595 i_Event1InterruptStatus = 0;
596 } else {
597 dev_warn(dev->class_dev,
598 "Event 1 not initialised\n");
599 return -EINVAL;
600 }
601 }
602 if (data[1] == 2) {
603 /* Test if event initialised */
604 if (i_Event2Status == 1) {
605 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
606 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
607 /* Disable Port B */
608 outb(0x74,
609 devpriv->iobase +
610 APCI1500_Z8536_CONTROL_REGISTER);
611 /* Selects the command and status register of */
612 /* port 2 */
613 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
614 /* Inhibits the pattern interrupt */
615 outb(0xE0,
616 devpriv->iobase +
617 APCI1500_Z8536_CONTROL_REGISTER);
618 /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
619 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
620 /* Enable Port B */
621 outb(0xF4,
622 devpriv->iobase +
623 APCI1500_Z8536_CONTROL_REGISTER);
624 i_Event2InterruptStatus = 0;
625 } else {
626
627 dev_warn(dev->class_dev,
628 "Event 2 not initialised\n");
629 return -EINVAL;
630 }
631 }
632
633 } else {
634 dev_warn(dev->class_dev,
635 "The port parameter is in error\n");
636 return -EINVAL;
637 }
638 break;
639 default:
640 dev_warn(dev->class_dev,
641 "The option of START/STOP logic does not exist\n");
642 return -EINVAL;
643 }
644
645 return insn->n;
646}
647
648/*
649 * Return the status of the digital input
650 */
651static int apci1500_di_read(struct comedi_device *dev,
652 struct comedi_subdevice *s,
653 struct comedi_insn *insn,
654 unsigned int *data)
655{
656 struct apci1500_private *devpriv = dev->private;
657 int i_DummyRead = 0;
658
659 /* Software reset */
660 i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
661 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
662 i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
663 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
664 outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
665 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
666
667 /* Selects the master configuration control register */
668 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
669 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
670 outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
671
672 /* Selects the mode specification register of port A */
673 outb(APCI1500_RW_PORT_A_SPECIFICATION,
674 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
675 outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
676
677 /* Selects the data path polarity register of port A */
678 outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
679 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
680 /* High level of port A means 1 */
681 outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
682
683 /* Selects the data direction register of port A */
684 outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
685 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
686 /* All bits used as inputs */
687 outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
688 /* Selects the command and status register of port A */
689 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
690 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
691 /* Deletes IP and IUS */
692 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
693 /* Selects the command and status register of port A */
694 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
695 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
696 /* Deactivates the interrupt management of port A: */
697 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
698 /* Selects the handshake specification register of port A */
699 outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
700 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
701 /* Deletes the register */
702 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
703
704 /* Selects the mode specification register of port B */
705 outb(APCI1500_RW_PORT_B_SPECIFICATION,
706 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
707 outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
708 /* Selects the data path polarity register of port B */
709 outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
710 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
711 /* A high level of port B means 1 */
712 outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
713 /* Selects the data direction register of port B */
714 outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
715 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
716 /* All bits used as inputs */
717 outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
718 /* Selects the command and status register of port B */
719 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
720 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
721 /* Deletes IP and IUS */
722 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
723 /* Selects the command and status register of port B */
724 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
725 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
726 /* Deactivates the interrupt management of port B: */
727 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
728 /* Selects the handshake specification register of port B */
729 outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
730 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
731 /* Deletes the register */
732 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
733
734 /* Selects the data path polarity register of port C */
735 outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
736 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
737 /* High level of port C means 1 */
738 outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
739 /* Selects the data direction register of port C */
740 outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
741 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
742 /* All bits used as inputs except channel 1 */
743 outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
744 /* Selects the special IO register of port C */
745 outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
746 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
747 /* Deletes it */
748 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
749 /* Selects the command and status register of timer 1 */
750 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
751 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
752 /* Deletes IP and IUS */
753 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
754 /* Selects the command and status register of timer 1 */
755 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
756 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
757 /* Deactivates the interrupt management of timer 1 */
758 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
759 /* Selects the command and status register of timer 2 */
760 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
761 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
762 /* Deletes IP and IUS */
763 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
764 /* Selects the command and status register of timer 2 */
765 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
766 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
767 /* Deactivates Timer 2 interrupt management: */
768 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
769 /* Selects the command and status register of timer 3 */
770 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
771 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
772 /* Deletes IP and IUS */
773 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
774 /* Selects the command and status register of Timer 3 */
775 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
776 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
777 /* Deactivates interrupt management of timer 3: */
778 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
779 /* Selects the master interrupt control register */
780 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
781 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
782 /* Deletes all interrupts */
783 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
784 return insn->n;
785}
786
787static int apci1500_di_insn_bits(struct comedi_device *dev,
788 struct comedi_subdevice *s,
789 struct comedi_insn *insn,
790 unsigned int *data)
791{
792 struct apci1500_private *devpriv = dev->private;
793
794 data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP);
795
796 return insn->n;
797}
798
799/*
800 * Configures the digital output memory and the digital output error interrupt
801 *
802 * data[1] 1 = Enable the voltage error interrupt
803 * 2 = Disable the voltage error interrupt
804 */
805static int apci1500_do_config(struct comedi_device *dev,
806 struct comedi_subdevice *s,
807 struct comedi_insn *insn,
808 unsigned int *data)
809{
810 struct apci1500_private *devpriv = dev->private;
811
812 devpriv->b_OutputMemoryStatus = data[0];
813 return insn->n;
814}
815
816/*
817 * Writes port value to the selected port
818 */
819static int apci1500_do_write(struct comedi_device *dev,
820 struct comedi_subdevice *s,
821 struct comedi_insn *insn,
822 unsigned int *data)
823{
824 struct apci1500_private *devpriv = dev->private;
825 static unsigned int ui_Temp;
826 unsigned int ui_Temp1;
827 unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
828
829 if (!devpriv->b_OutputMemoryStatus)
830 ui_Temp = 0;
831
832 if (data[3] == 0) {
833 if (data[1] == 0) {
834 data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
835 outw(data[0],
836 devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
837 } else {
838 if (data[1] == 1) {
839 switch (ui_NoOfChannel) {
840
841 case 2:
842 data[0] =
843 (data[0] << (2 *
844 data[2])) | ui_Temp;
845 break;
846
847 case 4:
848 data[0] =
849 (data[0] << (4 *
850 data[2])) | ui_Temp;
851 break;
852
853 case 8:
854 data[0] =
855 (data[0] << (8 *
856 data[2])) | ui_Temp;
857 break;
858
859 case 15:
860 data[0] = data[0] | ui_Temp;
861 break;
862
863 default:
864 dev_err(dev->class_dev,
865 "chan spec wrong\n");
866 return -EINVAL; /* "sorry channel spec wrong " */
867
868 }
869
870 outw(data[0],
871 devpriv->i_IobaseAddon +
872 APCI1500_DIGITAL_OP);
873 } else {
874 dev_warn(dev->class_dev,
875 "Specified channel not supported\n");
876 return -EINVAL;
877 }
878 }
879 } else {
880 if (data[3] == 1) {
881 if (data[1] == 0) {
882 data[0] = ~data[0] & 0x1;
883 ui_Temp1 = 1;
884 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
885 ui_Temp = ui_Temp | ui_Temp1;
886 data[0] =
887 (data[0] << ui_NoOfChannel) ^
888 0xffffffff;
889 data[0] = data[0] & ui_Temp;
890 outw(data[0],
891 devpriv->i_IobaseAddon +
892 APCI1500_DIGITAL_OP);
893 } else {
894 if (data[1] == 1) {
895 switch (ui_NoOfChannel) {
896
897 case 2:
898 data[0] = ~data[0] & 0x3;
899 ui_Temp1 = 3;
900 ui_Temp1 =
901 ui_Temp1 << 2 * data[2];
902 ui_Temp = ui_Temp | ui_Temp1;
903 data[0] =
904 ((data[0] << (2 *
905 data
906 [2])) ^
907 0xffffffff) & ui_Temp;
908 break;
909
910 case 4:
911 data[0] = ~data[0] & 0xf;
912 ui_Temp1 = 15;
913 ui_Temp1 =
914 ui_Temp1 << 4 * data[2];
915 ui_Temp = ui_Temp | ui_Temp1;
916 data[0] =
917 ((data[0] << (4 *
918 data
919 [2])) ^
920 0xffffffff) & ui_Temp;
921 break;
922
923 case 8:
924 data[0] = ~data[0] & 0xff;
925 ui_Temp1 = 255;
926 ui_Temp1 =
927 ui_Temp1 << 8 * data[2];
928 ui_Temp = ui_Temp | ui_Temp1;
929 data[0] =
930 ((data[0] << (8 *
931 data
932 [2])) ^
933 0xffffffff) & ui_Temp;
934 break;
935
936 case 15:
937 break;
938
939 default:
940 dev_err(dev->class_dev,
941 "chan spec wrong\n");
942 return -EINVAL; /* "sorry channel spec wrong " */
943
944 }
945
946 outw(data[0],
947 devpriv->i_IobaseAddon +
948 APCI1500_DIGITAL_OP);
949 } else {
950 dev_warn(dev->class_dev,
951 "Specified channel not supported\n");
952 return -EINVAL;
953 }
954 }
955 } else {
956 dev_warn(dev->class_dev,
957 "Specified functionality does not exist\n");
958 return -EINVAL;
959 }
960 }
961 ui_Temp = data[0];
962 return insn->n;
963}
964
965/*
966 * Configures The Watchdog
967 *
968 * data[0] 0 = APCI1500_115_KHZ, 1 = APCI1500_3_6_KHZ, 2 = APCI1500_1_8_KHZ
969 * data[1] 0 = Counter1/Timer1, 1 = Counter2/Timer2, 2 = Counter3/Watchdog
970 * data[2] 0 = Counter, 1 = Timer/Watchdog
971 * data[3] This parameter has two meanings. If the counter/timer is used as
972 * a counter the limit value of the counter is given. If the counter/timer
973 * is used as a timer, the divider factor for the output is given.
974 * data[4] 0 = APCI1500_CONTINUOUS, 1 = APCI1500_SINGLE
975 * data[5] 0 = Software Trigger, 1 = Hardware Trigger
976 * data[6] 0 = Software gate, 1 = Hardware gate
977 * data[7] 0 = Interrupt Disable, 1 = Interrupt Enable
978 */
979static int apci1500_timer_config(struct comedi_device *dev,
980 struct comedi_subdevice *s,
981 struct comedi_insn *insn,
982 unsigned int *data)
983{
984 struct apci1500_private *devpriv = dev->private;
985 int i_TimerCounterMode, i_MasterConfiguration;
986
987 devpriv->tsk_Current = current;
988
989 /* Selection of the input clock */
990 if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
991 outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
992 } else {
993 if (data[0] != 3) {
994 dev_warn(dev->class_dev,
995 "The option for input clock selection does not exist\n");
996 return -EINVAL;
997 }
998 }
999 /* Select the counter/timer */
1000 switch (data[1]) {
1001 case COUNTER1:
1002 /* selecting counter or timer */
1003 switch (data[2]) {
1004 case 0:
1005 data[2] = APCI1500_COUNTER;
1006 break;
1007 case 1:
1008 data[2] = APCI1500_TIMER;
1009 break;
1010 default:
1011 dev_warn(dev->class_dev,
1012 "This choice is not a timer nor a counter\n");
1013 return -EINVAL;
1014 }
1015
1016 /* Selecting single or continuous mode */
1017 switch (data[4]) {
1018 case 0:
1019 data[4] = APCI1500_CONTINUOUS;
1020 break;
1021 case 1:
1022 data[4] = APCI1500_SINGLE;
1023 break;
1024 default:
1025 dev_warn(dev->class_dev,
1026 "This option for single/continuous mode does not exist\n");
1027 return -EINVAL;
1028 }
1029
1030 i_TimerCounterMode = data[2] | data[4] | 7;
1031 /* Test the reload value */
1032
1033 if ((data[3] >= 0) && (data[3] <= 65535)) {
1034 if (data[7] == APCI1500_ENABLE
1035 || data[7] == APCI1500_DISABLE) {
1036
1037 /* Selects the mode register of timer/counter 1 */
1038 outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
1039 devpriv->iobase +
1040 APCI1500_Z8536_CONTROL_REGISTER);
1041 /* Writes the new mode */
1042 outb(i_TimerCounterMode,
1043 devpriv->iobase +
1044 APCI1500_Z8536_CONTROL_REGISTER);
1045
1046 /* Selects the constant register of timer/counter 1 */
1047
1048 outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
1049 devpriv->iobase +
1050 APCI1500_Z8536_CONTROL_REGISTER);
1051
1052 /* Writes the low value */
1053
1054 outb(data[3],
1055 devpriv->iobase +
1056 APCI1500_Z8536_CONTROL_REGISTER);
1057
1058 /* Selects the constant register of timer/counter 1 */
1059
1060 outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
1061 devpriv->iobase +
1062 APCI1500_Z8536_CONTROL_REGISTER);
1063
1064 /* Writes the high value */
1065
1066 data[3] = data[3] >> 8;
1067 outb(data[3],
1068 devpriv->iobase +
1069 APCI1500_Z8536_CONTROL_REGISTER);
1070
1071 /* Selects the master configuration register */
1072
1073 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1074 devpriv->iobase +
1075 APCI1500_Z8536_CONTROL_REGISTER);
1076
1077 /* Reads the register */
1078
1079 i_MasterConfiguration =
1080 inb(devpriv->iobase +
1081 APCI1500_Z8536_CONTROL_REGISTER);
1082
1083 /* Enables timer/counter 1 and triggers timer/counter 1 */
1084
1085 i_MasterConfiguration =
1086 i_MasterConfiguration | 0x40;
1087
1088 /* Selects the master configuration register */
1089 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1090 devpriv->iobase +
1091 APCI1500_Z8536_CONTROL_REGISTER);
1092
1093 /* Writes the new configuration */
1094 outb(i_MasterConfiguration,
1095 devpriv->iobase +
1096 APCI1500_Z8536_CONTROL_REGISTER);
1097 /* Selects the commands register of */
1098 /* timer/counter 1 */
1099
1100 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1101 devpriv->iobase +
1102 APCI1500_Z8536_CONTROL_REGISTER);
1103
1104 /* Disable timer/counter 1 */
1105
1106 outb(0x0,
1107 devpriv->iobase +
1108 APCI1500_Z8536_CONTROL_REGISTER);
1109 /* Selects the commands register of */
1110 /* timer/counter 1 */
1111 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1112 devpriv->iobase +
1113 APCI1500_Z8536_CONTROL_REGISTER);
1114
1115 /* Trigger timer/counter 1 */
1116 outb(0x2,
1117 devpriv->iobase +
1118 APCI1500_Z8536_CONTROL_REGISTER);
1119 } else {
1120 dev_warn(dev->class_dev,
1121 "Error in selection of interrupt enable or disable\n");
1122 return -EINVAL;
1123 }
1124 } else {
1125 dev_warn(dev->class_dev,
1126 "Error in selection of reload value\n");
1127 return -EINVAL;
1128 }
1129 i_TimerCounterWatchdogInterrupt = data[7];
1130 i_TimerCounter1Init = 1;
1131 break;
1132
1133 case COUNTER2: /* selecting counter or timer */
1134 switch (data[2]) {
1135 case 0:
1136 data[2] = APCI1500_COUNTER;
1137 break;
1138 case 1:
1139 data[2] = APCI1500_TIMER;
1140 break;
1141 default:
1142 dev_warn(dev->class_dev,
1143 "This choice is not a timer nor a counter\n");
1144 return -EINVAL;
1145 }
1146
1147 /* Selecting single or continuous mode */
1148 switch (data[4]) {
1149 case 0:
1150 data[4] = APCI1500_CONTINUOUS;
1151 break;
1152 case 1:
1153 data[4] = APCI1500_SINGLE;
1154 break;
1155 default:
1156 dev_warn(dev->class_dev,
1157 "This option for single/continuous mode does not exist\n");
1158 return -EINVAL;
1159 }
1160
1161 /* Selecting software or hardware trigger */
1162 switch (data[5]) {
1163 case 0:
1164 data[5] = APCI1500_SOFTWARE_TRIGGER;
1165 break;
1166 case 1:
1167 data[5] = APCI1500_HARDWARE_TRIGGER;
1168 break;
1169 default:
1170 dev_warn(dev->class_dev,
1171 "This choice for software or hardware trigger does not exist\n");
1172 return -EINVAL;
1173 }
1174
1175 /* Selecting software or hardware gate */
1176 switch (data[6]) {
1177 case 0:
1178 data[6] = APCI1500_SOFTWARE_GATE;
1179 break;
1180 case 1:
1181 data[6] = APCI1500_HARDWARE_GATE;
1182 break;
1183 default:
1184 dev_warn(dev->class_dev,
1185 "This choice for software or hardware gate does not exist\n");
1186 return -EINVAL;
1187 }
1188
1189 i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
1190
1191 /* Test the reload value */
1192
1193 if ((data[3] >= 0) && (data[3] <= 65535)) {
1194 if (data[7] == APCI1500_ENABLE
1195 || data[7] == APCI1500_DISABLE) {
1196
1197 /* Selects the mode register of timer/counter 2 */
1198 outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
1199 devpriv->iobase +
1200 APCI1500_Z8536_CONTROL_REGISTER);
1201 /* Writes the new mode */
1202 outb(i_TimerCounterMode,
1203 devpriv->iobase +
1204 APCI1500_Z8536_CONTROL_REGISTER);
1205
1206 /* Selects the constant register of timer/counter 2 */
1207
1208 outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
1209 devpriv->iobase +
1210 APCI1500_Z8536_CONTROL_REGISTER);
1211
1212 /* Writes the low value */
1213
1214 outb(data[3],
1215 devpriv->iobase +
1216 APCI1500_Z8536_CONTROL_REGISTER);
1217
1218 /* Selects the constant register of timer/counter 2 */
1219
1220 outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
1221 devpriv->iobase +
1222 APCI1500_Z8536_CONTROL_REGISTER);
1223
1224 /* Writes the high value */
1225
1226 data[3] = data[3] >> 8;
1227 outb(data[3],
1228 devpriv->iobase +
1229 APCI1500_Z8536_CONTROL_REGISTER);
1230
1231 /* Selects the master configuration register */
1232
1233 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1234 devpriv->iobase +
1235 APCI1500_Z8536_CONTROL_REGISTER);
1236
1237 /* Reads the register */
1238
1239 i_MasterConfiguration =
1240 inb(devpriv->iobase +
1241 APCI1500_Z8536_CONTROL_REGISTER);
1242
1243 /* Enables timer/counter 2 and triggers timer/counter 2 */
1244
1245 i_MasterConfiguration =
1246 i_MasterConfiguration | 0x20;
1247
1248 /* Selects the master configuration register */
1249 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1250 devpriv->iobase +
1251 APCI1500_Z8536_CONTROL_REGISTER);
1252
1253 /* Writes the new configuration */
1254 outb(i_MasterConfiguration,
1255 devpriv->iobase +
1256 APCI1500_Z8536_CONTROL_REGISTER);
1257 /* Selects the commands register of */
1258 /* timer/counter 2 */
1259
1260 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1261 devpriv->iobase +
1262 APCI1500_Z8536_CONTROL_REGISTER);
1263
1264 /* Disable timer/counter 2 */
1265
1266 outb(0x0,
1267 devpriv->iobase +
1268 APCI1500_Z8536_CONTROL_REGISTER);
1269 /* Selects the commands register of */
1270 /* timer/counter 2 */
1271 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1272 devpriv->iobase +
1273 APCI1500_Z8536_CONTROL_REGISTER);
1274
1275 /* Trigger timer/counter 1 */
1276 outb(0x2,
1277 devpriv->iobase +
1278 APCI1500_Z8536_CONTROL_REGISTER);
1279 } else {
1280 dev_warn(dev->class_dev,
1281 "Error in selection of interrupt enable or disable\n");
1282 return -EINVAL;
1283 }
1284 } else {
1285 dev_warn(dev->class_dev,
1286 "Error in selection of reload value\n");
1287 return -EINVAL;
1288 }
1289 i_TimerCounterWatchdogInterrupt = data[7];
1290 i_TimerCounter2Init = 1;
1291 break;
1292
1293 case COUNTER3: /* selecting counter or watchdog */
1294 switch (data[2]) {
1295 case 0:
1296 data[2] = APCI1500_COUNTER;
1297 break;
1298 case 1:
1299 data[2] = APCI1500_WATCHDOG;
1300 break;
1301 default:
1302 dev_warn(dev->class_dev,
1303 "This choice is not a watchdog nor a counter\n");
1304 return -EINVAL;
1305 }
1306
1307 /* Selecting single or continuous mode */
1308 switch (data[4]) {
1309 case 0:
1310 data[4] = APCI1500_CONTINUOUS;
1311 break;
1312 case 1:
1313 data[4] = APCI1500_SINGLE;
1314 break;
1315 default:
1316 dev_warn(dev->class_dev,
1317 "This option for single/continuous mode does not exist\n");
1318 return -EINVAL;
1319 }
1320
1321 /* Selecting software or hardware gate */
1322 switch (data[6]) {
1323 case 0:
1324 data[6] = APCI1500_SOFTWARE_GATE;
1325 break;
1326 case 1:
1327 data[6] = APCI1500_HARDWARE_GATE;
1328 break;
1329 default:
1330 dev_warn(dev->class_dev,
1331 "This choice for software or hardware gate does not exist\n");
1332 return -EINVAL;
1333 }
1334
1335 /* Test if used for watchdog */
1336
1337 if (data[2] == APCI1500_WATCHDOG) {
1338 /* - Enables the output line */
1339 /* - Enables retrigger */
1340 /* - Pulses output */
1341 i_TimerCounterMode = data[2] | data[4] | 0x54;
1342 } else {
1343 i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
1344 }
1345 /* Test the reload value */
1346
1347 if ((data[3] >= 0) && (data[3] <= 65535)) {
1348 if (data[7] == APCI1500_ENABLE
1349 || data[7] == APCI1500_DISABLE) {
1350
1351 /* Selects the mode register of watchdog/counter 3 */
1352 outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
1353 devpriv->iobase +
1354 APCI1500_Z8536_CONTROL_REGISTER);
1355 /* Writes the new mode */
1356 outb(i_TimerCounterMode,
1357 devpriv->iobase +
1358 APCI1500_Z8536_CONTROL_REGISTER);
1359
1360 /* Selects the constant register of watchdog/counter 3 */
1361
1362 outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
1363 devpriv->iobase +
1364 APCI1500_Z8536_CONTROL_REGISTER);
1365
1366 /* Writes the low value */
1367
1368 outb(data[3],
1369 devpriv->iobase +
1370 APCI1500_Z8536_CONTROL_REGISTER);
1371
1372 /* Selects the constant register of watchdog/counter 3 */
1373
1374 outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
1375 devpriv->iobase +
1376 APCI1500_Z8536_CONTROL_REGISTER);
1377
1378 /* Writes the high value */
1379
1380 data[3] = data[3] >> 8;
1381 outb(data[3],
1382 devpriv->iobase +
1383 APCI1500_Z8536_CONTROL_REGISTER);
1384
1385 /* Selects the master configuration register */
1386
1387 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1388 devpriv->iobase +
1389 APCI1500_Z8536_CONTROL_REGISTER);
1390
1391 /* Reads the register */
1392
1393 i_MasterConfiguration =
1394 inb(devpriv->iobase +
1395 APCI1500_Z8536_CONTROL_REGISTER);
1396
1397 /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
1398
1399 i_MasterConfiguration =
1400 i_MasterConfiguration | 0x10;
1401
1402 /* Selects the master configuration register */
1403 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1404 devpriv->iobase +
1405 APCI1500_Z8536_CONTROL_REGISTER);
1406
1407 /* Writes the new configuration */
1408 outb(i_MasterConfiguration,
1409 devpriv->iobase +
1410 APCI1500_Z8536_CONTROL_REGISTER);
1411
1412 /* Test if COUNTER */
1413 if (data[2] == APCI1500_COUNTER) {
1414
1415 /* Selects the command register of */
1416 /* watchdog/counter 3 */
1417 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1418 devpriv->iobase +
1419 APCI1500_Z8536_CONTROL_REGISTER);
1420 /* Disable the watchdog/counter 3 and starts it */
1421 outb(0x0,
1422 devpriv->iobase +
1423 APCI1500_Z8536_CONTROL_REGISTER);
1424
1425 /* Selects the command register of */
1426 /* watchdog/counter 3 */
1427
1428 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1429 devpriv->iobase +
1430 APCI1500_Z8536_CONTROL_REGISTER);
1431 /* Trigger the watchdog/counter 3 and starts it */
1432 outb(0x2,
1433 devpriv->iobase +
1434 APCI1500_Z8536_CONTROL_REGISTER);
1435
1436 }
1437
1438 } else {
1439
1440 dev_warn(dev->class_dev,
1441 "Error in selection of interrupt enable or disable\n");
1442 return -EINVAL;
1443 }
1444 } else {
1445 dev_warn(dev->class_dev,
1446 "Error in selection of reload value\n");
1447 return -EINVAL;
1448 }
1449 i_TimerCounterWatchdogInterrupt = data[7];
1450 i_WatchdogCounter3Init = 1;
1451 break;
1452
1453 default:
1454 dev_warn(dev->class_dev,
1455 "The specified counter/timer option does not exist\n");
1456 return -EINVAL;
1457 }
1458 i_CounterLogic = data[2];
1459 return insn->n;
1460}
1461
1462/*
1463 * Start / Stop or trigger the timer counter or Watchdog
1464 *
1465 * data[0] 0 = Counter1/Timer1, 1 = Counter2/Timer2, 2 = Counter3/Watchdog
1466 * data[1] 0 = Start, 1 = Stop, 2 = Trigger
1467 * data[2] 0 = Counter, 1 = Timer/Watchdog
1468 */
1469static int apci1500_timer_write(struct comedi_device *dev,
1470 struct comedi_subdevice *s,
1471 struct comedi_insn *insn,
1472 unsigned int *data)
1473{
1474 struct apci1500_private *devpriv = dev->private;
1475 int i_CommandAndStatusValue;
1476
1477 switch (data[0]) {
1478 case COUNTER1:
1479 switch (data[1]) {
1480 case START:
1481 if (i_TimerCounter1Init == 1) {
1482 if (i_TimerCounterWatchdogInterrupt == 1)
1483 i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1484 else
1485 i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1486
1487 /* Starts timer/counter 1 */
1488 i_TimerCounter1Enabled = 1;
1489 /* Selects the commands and status register */
1490 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1491 devpriv->iobase +
1492 APCI1500_Z8536_CONTROL_REGISTER);
1493 outb(i_CommandAndStatusValue,
1494 devpriv->iobase +
1495 APCI1500_Z8536_CONTROL_REGISTER);
1496 } else {
1497 dev_warn(dev->class_dev,
1498 "Counter/Timer1 not configured\n");
1499 return -EINVAL;
1500 }
1501 break;
1502
1503 case STOP:
1504
1505 /* Stop timer/counter 1 */
1506
1507 /* Selects the commands and status register */
1508 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1509 devpriv->iobase +
1510 APCI1500_Z8536_CONTROL_REGISTER);
1511 outb(0x00,
1512 devpriv->iobase +
1513 APCI1500_Z8536_CONTROL_REGISTER);
1514 i_TimerCounter1Enabled = 0;
1515 break;
1516
1517 case TRIGGER:
1518 if (i_TimerCounter1Init == 1) {
1519 if (i_TimerCounter1Enabled == 1) {
1520 /* Set Trigger and gate */
1521
1522 i_CommandAndStatusValue = 0x6;
1523 } else {
1524 /* Set Trigger */
1525
1526 i_CommandAndStatusValue = 0x2;
1527 }
1528
1529 /* Selects the commands and status register */
1530 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1531 devpriv->iobase +
1532 APCI1500_Z8536_CONTROL_REGISTER);
1533 outb(i_CommandAndStatusValue,
1534 devpriv->iobase +
1535 APCI1500_Z8536_CONTROL_REGISTER);
1536 } else {
1537 dev_warn(dev->class_dev,
1538 "Counter/Timer1 not configured\n");
1539 return -EINVAL;
1540 }
1541 break;
1542
1543 default:
1544 dev_warn(dev->class_dev,
1545 "The specified option for start/stop/trigger does not exist\n");
1546 return -EINVAL;
1547 }
1548 break;
1549
1550 case COUNTER2:
1551 switch (data[1]) {
1552 case START:
1553 if (i_TimerCounter2Init == 1) {
1554 if (i_TimerCounterWatchdogInterrupt == 1)
1555 i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1556 else
1557 i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1558
1559 /* Starts timer/counter 2 */
1560 i_TimerCounter2Enabled = 1;
1561 /* Selects the commands and status register */
1562 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1563 devpriv->iobase +
1564 APCI1500_Z8536_CONTROL_REGISTER);
1565 outb(i_CommandAndStatusValue,
1566 devpriv->iobase +
1567 APCI1500_Z8536_CONTROL_REGISTER);
1568 } else {
1569 dev_warn(dev->class_dev,
1570 "Counter/Timer2 not configured\n");
1571 return -EINVAL;
1572 }
1573 break;
1574
1575 case STOP:
1576
1577 /* Stop timer/counter 2 */
1578
1579 /* Selects the commands and status register */
1580 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1581 devpriv->iobase +
1582 APCI1500_Z8536_CONTROL_REGISTER);
1583 outb(0x00,
1584 devpriv->iobase +
1585 APCI1500_Z8536_CONTROL_REGISTER);
1586 i_TimerCounter2Enabled = 0;
1587 break;
1588 case TRIGGER:
1589 if (i_TimerCounter2Init == 1) {
1590 if (i_TimerCounter2Enabled == 1) {
1591 /* Set Trigger and gate */
1592
1593 i_CommandAndStatusValue = 0x6;
1594 } else {
1595 /* Set Trigger */
1596
1597 i_CommandAndStatusValue = 0x2;
1598 }
1599
1600 /* Selects the commands and status register */
1601 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1602 devpriv->iobase +
1603 APCI1500_Z8536_CONTROL_REGISTER);
1604 outb(i_CommandAndStatusValue,
1605 devpriv->iobase +
1606 APCI1500_Z8536_CONTROL_REGISTER);
1607 } else {
1608 dev_warn(dev->class_dev,
1609 "Counter/Timer2 not configured\n");
1610 return -EINVAL;
1611 }
1612 break;
1613 default:
1614 dev_warn(dev->class_dev,
1615 "The specified option for start/stop/trigger does not exist\n");
1616 return -EINVAL;
1617 }
1618 break;
1619 case COUNTER3:
1620 switch (data[1]) {
1621 case START:
1622 if (i_WatchdogCounter3Init == 1) {
1623
1624 if (i_TimerCounterWatchdogInterrupt == 1)
1625 i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1626 else
1627 i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1628
1629 /* Starts Watchdog/counter 3 */
1630 i_WatchdogCounter3Enabled = 1;
1631 /* Selects the commands and status register */
1632 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1633 devpriv->iobase +
1634 APCI1500_Z8536_CONTROL_REGISTER);
1635 outb(i_CommandAndStatusValue,
1636 devpriv->iobase +
1637 APCI1500_Z8536_CONTROL_REGISTER);
1638
1639 } else {
1640 dev_warn(dev->class_dev,
1641 "Watchdog/Counter3 not configured\n");
1642 return -EINVAL;
1643 }
1644 break;
1645
1646 case STOP:
1647
1648 /* Stop Watchdog/counter 3 */
1649
1650 /* Selects the commands and status register */
1651 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1652 devpriv->iobase +
1653 APCI1500_Z8536_CONTROL_REGISTER);
1654 outb(0x00,
1655 devpriv->iobase +
1656 APCI1500_Z8536_CONTROL_REGISTER);
1657 i_WatchdogCounter3Enabled = 0;
1658 break;
1659
1660 case TRIGGER:
1661 switch (data[2]) {
1662 case 0: /* triggering counter 3 */
1663 if (i_WatchdogCounter3Init == 1) {
1664 if (i_WatchdogCounter3Enabled == 1) {
1665 /* Set Trigger and gate */
1666
1667 i_CommandAndStatusValue = 0x6;
1668 } else {
1669 /* Set Trigger */
1670
1671 i_CommandAndStatusValue = 0x2;
1672 }
1673
1674 /* Selects the commands and status register */
1675 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1676 devpriv->iobase +
1677 APCI1500_Z8536_CONTROL_REGISTER);
1678 outb(i_CommandAndStatusValue,
1679 devpriv->iobase +
1680 APCI1500_Z8536_CONTROL_REGISTER);
1681 } else {
1682 dev_warn(dev->class_dev,
1683 "Counter3 not configured\n");
1684 return -EINVAL;
1685 }
1686 break;
1687 case 1:
1688 /* triggering Watchdog 3 */
1689 if (i_WatchdogCounter3Init == 1) {
1690
1691 /* Selects the commands and status register */
1692 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1693 devpriv->iobase +
1694 APCI1500_Z8536_CONTROL_REGISTER);
1695 outb(0x6,
1696 devpriv->iobase +
1697 APCI1500_Z8536_CONTROL_REGISTER);
1698 } else {
1699 dev_warn(dev->class_dev,
1700 "Watchdog 3 not configured\n");
1701 return -EINVAL;
1702 }
1703 break;
1704 default:
1705 dev_warn(dev->class_dev,
1706 "Wrong choice of watchdog/counter3\n");
1707 return -EINVAL;
1708 }
1709 break;
1710 default:
1711 dev_warn(dev->class_dev,
1712 "The specified option for start/stop/trigger does not exist\n");
1713 return -EINVAL;
1714 }
1715 break;
1716 default:
1717 dev_warn(dev->class_dev,
1718 "The specified choice for counter/watchdog/timer does not exist\n");
1719 return -EINVAL;
1720 }
1721 return insn->n;
1722}
1723
1724/*
1725 * Read The Watchdog
1726 *
1727 * data[0] 0 = Counter1/Timer1, 1 = Counter2/Timer2, 2 = Counter3/Watchdog
1728 */
1729static int apci1500_timer_bits(struct comedi_device *dev,
1730 struct comedi_subdevice *s,
1731 struct comedi_insn *insn,
1732 unsigned int *data)
1733{
1734 struct apci1500_private *devpriv = dev->private;
1735 int i_CommandAndStatusValue;
1736
1737 switch (data[0]) {
1738 case COUNTER1:
1739 /* Read counter/timer1 */
1740 if (i_TimerCounter1Init == 1) {
1741 if (i_TimerCounter1Enabled == 1) {
1742 /* Set RCC and gate */
1743
1744 i_CommandAndStatusValue = 0xC;
1745 } else {
1746 /* Set RCC */
1747
1748 i_CommandAndStatusValue = 0x8;
1749 }
1750
1751 /* Selects the commands and status register */
1752 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1753 devpriv->iobase +
1754 APCI1500_Z8536_CONTROL_REGISTER);
1755 outb(i_CommandAndStatusValue,
1756 devpriv->iobase +
1757 APCI1500_Z8536_CONTROL_REGISTER);
1758
1759 /* Selects the counter register (high) */
1760 outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
1761 devpriv->iobase +
1762 APCI1500_Z8536_CONTROL_REGISTER);
1763 data[0] =
1764 inb(devpriv->iobase +
1765 APCI1500_Z8536_CONTROL_REGISTER);
1766 data[0] = data[0] << 8;
1767 data[0] = data[0] & 0xff00;
1768 outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
1769 devpriv->iobase +
1770 APCI1500_Z8536_CONTROL_REGISTER);
1771 data[0] =
1772 data[0] | inb(devpriv->iobase +
1773 APCI1500_Z8536_CONTROL_REGISTER);
1774 } else {
1775 dev_warn(dev->class_dev,
1776 "Timer/Counter1 not configured\n");
1777 return -EINVAL;
1778 }
1779 break;
1780 case COUNTER2:
1781 /* Read counter/timer2 */
1782 if (i_TimerCounter2Init == 1) {
1783 if (i_TimerCounter2Enabled == 1) {
1784 /* Set RCC and gate */
1785
1786 i_CommandAndStatusValue = 0xC;
1787 } else {
1788 /* Set RCC */
1789
1790 i_CommandAndStatusValue = 0x8;
1791 }
1792
1793 /* Selects the commands and status register */
1794 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1795 devpriv->iobase +
1796 APCI1500_Z8536_CONTROL_REGISTER);
1797 outb(i_CommandAndStatusValue,
1798 devpriv->iobase +
1799 APCI1500_Z8536_CONTROL_REGISTER);
1800
1801 /* Selects the counter register (high) */
1802 outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
1803 devpriv->iobase +
1804 APCI1500_Z8536_CONTROL_REGISTER);
1805 data[0] =
1806 inb(devpriv->iobase +
1807 APCI1500_Z8536_CONTROL_REGISTER);
1808 data[0] = data[0] << 8;
1809 data[0] = data[0] & 0xff00;
1810 outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
1811 devpriv->iobase +
1812 APCI1500_Z8536_CONTROL_REGISTER);
1813 data[0] =
1814 data[0] | inb(devpriv->iobase +
1815 APCI1500_Z8536_CONTROL_REGISTER);
1816 } else {
1817 dev_warn(dev->class_dev,
1818 "Timer/Counter2 not configured\n");
1819 return -EINVAL;
1820 }
1821 break;
1822 case COUNTER3:
1823 /* Read counter/watchdog2 */
1824 if (i_WatchdogCounter3Init == 1) {
1825 if (i_WatchdogCounter3Enabled == 1) {
1826 /* Set RCC and gate */
1827
1828 i_CommandAndStatusValue = 0xC;
1829 } else {
1830 /* Set RCC */
1831
1832 i_CommandAndStatusValue = 0x8;
1833 }
1834
1835 /* Selects the commands and status register */
1836 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1837 devpriv->iobase +
1838 APCI1500_Z8536_CONTROL_REGISTER);
1839 outb(i_CommandAndStatusValue,
1840 devpriv->iobase +
1841 APCI1500_Z8536_CONTROL_REGISTER);
1842
1843 /* Selects the counter register (high) */
1844 outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
1845 devpriv->iobase +
1846 APCI1500_Z8536_CONTROL_REGISTER);
1847 data[0] =
1848 inb(devpriv->iobase +
1849 APCI1500_Z8536_CONTROL_REGISTER);
1850 data[0] = data[0] << 8;
1851 data[0] = data[0] & 0xff00;
1852 outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
1853 devpriv->iobase +
1854 APCI1500_Z8536_CONTROL_REGISTER);
1855 data[0] =
1856 data[0] | inb(devpriv->iobase +
1857 APCI1500_Z8536_CONTROL_REGISTER);
1858 } else {
1859 dev_warn(dev->class_dev,
1860 "WatchdogCounter3 not configured\n");
1861 return -EINVAL;
1862 }
1863 break;
1864 default:
1865 dev_warn(dev->class_dev,
1866 "The choice of timer/counter/watchdog does not exist\n");
1867 return -EINVAL;
1868 }
1869
1870 return insn->n;
1871}
1872
1873/*
1874 * Read the interrupt mask
1875 *
1876 * data[0] The interrupt mask value
1877 * data[1] Channel Number
1878 */
1879static int apci1500_timer_read(struct comedi_device *dev,
1880 struct comedi_subdevice *s,
1881 struct comedi_insn *insn,
1882 unsigned int *data)
1883{
1884 data[0] = i_InterruptMask;
1885 data[1] = i_InputChannel;
1886 i_InterruptMask = 0;
1887 return insn->n;
1888}
1889
1890/*
1891 * Configures the interrupt registers
1892 */
1893static int apci1500_do_bits(struct comedi_device *dev,
1894 struct comedi_subdevice *s,
1895 struct comedi_insn *insn,
1896 unsigned int *data)
1897{
1898 struct apci1500_private *devpriv = dev->private;
1899 unsigned int ui_Status;
1900 int i_RegValue;
1901 int i_Constant;
1902
1903 devpriv->tsk_Current = current;
1904 outl(0x0, devpriv->i_IobaseAmcc + 0x38);
1905 if (data[0] == 1) {
1906 i_Constant = 0xC0;
1907 } else {
1908 if (data[0] == 0) {
1909 i_Constant = 0x00;
1910 } else {
1911 dev_warn(dev->class_dev,
1912 "The parameter passed to driver is in error for enabling the voltage interrupt\n");
1913 return -EINVAL;
1914 }
1915 }
1916
1917 /* Selects the mode specification register of port B */
1918 outb(APCI1500_RW_PORT_B_SPECIFICATION,
1919 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1920 i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1921 outb(APCI1500_RW_PORT_B_SPECIFICATION,
1922 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1923 /* Writes the new configuration (APCI1500_OR) */
1924 i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
1925
1926 outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1927 /* Selects the command and status register of port B */
1928 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
1929 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1930 /* Authorises the interrupt on the board */
1931 outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1932 /* Selects the pattern polarity register of port B */
1933 outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
1934 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1935 outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1936 /* Selects the pattern transition register of port B */
1937 outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
1938 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1939 outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1940 /* Selects the pattern mask register of port B */
1941 outb(APCI1500_RW_PORT_B_PATTERN_MASK,
1942 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1943 outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1944
1945 /* Selects the command and status register of port A */
1946 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
1947 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1948 i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1949 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
1950 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1951 /* Deletes the interrupt of port A */
1952
1953 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1954 outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1955 /* Selects the command and status register of port B */
1956 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
1957 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1958 i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1959 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
1960 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1961 /* Deletes the interrupt of port B */
1962
1963 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1964 outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1965
1966 /* Selects the command and status register of timer 1 */
1967 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1968 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1969 i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1970 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1971 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1972 /* Deletes the interrupt of timer 1 */
1973
1974 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1975 outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1976
1977 /* Selects the command and status register of timer 2 */
1978 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1979 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1980 i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1981 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1982 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1983 /* Deletes the interrupt of timer 2 */
1984
1985 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1986 outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1987
1988 /* Selects the command and status register of timer 3 */
1989 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1990 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1991 i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1992 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1993 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1994 /* Deletes the interrupt of timer 3 */
1995
1996 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1997 outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1998
1999 /* Selects the master interrupt control register */
2000 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2001 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2002 /* Authorizes the main interrupt on the board */
2003 outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2004
2005 /* Enables the PCI interrupt */
2006 outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
2007 ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
2008 ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
2009 outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
2010
2011 return insn->n;
2012}
2013
2014static irqreturn_t apci1500_interrupt(int irq, void *d)
2015{
2016
2017 struct comedi_device *dev = d;
2018 struct apci1500_private *devpriv = dev->private;
2019 unsigned int ui_InterruptStatus = 0;
2020 int i_RegValue = 0;
2021
2022 /* Clear the interrupt mask */
2023 i_InterruptMask = 0;
2024
2025 /* Read the board interrupt status */
2026 ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
2027
2028 /* Test if board generated a interrupt */
2029 if ((ui_InterruptStatus & 0x800000) == 0x800000) {
2030 /* Disable all Interrupt */
2031 /* Selects the master interrupt control register */
2032 /* Disables the main interrupt on the board */
2033 /* Selects the command and status register of port A */
2034 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2035 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2036 i_RegValue =
2037 inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2038 if ((i_RegValue & 0x60) == 0x60) {
2039 /* Selects the command and status register of port A */
2040 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2041 devpriv->iobase +
2042 APCI1500_Z8536_CONTROL_REGISTER);
2043 /* Deletes the interrupt of port A */
2044 i_RegValue = (i_RegValue & 0x0F) | 0x20;
2045 outb(i_RegValue,
2046 devpriv->iobase +
2047 APCI1500_Z8536_CONTROL_REGISTER);
2048 i_InterruptMask = i_InterruptMask | 1;
2049 if (i_Logic == APCI1500_OR_PRIORITY) {
2050 outb(APCI1500_RW_PORT_A_SPECIFICATION,
2051 devpriv->iobase +
2052 APCI1500_Z8536_CONTROL_REGISTER);
2053 i_RegValue =
2054 inb(devpriv->iobase +
2055 APCI1500_Z8536_CONTROL_REGISTER);
2056
2057 /* Selects the interrupt vector register of port A */
2058 outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
2059 devpriv->iobase +
2060 APCI1500_Z8536_CONTROL_REGISTER);
2061 i_RegValue =
2062 inb(devpriv->iobase +
2063 APCI1500_Z8536_CONTROL_REGISTER);
2064
2065 i_InputChannel = 1 + (i_RegValue >> 1);
2066
2067 } else {
2068 i_InputChannel = 0;
2069 }
2070 }
2071
2072 /* Selects the command and status register of port B */
2073 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2074 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2075 i_RegValue =
2076 inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2077 if ((i_RegValue & 0x60) == 0x60) {
2078 /* Selects the command and status register of port B */
2079 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2080 devpriv->iobase +
2081 APCI1500_Z8536_CONTROL_REGISTER);
2082 /* Deletes the interrupt of port B */
2083 i_RegValue = (i_RegValue & 0x0F) | 0x20;
2084 outb(i_RegValue,
2085 devpriv->iobase +
2086 APCI1500_Z8536_CONTROL_REGISTER);
2087 /* Reads port B */
2088 i_RegValue =
2089 inb((unsigned int) devpriv->iobase +
2090 APCI1500_Z8536_PORT_B);
2091
2092 i_RegValue = i_RegValue & 0xC0;
2093 /* Tests if this is an external error */
2094
2095 if (i_RegValue) {
2096 /* Disable the interrupt */
2097 /* Selects the command and status register of port B */
2098 outl(0x0, devpriv->i_IobaseAmcc + 0x38);
2099
2100 if (i_RegValue & 0x80) {
2101 i_InterruptMask =
2102 i_InterruptMask | 0x40;
2103 }
2104
2105 if (i_RegValue & 0x40) {
2106 i_InterruptMask =
2107 i_InterruptMask | 0x80;
2108 }
2109 } else {
2110 i_InterruptMask = i_InterruptMask | 2;
2111 }
2112 }
2113
2114 /* Selects the command and status register of timer 1 */
2115 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2116 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2117 i_RegValue =
2118 inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2119 if ((i_RegValue & 0x60) == 0x60) {
2120 /* Selects the command and status register of timer 1 */
2121 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2122 devpriv->iobase +
2123 APCI1500_Z8536_CONTROL_REGISTER);
2124 /* Deletes the interrupt of timer 1 */
2125 i_RegValue = (i_RegValue & 0x0F) | 0x20;
2126 outb(i_RegValue,
2127 devpriv->iobase +
2128 APCI1500_Z8536_CONTROL_REGISTER);
2129 i_InterruptMask = i_InterruptMask | 4;
2130 }
2131 /* Selects the command and status register of timer 2 */
2132 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2133 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2134 i_RegValue =
2135 inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2136 if ((i_RegValue & 0x60) == 0x60) {
2137 /* Selects the command and status register of timer 2 */
2138 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2139 devpriv->iobase +
2140 APCI1500_Z8536_CONTROL_REGISTER);
2141 /* Deletes the interrupt of timer 2 */
2142 i_RegValue = (i_RegValue & 0x0F) | 0x20;
2143 outb(i_RegValue,
2144 devpriv->iobase +
2145 APCI1500_Z8536_CONTROL_REGISTER);
2146 i_InterruptMask = i_InterruptMask | 8;
2147 }
2148
2149 /* Selects the command and status register of timer 3 */
2150 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2151 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2152 i_RegValue =
2153 inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2154 if ((i_RegValue & 0x60) == 0x60) {
2155 /* Selects the command and status register of timer 3 */
2156 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2157 devpriv->iobase +
2158 APCI1500_Z8536_CONTROL_REGISTER);
2159 /* Deletes the interrupt of timer 3 */
2160 i_RegValue = (i_RegValue & 0x0F) | 0x20;
2161 outb(i_RegValue,
2162 devpriv->iobase +
2163 APCI1500_Z8536_CONTROL_REGISTER);
2164 if (i_CounterLogic == APCI1500_COUNTER)
2165 i_InterruptMask = i_InterruptMask | 0x10;
2166 else
2167 i_InterruptMask = i_InterruptMask | 0x20;
2168 }
2169
2170 send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
2171 /* Enable all Interrupts */
2172
2173 /* Selects the master interrupt control register */
2174 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2175 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2176 /* Authorizes the main interrupt on the board */
2177 outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2178 } else {
2179 dev_warn(dev->class_dev,
2180 "Interrupt from unknown source\n");
2181
2182 }
2183
2184 return IRQ_HANDLED;
2185}
2186
2187static int apci1500_reset(struct comedi_device *dev)
2188{
2189 struct apci1500_private *devpriv = dev->private;
2190 int i_DummyRead = 0;
2191
2192 i_TimerCounter1Init = 0;
2193 i_TimerCounter2Init = 0;
2194 i_WatchdogCounter3Init = 0;
2195 i_Event1Status = 0;
2196 i_Event2Status = 0;
2197 i_TimerCounterWatchdogInterrupt = 0;
2198 i_Logic = 0;
2199 i_CounterLogic = 0;
2200 i_InterruptMask = 0;
2201 i_InputChannel = 0;
2202 i_TimerCounter1Enabled = 0;
2203 i_TimerCounter2Enabled = 0;
2204 i_WatchdogCounter3Enabled = 0;
2205
2206 /* Software reset */
2207 i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2208 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2209 i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2210 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2211 outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2212 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2213
2214 /* Selects the master configuration control register */
2215 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
2216 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2217 outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2218
2219 /* Selects the mode specification register of port A */
2220 outb(APCI1500_RW_PORT_A_SPECIFICATION,
2221 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2222 outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2223
2224 /* Selects the data path polarity register of port A */
2225 outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
2226 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2227 /* High level of port A means 1 */
2228 outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2229
2230 /* Selects the data direction register of port A */
2231 outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
2232 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2233 /* All bits used as inputs */
2234 outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2235 /* Selects the command and status register of port A */
2236 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2237 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2238 /* Deletes IP and IUS */
2239 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2240 /* Selects the command and status register of port A */
2241 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2242 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2243 /* Deactivates the interrupt management of port A: */
2244 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2245 /* Selects the handshake specification register of port A */
2246 outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
2247 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2248 /* Deletes the register */
2249 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2250
2251 /* Selects the mode specification register of port B */
2252 outb(APCI1500_RW_PORT_B_SPECIFICATION,
2253 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2254 outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2255 /* Selects the data path polarity register of port B */
2256 outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
2257 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2258 /* A high level of port B means 1 */
2259 outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2260 /* Selects the data direction register of port B */
2261 outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
2262 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2263 /* All bits used as inputs */
2264 outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2265 /* Selects the command and status register of port B */
2266 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2267 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2268 /* Deletes IP and IUS */
2269 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2270 /* Selects the command and status register of port B */
2271 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2272 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2273 /* Deactivates the interrupt management of port B: */
2274 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2275 /* Selects the handshake specification register of port B */
2276 outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
2277 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2278 /* Deletes the register */
2279 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2280
2281 /* Selects the data path polarity register of port C */
2282 outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
2283 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2284 /* High level of port C means 1 */
2285 outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2286 /* Selects the data direction register of port C */
2287 outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
2288 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2289 /* All bits used as inputs except channel 1 */
2290 outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2291 /* Selects the special IO register of port C */
2292 outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
2293 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2294 /* Deletes it */
2295 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2296 /* Selects the command and status register of timer 1 */
2297 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2298 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2299 /* Deletes IP and IUS */
2300 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2301 /* Selects the command and status register of timer 1 */
2302 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2303 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2304 /* Deactivates the interrupt management of timer 1 */
2305 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2306 /* Selects the command and status register of timer 2 */
2307 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2308 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2309 /* Deletes IP and IUS */
2310 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2311 /* Selects the command and status register of timer 2 */
2312 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2313 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2314 /* Deactivates Timer 2 interrupt management: */
2315 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2316 /* Selects the command and status register of timer 3 */
2317 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2318 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2319 /* Deletes IP and IUS */
2320 outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2321 /* Selects the command and status register of Timer 3 */
2322 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2323 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2324 /* Deactivates interrupt management of timer 3: */
2325 outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2326 /* Selects the master interrupt control register */
2327 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2328 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2329 /* Deletes all interrupts */
2330 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2331 /* reset all the digital outputs */
2332 outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
2333 /* Disable the board interrupt */
2334 /* Selects the master interrupt control register */
2335 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2336 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2337 /* Deactivates all interrupts */
2338 outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2339 /* Selects the command and status register of port A */
2340 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2341 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2342 /* Deactivates all interrupts */
2343 outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2344 /* Selects the command and status register of port B */
2345 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2346 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2347 /* Deactivates all interrupts */
2348 outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2349 /* Selects the command and status register of timer 1 */
2350 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2351 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2352 /* Deactivates all interrupts */
2353 outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2354 /* Selects the command and status register of timer 2 */
2355 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2356 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2357 /* Deactivates all interrupts */
2358 outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2359 /* Selects the command and status register of timer 3*/
2360 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2361 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2362 /* Deactivates all interrupts */
2363 outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2364 return 0;
2365}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index 339519a3d6b5..1f2f78186d58 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -93,7 +93,6 @@ static int apci3501_write_insn_timer(struct comedi_device *dev,
93{ 93{
94 struct apci3501_private *devpriv = dev->private; 94 struct apci3501_private *devpriv = dev->private;
95 unsigned int ul_Command1 = 0; 95 unsigned int ul_Command1 = 0;
96 int i_Temp;
97 96
98 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { 97 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
99 98
@@ -135,7 +134,7 @@ static int apci3501_write_insn_timer(struct comedi_device *dev,
135 } 134 }
136 } 135 }
137 136
138 i_Temp = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; 137 inl(dev->iobase + APCI3501_TIMER_STATUS_REG);
139 return insn->n; 138 return insn->n;
140} 139}
141 140
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
index bf14165297b7..4911b627203b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -22,6 +22,54 @@
22 * more details. 22 * more details.
23 */ 23 */
24 24
25/*
26 * Driver: addi_apci_1032
27 * Description: ADDI-DATA APCI-1032 Digital Input Board
28 * Author: ADDI-DATA GmbH <info@addi-data.com>,
29 * H Hartley Sweeten <hsweeten@visionengravers.com>
30 * Status: untested
31 * Devices: [ADDI-DATA] APCI-1032 (addi_apci_1032)
32 *
33 * Configuration options:
34 * None; devices are configured automatically.
35 *
36 * This driver models the APCI-1032 as a 32-channel, digital input subdevice
37 * plus an additional digital input subdevice to handle change-of-state (COS)
38 * interrupts (if an interrupt handler can be set up successfully).
39 *
40 * The COS subdevice supports comedi asynchronous read commands.
41 *
42 * Change-Of-State (COS) interrupt configuration:
43 *
44 * Channels 0 to 15 are interruptible. These channels can be configured
45 * to generate interrupts based on AND/OR logic for the desired channels.
46 *
47 * OR logic:
48 * - reacts to rising or falling edges
49 * - interrupt is generated when any enabled channel meets the desired
50 * interrupt condition
51 *
52 * AND logic:
53 * - reacts to changes in level of the selected inputs
54 * - interrupt is generated when all enabled channels meet the desired
55 * interrupt condition
56 * - after an interrupt, a change in level must occur on the selected
57 * inputs to release the IRQ logic
58 *
59 * The COS subdevice must be configured before setting up a comedi
60 * asynchronous command:
61 *
62 * data[0] : INSN_CONFIG_DIGITAL_TRIG
63 * data[1] : trigger number (= 0)
64 * data[2] : configuration operation:
65 * - COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
66 * - COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
67 * - COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
68 * data[3] : left-shift for data[4] and data[5]
69 * data[4] : rising-edge/high level channels
70 * data[5] : falling-edge/low level channels
71 */
72
25#include <linux/module.h> 73#include <linux/module.h>
26#include <linux/pci.h> 74#include <linux/pci.h>
27#include <linux/interrupt.h> 75#include <linux/interrupt.h>
@@ -62,36 +110,6 @@ static int apci1032_reset(struct comedi_device *dev)
62 return 0; 110 return 0;
63} 111}
64 112
65/*
66 * Change-Of-State (COS) interrupt configuration
67 *
68 * Channels 0 to 15 are interruptible. These channels can be configured
69 * to generate interrupts based on AND/OR logic for the desired channels.
70 *
71 * OR logic
72 * - reacts to rising or falling edges
73 * - interrupt is generated when any enabled channel
74 * meet the desired interrupt condition
75 *
76 * AND logic
77 * - reacts to changes in level of the selected inputs
78 * - interrupt is generated when all enabled channels
79 * meet the desired interrupt condition
80 * - after an interrupt, a change in level must occur on
81 * the selected inputs to release the IRQ logic
82 *
83 * The COS interrupt must be configured before it can be enabled.
84 *
85 * data[0] : INSN_CONFIG_DIGITAL_TRIG
86 * data[1] : trigger number (= 0)
87 * data[2] : configuration operation:
88 * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
89 * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
90 * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
91 * data[3] : left-shift for data[4] and data[5]
92 * data[4] : rising-edge/high level channels
93 * data[5] : falling-edge/low level channels
94 */
95static int apci1032_cos_insn_config(struct comedi_device *dev, 113static int apci1032_cos_insn_config(struct comedi_device *dev,
96 struct comedi_subdevice *s, 114 struct comedi_subdevice *s,
97 struct comedi_insn *insn, 115 struct comedi_insn *insn,
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index 30b132c3d092..f15aa1f6b476 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -1,22 +1,755 @@
1/*
2 * addi_apci_1500.c
3 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
4 *
5 * ADDI-DATA GmbH
6 * Dieselstrasse 3
7 * D-77833 Ottersweier
8 * Tel: +19(0)7223/9493-0
9 * Fax: +49(0)7223/9493-92
10 * http://www.addi-data.com
11 * info@addi-data.com
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * more details.
22 */
23
1#include <linux/module.h> 24#include <linux/module.h>
2#include <linux/pci.h> 25#include <linux/pci.h>
3#include <linux/sched.h>
4#include <linux/interrupt.h> 26#include <linux/interrupt.h>
5 27
6#include "../comedidev.h" 28#include "../comedidev.h"
7#include "comedi_fc.h" 29#include "comedi_fc.h"
8#include "amcc_s5933.h" 30#include "amcc_s5933.h"
31#include "z8536.h"
32
33/*
34 * PCI Bar 0 Register map (devpriv->amcc)
35 * see amcc_s5933.h for register and bit defines
36 */
37
38/*
39 * PCI Bar 1 Register map (dev->iobase)
40 * see z8536.h for Z8536 internal registers and bit defines
41 */
42#define APCI1500_Z8536_PORTC_REG 0x00
43#define APCI1500_Z8536_PORTB_REG 0x01
44#define APCI1500_Z8536_PORTA_REG 0x02
45#define APCI1500_Z8536_CTRL_REG 0x03
46
47/*
48 * PCI Bar 2 Register map (devpriv->addon)
49 */
50#define APCI1500_CLK_SEL_REG 0x00
51#define APCI1500_DI_REG 0x00
52#define APCI1500_DO_REG 0x02
9 53
10struct apci1500_private { 54struct apci1500_private {
11 int iobase; 55 unsigned long amcc;
12 int i_IobaseAmcc; 56 unsigned long addon;
13 int i_IobaseAddon; 57
14 int i_IobaseReserved; 58 unsigned int clk_src;
15 unsigned char b_OutputMemoryStatus; 59
16 struct task_struct *tsk_Current; 60 /* Digital trigger configuration [0]=AND [1]=OR */
61 unsigned int pm[2]; /* Pattern Mask */
62 unsigned int pt[2]; /* Pattern Transition */
63 unsigned int pp[2]; /* Pattern Polarity */
17}; 64};
18 65
19#include "addi-data/hwdrv_apci1500.c" 66static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg)
67{
68 unsigned long flags;
69 unsigned int val;
70
71 spin_lock_irqsave(&dev->spinlock, flags);
72 outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
73 val = inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
74 spin_unlock_irqrestore(&dev->spinlock, flags);
75
76 return val;
77}
78
79static void z8536_write(struct comedi_device *dev,
80 unsigned int val, unsigned int reg)
81{
82 unsigned long flags;
83
84 spin_lock_irqsave(&dev->spinlock, flags);
85 outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
86 outb(val, dev->iobase + APCI1500_Z8536_CTRL_REG);
87 spin_unlock_irqrestore(&dev->spinlock, flags);
88}
89
90static void z8536_reset(struct comedi_device *dev)
91{
92 unsigned long flags;
93
94 /*
95 * Even if the state of the Z8536 is not known, the following
96 * sequence will reset it and put it in State 0.
97 */
98 spin_lock_irqsave(&dev->spinlock, flags);
99 inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
100 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
101 inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
102 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
103 outb(1, dev->iobase + APCI1500_Z8536_CTRL_REG);
104 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
105 spin_unlock_irqrestore(&dev->spinlock, flags);
106
107 /* Disable all Ports and Counter/Timers */
108 z8536_write(dev, 0x00, Z8536_CFG_CTRL_REG);
109
110 /*
111 * Port A is connected to Ditial Input channels 0-7.
112 * Configure the port to allow interrupt detection.
113 */
114 z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
115 Z8536_PAB_MODE_SB |
116 Z8536_PAB_MODE_PMS_DISABLE,
117 Z8536_PA_MODE_REG);
118 z8536_write(dev, 0xff, Z8536_PB_DPP_REG);
119 z8536_write(dev, 0xff, Z8536_PA_DD_REG);
120
121 /*
122 * Port B is connected to Ditial Input channels 8-13.
123 * Configure the port to allow interrupt detection.
124 *
125 * NOTE: Bits 7 and 6 of Port B are connected to internal
126 * diagnostic signals and bit 7 is inverted.
127 */
128 z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
129 Z8536_PAB_MODE_SB |
130 Z8536_PAB_MODE_PMS_DISABLE,
131 Z8536_PB_MODE_REG);
132 z8536_write(dev, 0x7f, Z8536_PB_DPP_REG);
133 z8536_write(dev, 0xff, Z8536_PB_DD_REG);
134
135 /*
136 * Not sure what Port C is connected to...
137 */
138 z8536_write(dev, 0x09, Z8536_PC_DPP_REG);
139 z8536_write(dev, 0x0e, Z8536_PC_DD_REG);
140
141 /*
142 * Clear and disable all interrupt sources.
143 *
144 * Just in case, the reset of the Z8536 should have already
145 * done this.
146 */
147 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PA_CMDSTAT_REG);
148 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
149
150 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PB_CMDSTAT_REG);
151 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
152
153 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(0));
154 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(0));
155
156 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(1));
157 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(1));
158
159 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(2));
160 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(2));
161
162 /* Disable all interrupts */
163 z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
164}
165
166static void apci1500_port_enable(struct comedi_device *dev, bool enable)
167{
168 unsigned int cfg;
169
170 cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
171 if (enable)
172 cfg |= (Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
173 else
174 cfg &= ~(Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
175 z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
176}
177
178static void apci1500_timer_enable(struct comedi_device *dev,
179 unsigned int chan, bool enable)
180{
181 unsigned int bit;
182 unsigned int cfg;
183
184 if (chan == 0)
185 bit = Z8536_CFG_CTRL_CT1E;
186 else if (chan == 1)
187 bit = Z8536_CFG_CTRL_CT2E;
188 else
189 bit = Z8536_CFG_CTRL_PCE_CT3E;
190
191 cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
192 if (enable) {
193 cfg |= bit;
194 } else {
195 cfg &= ~bit;
196 z8536_write(dev, 0x00, Z8536_CT_CMDSTAT_REG(chan));
197 }
198 z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
199}
200
201static bool apci1500_ack_irq(struct comedi_device *dev,
202 unsigned int reg)
203{
204 unsigned int val;
205
206 val = z8536_read(dev, reg);
207 if ((val & Z8536_STAT_IE_IP) == Z8536_STAT_IE_IP) {
208 val &= 0x0f; /* preserve any write bits */
209 val |= Z8536_CMD_CLR_IP_IUS;
210 z8536_write(dev, val, reg);
211
212 return true;
213 }
214 return false;
215}
216
217static irqreturn_t apci1500_interrupt(int irq, void *d)
218{
219 struct comedi_device *dev = d;
220 struct apci1500_private *devpriv = dev->private;
221 struct comedi_subdevice *s = dev->read_subdev;
222 unsigned int status = 0;
223 unsigned int val;
224
225 val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
226 if (!(val & INTCSR_INTR_ASSERTED))
227 return IRQ_NONE;
228
229 if (apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG))
230 status |= 0x01; /* port a event (inputs 0-7) */
231
232 if (apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG)) {
233 /* Tests if this is an external error */
234 val = inb(dev->iobase + APCI1500_Z8536_PORTB_REG);
235 val &= 0xc0;
236 if (val) {
237 if (val & 0x80) /* voltage error */
238 status |= 0x40;
239 if (val & 0x40) /* short circuit error */
240 status |= 0x80;
241 } else {
242 status |= 0x02; /* port b event (inputs 8-13) */
243 }
244 }
245
246 /*
247 * NOTE: The 'status' returned by the sample matches the
248 * interrupt mask information from the APCI-1500 Users Manual.
249 *
250 * Mask Meaning
251 * ---------- ------------------------------------------
252 * 0x00000001 Event 1 has occured
253 * 0x00000010 Event 2 has occured
254 * 0x00000100 Counter/timer 1 has run down (not implemented)
255 * 0x00001000 Counter/timer 2 has run down (not implemented)
256 * 0x00010000 Counter 3 has run down (not implemented)
257 * 0x00100000 Watchdog has run down (not implemented)
258 * 0x01000000 Voltage error
259 * 0x10000000 Short-circuit error
260 */
261 comedi_buf_write_samples(s, &status, 1);
262 comedi_handle_events(dev, s);
263
264 return IRQ_HANDLED;
265}
266
267static int apci1500_di_cancel(struct comedi_device *dev,
268 struct comedi_subdevice *s)
269{
270 /* Disables the main interrupt on the board */
271 z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
272
273 /* Disable Ports A & B */
274 apci1500_port_enable(dev, false);
275
276 /* Ack any pending interrupts */
277 apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG);
278 apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG);
279
280 /* Disable pattern interrupts */
281 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
282 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
283
284 /* Enable Ports A & B */
285 apci1500_port_enable(dev, true);
286
287 return 0;
288}
289
290static int apci1500_di_inttrig_start(struct comedi_device *dev,
291 struct comedi_subdevice *s,
292 unsigned int trig_num)
293{
294 struct apci1500_private *devpriv = dev->private;
295 struct comedi_cmd *cmd = &s->async->cmd;
296 unsigned int pa_mode = Z8536_PAB_MODE_PMS_DISABLE;
297 unsigned int pb_mode = Z8536_PAB_MODE_PMS_DISABLE;
298 unsigned int pa_trig = trig_num & 0x01;
299 unsigned int pb_trig = (trig_num >> 1) & 0x01;
300 bool valid_trig = false;
301 unsigned int val;
302
303 if (trig_num != cmd->start_arg)
304 return -EINVAL;
305
306 /* Disable Ports A & B */
307 apci1500_port_enable(dev, false);
308
309 /* Set Port A for selected trigger pattern */
310 z8536_write(dev, devpriv->pm[pa_trig] & 0xff, Z8536_PA_PM_REG);
311 z8536_write(dev, devpriv->pt[pa_trig] & 0xff, Z8536_PA_PT_REG);
312 z8536_write(dev, devpriv->pp[pa_trig] & 0xff, Z8536_PA_PP_REG);
313
314 /* Set Port B for selected trigger pattern */
315 z8536_write(dev, (devpriv->pm[pb_trig] >> 8) & 0xff, Z8536_PB_PM_REG);
316 z8536_write(dev, (devpriv->pt[pb_trig] >> 8) & 0xff, Z8536_PB_PT_REG);
317 z8536_write(dev, (devpriv->pp[pb_trig] >> 8) & 0xff, Z8536_PB_PP_REG);
318
319 /* Set Port A trigger mode (if enabled) and enable interrupt */
320 if (devpriv->pm[pa_trig] & 0xff) {
321 pa_mode = pa_trig ? Z8536_PAB_MODE_PMS_AND
322 : Z8536_PAB_MODE_PMS_OR;
323
324 val = z8536_read(dev, Z8536_PA_MODE_REG);
325 val &= ~Z8536_PAB_MODE_PMS_MASK;
326 val |= (pa_mode | Z8536_PAB_MODE_IMO);
327 z8536_write(dev, val, Z8536_PA_MODE_REG);
328
329 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PA_CMDSTAT_REG);
330
331 valid_trig = true;
332
333 dev_dbg(dev->class_dev,
334 "Port A configured for %s mode pattern detection\n",
335 pa_trig ? "AND" : "OR");
336 }
337
338 /* Set Port B trigger mode (if enabled) and enable interrupt */
339 if (devpriv->pm[pb_trig] & 0xff00) {
340 pb_mode = pb_trig ? Z8536_PAB_MODE_PMS_AND
341 : Z8536_PAB_MODE_PMS_OR;
342
343 val = z8536_read(dev, Z8536_PB_MODE_REG);
344 val &= ~Z8536_PAB_MODE_PMS_MASK;
345 val |= (pb_mode | Z8536_PAB_MODE_IMO);
346 z8536_write(dev, val, Z8536_PB_MODE_REG);
347
348 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PB_CMDSTAT_REG);
349
350 valid_trig = true;
351
352 dev_dbg(dev->class_dev,
353 "Port B configured for %s mode pattern detection\n",
354 pb_trig ? "AND" : "OR");
355 }
356
357 /* Enable Ports A & B */
358 apci1500_port_enable(dev, true);
359
360 if (!valid_trig) {
361 dev_dbg(dev->class_dev,
362 "digital trigger %d is not configured\n", trig_num);
363 return -EINVAL;
364 }
365
366 /* Authorizes the main interrupt on the board */
367 z8536_write(dev, Z8536_INT_CTRL_MIE | Z8536_INT_CTRL_DLC,
368 Z8536_INT_CTRL_REG);
369
370 return 0;
371}
372
373static int apci1500_di_cmd(struct comedi_device *dev,
374 struct comedi_subdevice *s)
375{
376 s->async->inttrig = apci1500_di_inttrig_start;
377
378 return 0;
379}
380
381static int apci1500_di_cmdtest(struct comedi_device *dev,
382 struct comedi_subdevice *s,
383 struct comedi_cmd *cmd)
384{
385 int err = 0;
386
387 /* Step 1 : check if triggers are trivially valid */
388
389 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
390 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
391 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
392 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
393 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
394
395 if (err)
396 return 1;
397
398 /* Step 2a : make sure trigger sources are unique */
399 /* Step 2b : and mutually compatible */
400
401 /* Step 3: check if arguments are trivially valid */
402
403 /*
404 * Internal start source triggers:
405 *
406 * 0 AND mode for Port A (digital inputs 0-7)
407 * AND mode for Port B (digital inputs 8-13 and internal signals)
408 *
409 * 1 OR mode for Port A (digital inputs 0-7)
410 * AND mode for Port B (digital inputs 8-13 and internal signals)
411 *
412 * 2 AND mode for Port A (digital inputs 0-7)
413 * OR mode for Port B (digital inputs 8-13 and internal signals)
414 *
415 * 3 OR mode for Port A (digital inputs 0-7)
416 * OR mode for Port B (digital inputs 8-13 and internal signals)
417 */
418 err |= cfc_check_trigger_arg_max(&cmd->start_arg, 3);
419
420 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
421 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
422 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
423 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
424
425 if (err)
426 return 3;
427
428 /* Step 4: fix up any arguments */
429
430 /* Step 5: check channel list if it exists */
431
432 return 0;
433}
434
435/*
436 * The pattern-recognition logic must be configured before the digital
437 * input async command is started.
438 *
439 * Digital input channels 0 to 13 can generate interrupts. Channels 14
440 * and 15 are connected to internal board status/diagnostic signals.
441 *
442 * Channel 14 - Voltage error (the external supply is < 5V)
443 * Channel 15 - Short-circuit/overtemperature error
444 *
445 * data[0] : INSN_CONFIG_DIGITAL_TRIG
446 * data[1] : trigger number
447 * 0 = AND mode
448 * 1 = OR mode
449 * data[2] : configuration operation:
450 * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
451 * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = edge interrupts
452 * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = level interrupts
453 * data[3] : left-shift for data[4] and data[5]
454 * data[4] : rising-edge/high level channels
455 * data[5] : falling-edge/low level channels
456 */
457static int apci1500_di_cfg_trig(struct comedi_device *dev,
458 struct comedi_subdevice *s,
459 struct comedi_insn *insn,
460 unsigned int *data)
461{
462 struct apci1500_private *devpriv = dev->private;
463 unsigned int trig = data[1];
464 unsigned int shift = data[3];
465 unsigned int hi_mask = data[4] << shift;
466 unsigned int lo_mask = data[5] << shift;
467 unsigned int chan_mask = hi_mask | lo_mask;
468 unsigned int old_mask = (1 << shift) - 1;
469 unsigned int pm = devpriv->pm[trig] & old_mask;
470 unsigned int pt = devpriv->pt[trig] & old_mask;
471 unsigned int pp = devpriv->pp[trig] & old_mask;
472
473 if (trig > 1) {
474 dev_dbg(dev->class_dev,
475 "invalid digital trigger number (0=AND, 1=OR)\n");
476 return -EINVAL;
477 }
478
479 if (chan_mask > 0xffff) {
480 dev_dbg(dev->class_dev, "invalid digital trigger channel\n");
481 return -EINVAL;
482 }
483
484 switch (data[2]) {
485 case COMEDI_DIGITAL_TRIG_DISABLE:
486 /* clear trigger configuration */
487 pm = 0;
488 pt = 0;
489 pp = 0;
490 break;
491 case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
492 pm |= chan_mask; /* enable channels */
493 pt |= chan_mask; /* enable edge detection */
494 pp |= hi_mask; /* rising-edge channels */
495 pp &= ~lo_mask; /* falling-edge channels */
496 break;
497 case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
498 pm |= chan_mask; /* enable channels */
499 pt &= ~chan_mask; /* enable level detection */
500 pp |= hi_mask; /* high level channels */
501 pp &= ~lo_mask; /* low level channels */
502 break;
503 default:
504 return -EINVAL;
505 }
506
507 /*
508 * The AND mode trigger can only have one channel (max) enabled
509 * for edge detection.
510 */
511 if (trig == 0) {
512 int ret = 0;
513 unsigned int src;
514
515 src = pt & 0xff;
516 if (src)
517 ret |= cfc_check_trigger_is_unique(src);
518
519 src = (pt >> 8) & 0xff;
520 if (src)
521 ret |= cfc_check_trigger_is_unique(src);
522
523 if (ret) {
524 dev_dbg(dev->class_dev,
525 "invalid AND trigger configuration\n");
526 return ret;
527 }
528 }
529
530 /* save the trigger configuration */
531 devpriv->pm[trig] = pm;
532 devpriv->pt[trig] = pt;
533 devpriv->pp[trig] = pp;
534
535 return insn->n;
536}
537
538static int apci1500_di_insn_config(struct comedi_device *dev,
539 struct comedi_subdevice *s,
540 struct comedi_insn *insn,
541 unsigned int *data)
542{
543 switch (data[0]) {
544 case INSN_CONFIG_DIGITAL_TRIG:
545 return apci1500_di_cfg_trig(dev, s, insn, data);
546 default:
547 return -EINVAL;
548 }
549}
550
551static int apci1500_di_insn_bits(struct comedi_device *dev,
552 struct comedi_subdevice *s,
553 struct comedi_insn *insn,
554 unsigned int *data)
555{
556 struct apci1500_private *devpriv = dev->private;
557
558 data[1] = inw(devpriv->addon + APCI1500_DI_REG);
559
560 return insn->n;
561}
562
563static int apci1500_do_insn_bits(struct comedi_device *dev,
564 struct comedi_subdevice *s,
565 struct comedi_insn *insn,
566 unsigned int *data)
567{
568 struct apci1500_private *devpriv = dev->private;
569
570 if (comedi_dio_update_state(s, data))
571 outw(s->state, devpriv->addon + APCI1500_DO_REG);
572
573 data[1] = s->state;
574
575 return insn->n;
576}
577
578static int apci1500_timer_insn_config(struct comedi_device *dev,
579 struct comedi_subdevice *s,
580 struct comedi_insn *insn,
581 unsigned int *data)
582{
583 struct apci1500_private *devpriv = dev->private;
584 unsigned int chan = CR_CHAN(insn->chanspec);
585 unsigned int val;
586
587 switch (data[0]) {
588 case INSN_CONFIG_ARM:
589 val = data[1] & s->maxdata;
590 z8536_write(dev, val & 0xff, Z8536_CT_RELOAD_LSB_REG(chan));
591 z8536_write(dev, (val >> 8) & 0xff,
592 Z8536_CT_RELOAD_MSB_REG(chan));
593
594 apci1500_timer_enable(dev, chan, true);
595 z8536_write(dev, Z8536_CT_CMDSTAT_GCB,
596 Z8536_CT_CMDSTAT_REG(chan));
597 break;
598 case INSN_CONFIG_DISARM:
599 apci1500_timer_enable(dev, chan, false);
600 break;
601
602 case INSN_CONFIG_GET_COUNTER_STATUS:
603 data[1] = 0;
604 val = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
605 if (val & Z8536_CT_STAT_CIP)
606 data[1] |= COMEDI_COUNTER_COUNTING;
607 if (val & Z8536_CT_CMDSTAT_GCB)
608 data[1] |= COMEDI_COUNTER_ARMED;
609 if (val & Z8536_STAT_IP) {
610 data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
611 apci1500_ack_irq(dev, Z8536_CT_CMDSTAT_REG(chan));
612 }
613 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
614 COMEDI_COUNTER_TERMINAL_COUNT;
615 break;
616
617 case INSN_CONFIG_SET_COUNTER_MODE:
618 /* Simulate the 8254 timer modes */
619 switch (data[1]) {
620 case I8254_MODE0:
621 /* Interrupt on Terminal Count */
622 val = Z8536_CT_MODE_ECE |
623 Z8536_CT_MODE_DCS_ONESHOT;
624 break;
625 case I8254_MODE1:
626 /* Hardware Retriggerable One-Shot */
627 val = Z8536_CT_MODE_ETE |
628 Z8536_CT_MODE_DCS_ONESHOT;
629 break;
630 case I8254_MODE2:
631 /* Rate Generator */
632 val = Z8536_CT_MODE_CSC |
633 Z8536_CT_MODE_DCS_PULSE;
634 break;
635 case I8254_MODE3:
636 /* Square Wave Mode */
637 val = Z8536_CT_MODE_CSC |
638 Z8536_CT_MODE_DCS_SQRWAVE;
639 break;
640 case I8254_MODE4:
641 /* Software Triggered Strobe */
642 val = Z8536_CT_MODE_REB |
643 Z8536_CT_MODE_DCS_PULSE;
644 break;
645 case I8254_MODE5:
646 /* Hardware Triggered Strobe (watchdog) */
647 val = Z8536_CT_MODE_EOE |
648 Z8536_CT_MODE_ETE |
649 Z8536_CT_MODE_REB |
650 Z8536_CT_MODE_DCS_PULSE;
651 break;
652 default:
653 return -EINVAL;
654 }
655 apci1500_timer_enable(dev, chan, false);
656 z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
657 break;
658
659 case INSN_CONFIG_SET_CLOCK_SRC:
660 if (data[1] > 2)
661 return -EINVAL;
662 devpriv->clk_src = data[1];
663 if (devpriv->clk_src == 2)
664 devpriv->clk_src = 3;
665 outw(devpriv->clk_src, devpriv->addon + APCI1500_CLK_SEL_REG);
666 break;
667 case INSN_CONFIG_GET_CLOCK_SRC:
668 switch (devpriv->clk_src) {
669 case 0:
670 data[1] = 0; /* 111.86 kHz / 2 */
671 data[2] = 17879; /* 17879 ns (approx) */
672 break;
673 case 1:
674 data[1] = 1; /* 3.49 kHz / 2 */
675 data[2] = 573066; /* 573066 ns (approx) */
676 break;
677 case 3:
678 data[1] = 2; /* 1.747 kHz / 2 */
679 data[2] = 1164822; /* 1164822 ns (approx) */
680 break;
681 default:
682 return -EINVAL;
683 }
684 break;
685
686 case INSN_CONFIG_SET_GATE_SRC:
687 if (chan == 0)
688 return -EINVAL;
689
690 val = z8536_read(dev, Z8536_CT_MODE_REG(chan));
691 val &= Z8536_CT_MODE_EGE;
692 if (data[1] == 1)
693 val |= Z8536_CT_MODE_EGE;
694 else if (data[1] > 1)
695 return -EINVAL;
696 z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
697 break;
698 case INSN_CONFIG_GET_GATE_SRC:
699 if (chan == 0)
700 return -EINVAL;
701 break;
702
703 default:
704 return -EINVAL;
705 }
706 return insn->n;
707}
708
709static int apci1500_timer_insn_write(struct comedi_device *dev,
710 struct comedi_subdevice *s,
711 struct comedi_insn *insn,
712 unsigned int *data)
713{
714 unsigned int chan = CR_CHAN(insn->chanspec);
715 unsigned int cmd;
716
717 cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
718 cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */
719 cmd |= Z8536_CT_CMD_TCB; /* set trigger */
720
721 /* software trigger a timer, it only makes sense to do one write */
722 if (insn->n)
723 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
724
725 return insn->n;
726}
727
728static int apci1500_timer_insn_read(struct comedi_device *dev,
729 struct comedi_subdevice *s,
730 struct comedi_insn *insn,
731 unsigned int *data)
732{
733 unsigned int chan = CR_CHAN(insn->chanspec);
734 unsigned int cmd;
735 unsigned int val;
736 int i;
737
738 cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
739 cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */
740 cmd |= Z8536_CT_CMD_RCC; /* set RCC */
741
742 for (i = 0; i < insn->n; i++) {
743 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
744
745 val = z8536_read(dev, Z8536_CT_VAL_MSB_REG(chan)) << 8;
746 val |= z8536_read(dev, Z8536_CT_VAL_LSB_REG(chan));
747
748 data[i] = val;
749 }
750
751 return insn->n;
752}
20 753
21static int apci1500_auto_attach(struct comedi_device *dev, 754static int apci1500_auto_attach(struct comedi_device *dev,
22 unsigned long context) 755 unsigned long context)
@@ -35,10 +768,10 @@ static int apci1500_auto_attach(struct comedi_device *dev,
35 return ret; 768 return ret;
36 769
37 dev->iobase = pci_resource_start(pcidev, 1); 770 dev->iobase = pci_resource_start(pcidev, 1);
38 devpriv->iobase = dev->iobase; 771 devpriv->amcc = pci_resource_start(pcidev, 0);
39 devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); 772 devpriv->addon = pci_resource_start(pcidev, 2);
40 devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); 773
41 devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); 774 z8536_reset(dev);
42 775
43 if (pcidev->irq > 0) { 776 if (pcidev->irq > 0) {
44 ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED, 777 ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED,
@@ -51,51 +784,66 @@ static int apci1500_auto_attach(struct comedi_device *dev,
51 if (ret) 784 if (ret)
52 return ret; 785 return ret;
53 786
54 /* Allocate and Initialise DI Subdevice Structures */ 787 /* Digital Input subdevice */
55 s = &dev->subdevices[0]; 788 s = &dev->subdevices[0];
56 s->type = COMEDI_SUBD_DI; 789 s->type = COMEDI_SUBD_DI;
57 s->subdev_flags = SDF_READABLE; 790 s->subdev_flags = SDF_READABLE;
58 s->n_chan = 16; 791 s->n_chan = 16;
59 s->maxdata = 1; 792 s->maxdata = 1;
60 s->range_table = &range_digital; 793 s->range_table = &range_digital;
61 s->insn_config = apci1500_di_config; 794 s->insn_bits = apci1500_di_insn_bits;
62 s->insn_read = apci1500_di_read; 795 if (dev->irq) {
63 s->insn_write = apci1500_di_write; 796 dev->read_subdev = s;
64 s->insn_bits = apci1500_di_insn_bits; 797 s->subdev_flags |= SDF_CMD_READ;
65 798 s->len_chanlist = 1;
66 /* Allocate and Initialise DO Subdevice Structures */ 799 s->insn_config = apci1500_di_insn_config;
800 s->do_cmdtest = apci1500_di_cmdtest;
801 s->do_cmd = apci1500_di_cmd;
802 s->cancel = apci1500_di_cancel;
803 }
804
805 /* Digital Output subdevice */
67 s = &dev->subdevices[1]; 806 s = &dev->subdevices[1];
68 s->type = COMEDI_SUBD_DO; 807 s->type = COMEDI_SUBD_DO;
69 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 808 s->subdev_flags = SDF_WRITABLE;
70 s->n_chan = 16; 809 s->n_chan = 16;
71 s->maxdata = 1; 810 s->maxdata = 1;
72 s->range_table = &range_digital; 811 s->range_table = &range_digital;
73 s->insn_config = apci1500_do_config; 812 s->insn_bits = apci1500_do_insn_bits;
74 s->insn_write = apci1500_do_write; 813
75 s->insn_bits = apci1500_do_bits; 814 /* reset all the digital outputs */
76 815 outw(0x0, devpriv->addon + APCI1500_DO_REG);
77 /* Allocate and Initialise Timer Subdevice Structures */ 816
817 /* Counter/Timer(Watchdog) subdevice */
78 s = &dev->subdevices[2]; 818 s = &dev->subdevices[2];
79 s->type = COMEDI_SUBD_TIMER; 819 s->type = COMEDI_SUBD_TIMER;
80 s->subdev_flags = SDF_WRITABLE; 820 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
81 s->n_chan = 1; 821 s->n_chan = 3;
82 s->maxdata = 0; 822 s->maxdata = 0xffff;
83 s->len_chanlist = 1; 823 s->range_table = &range_unknown;
84 s->range_table = &range_digital; 824 s->insn_config = apci1500_timer_insn_config;
85 s->insn_write = apci1500_timer_write; 825 s->insn_write = apci1500_timer_insn_write;
86 s->insn_read = apci1500_timer_read; 826 s->insn_read = apci1500_timer_insn_read;
87 s->insn_config = apci1500_timer_config; 827
88 s->insn_bits = apci1500_timer_bits; 828 /* Enable the PCI interrupt */
89 829 if (dev->irq) {
90 apci1500_reset(dev); 830 outl(0x2000 | INTCSR_INBOX_FULL_INT,
831 devpriv->amcc + AMCC_OP_REG_INTCSR);
832 inl(devpriv->amcc + AMCC_OP_REG_IMB1);
833 inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
834 outl(INTCSR_INBOX_INTR_STATUS | 0x2000 | INTCSR_INBOX_FULL_INT,
835 devpriv->amcc + AMCC_OP_REG_INTCSR);
836 }
91 837
92 return 0; 838 return 0;
93} 839}
94 840
95static void apci1500_detach(struct comedi_device *dev) 841static void apci1500_detach(struct comedi_device *dev)
96{ 842{
97 if (dev->iobase) 843 struct apci1500_private *devpriv = dev->private;
98 apci1500_reset(dev); 844
845 if (devpriv->amcc)
846 outl(0x0, devpriv->amcc + AMCC_OP_REG_INTCSR);
99 comedi_pci_detach(dev); 847 comedi_pci_detach(dev);
100} 848}
101 849
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index a726efcea6a5..5961f195ba0b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -267,7 +267,6 @@ static irqreturn_t apci3501_interrupt(int irq, void *d)
267 struct apci3501_private *devpriv = dev->private; 267 struct apci3501_private *devpriv = dev->private;
268 unsigned int ui_Timer_AOWatchdog; 268 unsigned int ui_Timer_AOWatchdog;
269 unsigned long ul_Command1; 269 unsigned long ul_Command1;
270 int i_temp;
271 270
272 /* Disable Interrupt */ 271 /* Disable Interrupt */
273 ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); 272 ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG);
@@ -285,7 +284,7 @@ static irqreturn_t apci3501_interrupt(int irq, void *d)
285 ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); 284 ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG);
286 ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1); 285 ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
287 outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); 286 outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG);
288 i_temp = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; 287 inl(dev->iobase + APCI3501_TIMER_STATUS_REG);
289 288
290 return IRQ_HANDLED; 289 return IRQ_HANDLED;
291} 290}
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index 528f15c25dae..a3ea4b7c18dd 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: adl_pci6208 20 * Driver: adl_pci6208
21 * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards 21 * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
22 * Devices: (ADLink) PCI-6208 [adl_pci6208] 22 * Devices: [ADLink] PCI-6208 (adl_pci6208), PCI-6216 (adl_pci6216)
23 * (ADLink) PCI-6216 [adl_pci6216]
24 * Author: nsyeow <nsyeow@pd.jaring.my> 23 * Author: nsyeow <nsyeow@pd.jaring.my>
25 * Updated: Fri, 30 Jan 2004 14:44:27 +0800 24 * Updated: Fri, 30 Jan 2004 14:44:27 +0800
26 * Status: untested 25 * Status: untested
diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c
index fb8e5f582496..618e641ffaac 100644
--- a/drivers/staging/comedi/drivers/adl_pci7x3x.c
+++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c
@@ -22,27 +22,35 @@
22 */ 22 */
23 23
24/* 24/*
25Driver: adl_pci7x3x 25 * Driver: adl_pci7x3x
26Description: 32/64-Channel Isolated Digital I/O Boards 26 * Description: 32/64-Channel Isolated Digital I/O Boards
27Devices: (ADLink) PCI-7230 [adl_pci7230] - 16 input / 16 output 27 * Devices: [ADLink] PCI-7230 (adl_pci7230), PCI-7233 (adl_pci7233),
28 (ADLink) PCI-7233 [adl_pci7233] - 32 input 28 * PCI-7234 (adl_pci7234), PCI-7432 (adl_pci7432), PCI-7433 (adl_pci7433),
29 (ADLink) PCI-7234 [adl_pci7234] - 32 output 29 * PCI-7434 (adl_pci7434)
30 (ADLink) PCI-7432 [adl_pci7432] - 32 input / 32 output 30 * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
31 (ADLink) PCI-7433 [adl_pci7433] - 64 input 31 * Updated: Thu, 02 Aug 2012 14:27:46 -0700
32 (ADLink) PCI-7434 [adl_pci7434] - 64 output 32 * Status: untested
33Author: H Hartley Sweeten <hsweeten@visionengravers.com> 33 *
34Updated: Thu, 02 Aug 2012 14:27:46 -0700 34 * One or two subdevices are setup by this driver depending on
35Status: untested 35 * the number of digital inputs and/or outputs provided by the
36 36 * board. Each subdevice has a maximum of 32 channels.
37The PCI-7230, PCI-7432 and PCI-7433 boards also support external 37 *
38interrupt signals on digital input channels 0 and 1. The PCI-7233 38 * PCI-7230 - 2 subdevices: 0 - 16 input, 1 - 16 output
39has dual-interrupt sources for change-of-state (COS) on any 16 39 * PCI-7233 - 1 subdevice: 0 - 32 input
40digital input channels of LSB and for COS on any 16 digital input 40 * PCI-7234 - 1 subdevice: 0 - 32 output
41lines of MSB. Interrupts are not currently supported by this 41 * PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
42driver. 42 * PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
43 43 * PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
44Configuration Options: not applicable, uses comedi PCI auto config 44 *
45*/ 45 * The PCI-7230, PCI-7432 and PCI-7433 boards also support external
46 * interrupt signals on digital input channels 0 and 1. The PCI-7233
47 * has dual-interrupt sources for change-of-state (COS) on any 16
48 * digital input channels of LSB and for COS on any 16 digital input
49 * lines of MSB. Interrupts are not currently supported by this
50 * driver.
51 *
52 * Configuration Options: not applicable, uses comedi PCI auto config
53 */
46 54
47#include <linux/module.h> 55#include <linux/module.h>
48#include <linux/pci.h> 56#include <linux/pci.h>
@@ -155,18 +163,6 @@ static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
155 return ret; 163 return ret;
156 dev->iobase = pci_resource_start(pcidev, 2); 164 dev->iobase = pci_resource_start(pcidev, 2);
157 165
158 /*
159 * One or two subdevices are setup by this driver depending on
160 * the number of digital inputs and/or outputs provided by the
161 * board. Each subdevice has a maximum of 32 channels.
162 *
163 * PCI-7230 - 2 subdevices: 0 - 16 input, 1 - 16 output
164 * PCI-7233 - 1 subdevice: 0 - 32 input
165 * PCI-7234 - 1 subdevice: 0 - 32 output
166 * PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
167 * PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
168 * PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
169 */
170 ret = comedi_alloc_subdevices(dev, board->nsubdevs); 166 ret = comedi_alloc_subdevices(dev, board->nsubdevs);
171 if (ret) 167 if (ret)
172 return ret; 168 return ret;
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index 72bccb447a74..cc6c53b800a7 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -18,7 +18,7 @@
18/* 18/*
19 * Driver: adl_pci8164 19 * Driver: adl_pci8164
20 * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board 20 * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
21 * Devices: (ADLink) PCI-8164 [adl_pci8164] 21 * Devices: [ADLink] PCI-8164 (adl_pci8164)
22 * Author: Michel Lachaine <mike@mikelachaine.ca> 22 * Author: Michel Lachaine <mike@mikelachaine.ca>
23 * Status: experimental 23 * Status: experimental
24 * Updated: Mon, 14 Apr 2008 15:10:32 +0100 24 * Updated: Mon, 14 Apr 2008 15:10:32 +0100
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 47f6c0e9f014..f68dc99f8e27 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -539,7 +539,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
539 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 539 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
540 dev_dbg(dev->class_dev, "fifo overflow\n"); 540 dev_dbg(dev->class_dev, "fifo overflow\n");
541 outb(0, dev->iobase + PCI9111_INT_CLR_REG); 541 outb(0, dev->iobase + PCI9111_INT_CLR_REG);
542 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 542 async->events |= COMEDI_CB_ERROR;
543 comedi_handle_events(dev, s); 543 comedi_handle_events(dev, s);
544 544
545 return IRQ_HANDLED; 545 return IRQ_HANDLED;
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 26603582e71a..f61e392c2d3e 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -749,13 +749,13 @@ static irqreturn_t pci9118_interrupt(int irq, void *d)
749 749
750 if (intcsr & MASTER_ABORT_INT) { 750 if (intcsr & MASTER_ABORT_INT) {
751 dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); 751 dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
752 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 752 s->async->events |= COMEDI_CB_ERROR;
753 goto interrupt_exit; 753 goto interrupt_exit;
754 } 754 }
755 755
756 if (intcsr & TARGET_ABORT_INT) { 756 if (intcsr & TARGET_ABORT_INT) {
757 dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); 757 dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
758 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 758 s->async->events |= COMEDI_CB_ERROR;
759 goto interrupt_exit; 759 goto interrupt_exit;
760 } 760 }
761 761
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index d02df7d0c629..9800c01e6fb9 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -51,11 +51,6 @@ Configuration options:
51#include "8253.h" 51#include "8253.h"
52#include "amcc_s5933.h" 52#include "amcc_s5933.h"
53 53
54/* hardware types of the cards */
55#define TYPE_PCI171X 0
56#define TYPE_PCI1713 2
57#define TYPE_PCI1720 3
58
59#define PCI171x_AD_DATA 0 /* R: A/D data */ 54#define PCI171x_AD_DATA 0 /* R: A/D data */
60#define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */ 55#define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */
61#define PCI171x_RANGE 2 /* W: A/D gain/range register */ 56#define PCI171x_RANGE 2 /* W: A/D gain/range register */
@@ -164,7 +159,7 @@ static const struct comedi_lrange range_pci17x1 = {
164 159
165static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 }; 160static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
166 161
167static const struct comedi_lrange range_pci1720 = { 162static const struct comedi_lrange pci1720_ao_range = {
168 4, { 163 4, {
169 UNI_RANGE(5), 164 UNI_RANGE(5),
170 UNI_RANGE(10), 165 UNI_RANGE(10),
@@ -173,7 +168,7 @@ static const struct comedi_lrange range_pci1720 = {
173 } 168 }
174}; 169};
175 170
176static const struct comedi_lrange range_pci171x_da = { 171static const struct comedi_lrange pci171x_ao_range = {
177 2, { 172 2, {
178 UNI_RANGE(5), 173 UNI_RANGE(5),
179 UNI_RANGE(10) 174 UNI_RANGE(10)
@@ -191,112 +186,81 @@ enum pci1710_boardid {
191 186
192struct boardtype { 187struct boardtype {
193 const char *name; /* board name */ 188 const char *name; /* board name */
194 char have_irq; /* 1=card support IRQ */
195 char cardtype; /* 0=1710& co. 2=1713, ... */
196 int n_aichan; /* num of A/D chans */ 189 int n_aichan; /* num of A/D chans */
197 int n_aichand; /* num of A/D chans in diff mode */
198 int n_aochan; /* num of D/A chans */
199 int n_dichan; /* num of DI chans */
200 int n_dochan; /* num of DO chans */
201 int n_counter; /* num of counters */
202 int ai_maxdata; /* resolution of A/D */
203 int ao_maxdata; /* resolution of D/A */
204 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ 190 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
205 const char *rangecode_ai; /* range codes for programming */ 191 const char *rangecode_ai; /* range codes for programming */
206 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ 192 unsigned int is_pci1713:1;
207 unsigned int ai_ns_min; /* max sample speed of card v ns */ 193 unsigned int is_pci1720:1;
208 unsigned int fifo_half_size; /* size of FIFO/2 */ 194 unsigned int has_irq:1;
195 unsigned int has_large_fifo:1; /* 4K or 1K FIFO */
196 unsigned int has_diff_ai:1;
197 unsigned int has_ao:1;
198 unsigned int has_di_do:1;
199 unsigned int has_counter:1;
209}; 200};
210 201
211static const struct boardtype boardtypes[] = { 202static const struct boardtype boardtypes[] = {
212 [BOARD_PCI1710] = { 203 [BOARD_PCI1710] = {
213 .name = "pci1710", 204 .name = "pci1710",
214 .have_irq = 1,
215 .cardtype = TYPE_PCI171X,
216 .n_aichan = 16, 205 .n_aichan = 16,
217 .n_aichand = 8,
218 .n_aochan = 2,
219 .n_dichan = 16,
220 .n_dochan = 16,
221 .n_counter = 1,
222 .ai_maxdata = 0x0fff,
223 .ao_maxdata = 0x0fff,
224 .rangelist_ai = &range_pci1710_3, 206 .rangelist_ai = &range_pci1710_3,
225 .rangecode_ai = range_codes_pci1710_3, 207 .rangecode_ai = range_codes_pci1710_3,
226 .rangelist_ao = &range_pci171x_da, 208 .has_irq = 1,
227 .ai_ns_min = 10000, 209 .has_large_fifo = 1,
228 .fifo_half_size = 2048, 210 .has_diff_ai = 1,
211 .has_ao = 1,
212 .has_di_do = 1,
213 .has_counter = 1,
229 }, 214 },
230 [BOARD_PCI1710HG] = { 215 [BOARD_PCI1710HG] = {
231 .name = "pci1710hg", 216 .name = "pci1710hg",
232 .have_irq = 1,
233 .cardtype = TYPE_PCI171X,
234 .n_aichan = 16, 217 .n_aichan = 16,
235 .n_aichand = 8,
236 .n_aochan = 2,
237 .n_dichan = 16,
238 .n_dochan = 16,
239 .n_counter = 1,
240 .ai_maxdata = 0x0fff,
241 .ao_maxdata = 0x0fff,
242 .rangelist_ai = &range_pci1710hg, 218 .rangelist_ai = &range_pci1710hg,
243 .rangecode_ai = range_codes_pci1710hg, 219 .rangecode_ai = range_codes_pci1710hg,
244 .rangelist_ao = &range_pci171x_da, 220 .has_irq = 1,
245 .ai_ns_min = 10000, 221 .has_large_fifo = 1,
246 .fifo_half_size = 2048, 222 .has_diff_ai = 1,
223 .has_ao = 1,
224 .has_di_do = 1,
225 .has_counter = 1,
247 }, 226 },
248 [BOARD_PCI1711] = { 227 [BOARD_PCI1711] = {
249 .name = "pci1711", 228 .name = "pci1711",
250 .have_irq = 1,
251 .cardtype = TYPE_PCI171X,
252 .n_aichan = 16, 229 .n_aichan = 16,
253 .n_aochan = 2,
254 .n_dichan = 16,
255 .n_dochan = 16,
256 .n_counter = 1,
257 .ai_maxdata = 0x0fff,
258 .ao_maxdata = 0x0fff,
259 .rangelist_ai = &range_pci17x1, 230 .rangelist_ai = &range_pci17x1,
260 .rangecode_ai = range_codes_pci17x1, 231 .rangecode_ai = range_codes_pci17x1,
261 .rangelist_ao = &range_pci171x_da, 232 .has_irq = 1,
262 .ai_ns_min = 10000, 233 .has_ao = 1,
263 .fifo_half_size = 512, 234 .has_di_do = 1,
235 .has_counter = 1,
264 }, 236 },
265 [BOARD_PCI1713] = { 237 [BOARD_PCI1713] = {
266 .name = "pci1713", 238 .name = "pci1713",
267 .have_irq = 1,
268 .cardtype = TYPE_PCI1713,
269 .n_aichan = 32, 239 .n_aichan = 32,
270 .n_aichand = 16,
271 .ai_maxdata = 0x0fff,
272 .rangelist_ai = &range_pci1710_3, 240 .rangelist_ai = &range_pci1710_3,
273 .rangecode_ai = range_codes_pci1710_3, 241 .rangecode_ai = range_codes_pci1710_3,
274 .ai_ns_min = 10000, 242 .is_pci1713 = 1,
275 .fifo_half_size = 2048, 243 .has_irq = 1,
244 .has_large_fifo = 1,
245 .has_diff_ai = 1,
276 }, 246 },
277 [BOARD_PCI1720] = { 247 [BOARD_PCI1720] = {
278 .name = "pci1720", 248 .name = "pci1720",
279 .cardtype = TYPE_PCI1720, 249 .is_pci1720 = 1,
280 .n_aochan = 4, 250 .has_ao = 1,
281 .ao_maxdata = 0x0fff,
282 .rangelist_ao = &range_pci1720,
283 }, 251 },
284 [BOARD_PCI1731] = { 252 [BOARD_PCI1731] = {
285 .name = "pci1731", 253 .name = "pci1731",
286 .have_irq = 1,
287 .cardtype = TYPE_PCI171X,
288 .n_aichan = 16, 254 .n_aichan = 16,
289 .n_dichan = 16,
290 .n_dochan = 16,
291 .ai_maxdata = 0x0fff,
292 .rangelist_ai = &range_pci17x1, 255 .rangelist_ai = &range_pci17x1,
293 .rangecode_ai = range_codes_pci17x1, 256 .rangecode_ai = range_codes_pci17x1,
294 .ai_ns_min = 10000, 257 .has_irq = 1,
295 .fifo_half_size = 512, 258 .has_di_do = 1,
296 }, 259 },
297}; 260};
298 261
299struct pci1710_private { 262struct pci1710_private {
263 unsigned int max_samples;
300 unsigned int CntrlReg; /* Control register */ 264 unsigned int CntrlReg; /* Control register */
301 unsigned char ai_et; 265 unsigned char ai_et;
302 unsigned int ai_et_CntrlReg; 266 unsigned int ai_et_CntrlReg;
@@ -308,39 +272,10 @@ struct pci1710_private {
308 unsigned int act_chanlist[32]; /* list of scanned channel */ 272 unsigned int act_chanlist[32]; /* list of scanned channel */
309 unsigned char saved_seglen; /* len of the non-repeating chanlist */ 273 unsigned char saved_seglen; /* len of the non-repeating chanlist */
310 unsigned char da_ranges; /* copy of D/A outpit range register */ 274 unsigned char da_ranges; /* copy of D/A outpit range register */
311 unsigned short ao_data[4]; /* data output buffer */
312 unsigned int cnt0_write_wait; /* after a write, wait for update of the 275 unsigned int cnt0_write_wait; /* after a write, wait for update of the
313 * internal state */ 276 * internal state */
314}; 277};
315 278
316/* used for gain list programming */
317static const unsigned int muxonechan[] = {
318 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
319 0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
320 0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
321 0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
322};
323
324static int pci171x_ai_dropout(struct comedi_device *dev,
325 struct comedi_subdevice *s,
326 unsigned int chan,
327 unsigned int val)
328{
329 const struct boardtype *board = dev->board_ptr;
330 struct pci1710_private *devpriv = dev->private;
331
332 if (board->cardtype != TYPE_PCI1713) {
333 if ((val & 0xf000) != devpriv->act_chanlist[chan]) {
334 dev_err(dev->class_dev,
335 "A/D data droput: received from channel %d, expected %d\n",
336 (val >> 12) & 0xf,
337 (devpriv->act_chanlist[chan] >> 12) & 0xf);
338 return -ENODATA;
339 }
340 }
341 return 0;
342}
343
344static int pci171x_ai_check_chanlist(struct comedi_device *dev, 279static int pci171x_ai_check_chanlist(struct comedi_device *dev,
345 struct comedi_subdevice *s, 280 struct comedi_subdevice *s,
346 struct comedi_cmd *cmd) 281 struct comedi_cmd *cmd)
@@ -407,33 +342,39 @@ static int pci171x_ai_check_chanlist(struct comedi_device *dev,
407 return 0; 342 return 0;
408} 343}
409 344
410static void setup_channel_list(struct comedi_device *dev, 345static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
411 struct comedi_subdevice *s, 346 struct comedi_subdevice *s,
412 unsigned int *chanlist, unsigned int n_chan, 347 unsigned int *chanlist,
413 unsigned int seglen) 348 unsigned int n_chan,
349 unsigned int seglen)
414{ 350{
415 const struct boardtype *this_board = dev->board_ptr; 351 const struct boardtype *board = dev->board_ptr;
416 struct pci1710_private *devpriv = dev->private; 352 struct pci1710_private *devpriv = dev->private;
417 unsigned int i, range, chanprog; 353 unsigned int first_chan = CR_CHAN(chanlist[0]);
354 unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]);
355 unsigned int i;
418 356
419 for (i = 0; i < seglen; i++) { /* store range list to card */ 357 for (i = 0; i < seglen; i++) { /* store range list to card */
420 chanprog = muxonechan[CR_CHAN(chanlist[i])]; 358 unsigned int chan = CR_CHAN(chanlist[i]);
421 outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ 359 unsigned int range = CR_RANGE(chanlist[i]);
422 range = this_board->rangecode_ai[CR_RANGE(chanlist[i])]; 360 unsigned int aref = CR_AREF(chanlist[i]);
423 if (CR_AREF(chanlist[i]) == AREF_DIFF) 361 unsigned int rangeval;
424 range |= 0x0020; 362
425 outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ 363 rangeval = board->rangecode_ai[range];
426 devpriv->act_chanlist[i] = 364 if (aref == AREF_DIFF)
427 (CR_CHAN(chanlist[i]) << 12) & 0xf000; 365 rangeval |= 0x0020;
428 } 366
429 for ( ; i < n_chan; i++) { /* store remainder of channel list */ 367 /* select channel and set range */
430 devpriv->act_chanlist[i] = 368 outw(chan | (chan << 8), dev->iobase + PCI171x_MUX);
431 (CR_CHAN(chanlist[i]) << 12) & 0xf000; 369 outw(rangeval, dev->iobase + PCI171x_RANGE);
370
371 devpriv->act_chanlist[i] = chan;
432 } 372 }
373 for ( ; i < n_chan; i++) /* store remainder of channel list */
374 devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
433 375
434 devpriv->ai_et_MuxVal =
435 CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
436 /* select channel interval to scan */ 376 /* select channel interval to scan */
377 devpriv->ai_et_MuxVal = first_chan | (last_chan << 8);
437 outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); 378 outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
438} 379}
439 380
@@ -450,9 +391,39 @@ static int pci171x_ai_eoc(struct comedi_device *dev,
450 return -EBUSY; 391 return -EBUSY;
451} 392}
452 393
453static int pci171x_insn_read_ai(struct comedi_device *dev, 394static int pci171x_ai_read_sample(struct comedi_device *dev,
395 struct comedi_subdevice *s,
396 unsigned int cur_chan,
397 unsigned int *val)
398{
399 const struct boardtype *board = dev->board_ptr;
400 struct pci1710_private *devpriv = dev->private;
401 unsigned int sample;
402 unsigned int chan;
403
404 sample = inw(dev->iobase + PCI171x_AD_DATA);
405 if (!board->is_pci1713) {
406 /*
407 * The upper 4 bits of the 16-bit sample are the channel number
408 * that the sample was acquired from. Verify that this channel
409 * number matches the expected channel number.
410 */
411 chan = sample >> 12;
412 if (chan != devpriv->act_chanlist[cur_chan]) {
413 dev_err(dev->class_dev,
414 "A/D data droput: received from channel %d, expected %d\n",
415 chan, devpriv->act_chanlist[cur_chan]);
416 return -ENODATA;
417 }
418 }
419 *val = sample & s->maxdata;
420 return 0;
421}
422
423static int pci171x_ai_insn_read(struct comedi_device *dev,
454 struct comedi_subdevice *s, 424 struct comedi_subdevice *s,
455 struct comedi_insn *insn, unsigned int *data) 425 struct comedi_insn *insn,
426 unsigned int *data)
456{ 427{
457 struct pci1710_private *devpriv = dev->private; 428 struct pci1710_private *devpriv = dev->private;
458 unsigned int chan = CR_CHAN(insn->chanspec); 429 unsigned int chan = CR_CHAN(insn->chanspec);
@@ -465,7 +436,7 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
465 outb(0, dev->iobase + PCI171x_CLRFIFO); 436 outb(0, dev->iobase + PCI171x_CLRFIFO);
466 outb(0, dev->iobase + PCI171x_CLRINT); 437 outb(0, dev->iobase + PCI171x_CLRINT);
467 438
468 setup_channel_list(dev, s, &insn->chanspec, 1, 1); 439 pci171x_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1);
469 440
470 for (i = 0; i < insn->n; i++) { 441 for (i = 0; i < insn->n; i++) {
471 unsigned int val; 442 unsigned int val;
@@ -476,12 +447,11 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
476 if (ret) 447 if (ret)
477 break; 448 break;
478 449
479 val = inw(dev->iobase + PCI171x_AD_DATA); 450 ret = pci171x_ai_read_sample(dev, s, chan, &val);
480 ret = pci171x_ai_dropout(dev, s, chan, val);
481 if (ret) 451 if (ret)
482 break; 452 break;
483 453
484 data[i] = val & s->maxdata; 454 data[i] = val;
485 } 455 }
486 456
487 outb(0, dev->iobase + PCI171x_CLRFIFO); 457 outb(0, dev->iobase + PCI171x_CLRFIFO);
@@ -490,73 +460,43 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
490 return ret ? ret : insn->n; 460 return ret ? ret : insn->n;
491} 461}
492 462
493/* 463static int pci171x_ao_insn_write(struct comedi_device *dev,
494==============================================================================
495*/
496static int pci171x_insn_write_ao(struct comedi_device *dev,
497 struct comedi_subdevice *s, 464 struct comedi_subdevice *s,
498 struct comedi_insn *insn, unsigned int *data) 465 struct comedi_insn *insn,
466 unsigned int *data)
499{ 467{
500 struct pci1710_private *devpriv = dev->private; 468 struct pci1710_private *devpriv = dev->private;
501 unsigned int val; 469 unsigned int chan = CR_CHAN(insn->chanspec);
502 int n, chan, range, ofs; 470 unsigned int range = CR_RANGE(insn->chanspec);
503 471 unsigned int reg = chan ? PCI171x_DA2 : PCI171x_DA1;
504 chan = CR_CHAN(insn->chanspec); 472 unsigned int val = s->readback[chan];
505 range = CR_RANGE(insn->chanspec); 473 int i;
506 if (chan) {
507 devpriv->da_ranges &= 0xfb;
508 devpriv->da_ranges |= (range << 2);
509 outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
510 ofs = PCI171x_DA2;
511 } else {
512 devpriv->da_ranges &= 0xfe;
513 devpriv->da_ranges |= range;
514 outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
515 ofs = PCI171x_DA1;
516 }
517 val = devpriv->ao_data[chan];
518
519 for (n = 0; n < insn->n; n++) {
520 val = data[n];
521 outw(val, dev->iobase + ofs);
522 }
523
524 devpriv->ao_data[chan] = val;
525
526 return n;
527 474
528} 475 devpriv->da_ranges &= ~(1 << (chan << 1));
476 devpriv->da_ranges |= (range << (chan << 1));
477 outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
529 478
530/* 479 for (i = 0; i < insn->n; i++) {
531============================================================================== 480 val = data[i];
532*/ 481 outw(val, dev->iobase + reg);
533static int pci171x_insn_read_ao(struct comedi_device *dev, 482 }
534 struct comedi_subdevice *s,
535 struct comedi_insn *insn, unsigned int *data)
536{
537 struct pci1710_private *devpriv = dev->private;
538 int n, chan;
539 483
540 chan = CR_CHAN(insn->chanspec); 484 s->readback[chan] = val;
541 for (n = 0; n < insn->n; n++)
542 data[n] = devpriv->ao_data[chan];
543 485
544 return n; 486 return insn->n;
545} 487}
546 488
547/* 489static int pci171x_di_insn_bits(struct comedi_device *dev,
548==============================================================================
549*/
550static int pci171x_insn_bits_di(struct comedi_device *dev,
551 struct comedi_subdevice *s, 490 struct comedi_subdevice *s,
552 struct comedi_insn *insn, unsigned int *data) 491 struct comedi_insn *insn,
492 unsigned int *data)
553{ 493{
554 data[1] = inw(dev->iobase + PCI171x_DI); 494 data[1] = inw(dev->iobase + PCI171x_DI);
555 495
556 return insn->n; 496 return insn->n;
557} 497}
558 498
559static int pci171x_insn_bits_do(struct comedi_device *dev, 499static int pci171x_do_insn_bits(struct comedi_device *dev,
560 struct comedi_subdevice *s, 500 struct comedi_subdevice *s,
561 struct comedi_insn *insn, 501 struct comedi_insn *insn,
562 unsigned int *data) 502 unsigned int *data)
@@ -584,10 +524,7 @@ static void pci171x_start_pacer(struct comedi_device *dev,
584 } 524 }
585} 525}
586 526
587/* 527static int pci171x_counter_insn_read(struct comedi_device *dev,
588==============================================================================
589*/
590static int pci171x_insn_counter_read(struct comedi_device *dev,
591 struct comedi_subdevice *s, 528 struct comedi_subdevice *s,
592 struct comedi_insn *insn, 529 struct comedi_insn *insn,
593 unsigned int *data) 530 unsigned int *data)
@@ -608,10 +545,7 @@ static int pci171x_insn_counter_read(struct comedi_device *dev,
608 return insn->n; 545 return insn->n;
609} 546}
610 547
611/* 548static int pci171x_counter_insn_write(struct comedi_device *dev,
612==============================================================================
613*/
614static int pci171x_insn_counter_write(struct comedi_device *dev,
615 struct comedi_subdevice *s, 549 struct comedi_subdevice *s,
616 struct comedi_insn *insn, 550 struct comedi_insn *insn,
617 unsigned int *data) 551 unsigned int *data)
@@ -638,10 +572,7 @@ static int pci171x_insn_counter_write(struct comedi_device *dev,
638 return insn->n; 572 return insn->n;
639} 573}
640 574
641/* 575static int pci171x_counter_insn_config(struct comedi_device *dev,
642==============================================================================
643*/
644static int pci171x_insn_counter_config(struct comedi_device *dev,
645 struct comedi_subdevice *s, 576 struct comedi_subdevice *s,
646 struct comedi_insn *insn, 577 struct comedi_insn *insn,
647 unsigned int *data) 578 unsigned int *data)
@@ -677,57 +608,48 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
677 return 1; 608 return 1;
678} 609}
679 610
680/* 611static int pci1720_ao_insn_write(struct comedi_device *dev,
681==============================================================================
682*/
683static int pci1720_insn_write_ao(struct comedi_device *dev,
684 struct comedi_subdevice *s, 612 struct comedi_subdevice *s,
685 struct comedi_insn *insn, unsigned int *data) 613 struct comedi_insn *insn,
614 unsigned int *data)
686{ 615{
687 struct pci1710_private *devpriv = dev->private; 616 struct pci1710_private *devpriv = dev->private;
617 unsigned int chan = CR_CHAN(insn->chanspec);
618 unsigned int range = CR_RANGE(insn->chanspec);
688 unsigned int val; 619 unsigned int val;
689 int n, rangereg, chan; 620 int i;
690 621
691 chan = CR_CHAN(insn->chanspec); 622 val = devpriv->da_ranges & (~(0x03 << (chan << 1)));
692 rangereg = devpriv->da_ranges & (~(0x03 << (chan << 1))); 623 val |= (range << (chan << 1));
693 rangereg |= (CR_RANGE(insn->chanspec) << (chan << 1)); 624 if (val != devpriv->da_ranges) {
694 if (rangereg != devpriv->da_ranges) { 625 outb(val, dev->iobase + PCI1720_RANGE);
695 outb(rangereg, dev->iobase + PCI1720_RANGE); 626 devpriv->da_ranges = val;
696 devpriv->da_ranges = rangereg;
697 } 627 }
698 val = devpriv->ao_data[chan];
699 628
700 for (n = 0; n < insn->n; n++) { 629 val = s->readback[chan];
701 val = data[n]; 630 for (i = 0; i < insn->n; i++) {
631 val = data[i];
702 outw(val, dev->iobase + PCI1720_DA0 + (chan << 1)); 632 outw(val, dev->iobase + PCI1720_DA0 + (chan << 1));
703 outb(0, dev->iobase + PCI1720_SYNCOUT); /* update outputs */ 633 outb(0, dev->iobase + PCI1720_SYNCOUT); /* update outputs */
704 } 634 }
705 635
706 devpriv->ao_data[chan] = val; 636 s->readback[chan] = val;
707 637
708 return n; 638 return insn->n;
709} 639}
710 640
711/*
712==============================================================================
713*/
714static int pci171x_ai_cancel(struct comedi_device *dev, 641static int pci171x_ai_cancel(struct comedi_device *dev,
715 struct comedi_subdevice *s) 642 struct comedi_subdevice *s)
716{ 643{
717 const struct boardtype *this_board = dev->board_ptr;
718 struct pci1710_private *devpriv = dev->private; 644 struct pci1710_private *devpriv = dev->private;
719 645
720 switch (this_board->cardtype) { 646 devpriv->CntrlReg &= Control_CNT0;
721 default: 647 devpriv->CntrlReg |= Control_SW;
722 devpriv->CntrlReg &= Control_CNT0; 648 /* reset any operations */
723 devpriv->CntrlReg |= Control_SW; 649 outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
724 /* reset any operations */ 650 pci171x_start_pacer(dev, false);
725 outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); 651 outb(0, dev->iobase + PCI171x_CLRFIFO);
726 pci171x_start_pacer(dev, false); 652 outb(0, dev->iobase + PCI171x_CLRINT);
727 outb(0, dev->iobase + PCI171x_CLRFIFO);
728 outb(0, dev->iobase + PCI171x_CLRINT);
729 break;
730 }
731 653
732 return 0; 654 return 0;
733} 655}
@@ -743,29 +665,25 @@ static void pci1710_handle_every_sample(struct comedi_device *dev,
743 status = inw(dev->iobase + PCI171x_STATUS); 665 status = inw(dev->iobase + PCI171x_STATUS);
744 if (status & Status_FE) { 666 if (status & Status_FE) {
745 dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status); 667 dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status);
746 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 668 s->async->events |= COMEDI_CB_ERROR;
747 comedi_handle_events(dev, s);
748 return; 669 return;
749 } 670 }
750 if (status & Status_FF) { 671 if (status & Status_FF) {
751 dev_dbg(dev->class_dev, 672 dev_dbg(dev->class_dev,
752 "A/D FIFO Full status (Fatal Error!) (%4x)\n", status); 673 "A/D FIFO Full status (Fatal Error!) (%4x)\n", status);
753 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 674 s->async->events |= COMEDI_CB_ERROR;
754 comedi_handle_events(dev, s);
755 return; 675 return;
756 } 676 }
757 677
758 outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ 678 outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */
759 679
760 for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) { 680 for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
761 val = inw(dev->iobase + PCI171x_AD_DATA); 681 ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val);
762 ret = pci171x_ai_dropout(dev, s, s->async->cur_chan, val);
763 if (ret) { 682 if (ret) {
764 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 683 s->async->events |= COMEDI_CB_ERROR;
765 break; 684 break;
766 } 685 }
767 686
768 val &= s->maxdata;
769 comedi_buf_write_samples(s, &val, 1); 687 comedi_buf_write_samples(s, &val, 1);
770 688
771 if (cmd->stop_src == TRIG_COUNT && 689 if (cmd->stop_src == TRIG_COUNT &&
@@ -776,85 +694,53 @@ static void pci1710_handle_every_sample(struct comedi_device *dev,
776 } 694 }
777 695
778 outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ 696 outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */
779
780 comedi_handle_events(dev, s);
781}
782
783/*
784==============================================================================
785*/
786static int move_block_from_fifo(struct comedi_device *dev,
787 struct comedi_subdevice *s, int n, int turn)
788{
789 unsigned int val;
790 int ret;
791 int i;
792
793 for (i = 0; i < n; i++) {
794 val = inw(dev->iobase + PCI171x_AD_DATA);
795
796 ret = pci171x_ai_dropout(dev, s, s->async->cur_chan, val);
797 if (ret) {
798 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
799 return ret;
800 }
801
802 val &= s->maxdata;
803 comedi_buf_write_samples(s, &val, 1);
804 }
805 return 0;
806} 697}
807 698
808static void pci1710_handle_fifo(struct comedi_device *dev, 699static void pci1710_handle_fifo(struct comedi_device *dev,
809 struct comedi_subdevice *s) 700 struct comedi_subdevice *s)
810{ 701{
811 const struct boardtype *this_board = dev->board_ptr; 702 struct pci1710_private *devpriv = dev->private;
812 struct comedi_cmd *cmd = &s->async->cmd; 703 struct comedi_async *async = s->async;
813 unsigned int nsamples; 704 struct comedi_cmd *cmd = &async->cmd;
814 unsigned int m; 705 unsigned int status;
815 706 int i;
816 m = inw(dev->iobase + PCI171x_STATUS); 707
817 if (!(m & Status_FH)) { 708 status = inw(dev->iobase + PCI171x_STATUS);
818 dev_dbg(dev->class_dev, "A/D FIFO not half full! (%4x)\n", m); 709 if (!(status & Status_FH)) {
819 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 710 dev_dbg(dev->class_dev, "A/D FIFO not half full!\n");
820 comedi_handle_events(dev, s); 711 async->events |= COMEDI_CB_ERROR;
821 return; 712 return;
822 } 713 }
823 if (m & Status_FF) { 714 if (status & Status_FF) {
824 dev_dbg(dev->class_dev, 715 dev_dbg(dev->class_dev,
825 "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); 716 "A/D FIFO Full status (Fatal Error!)\n");
826 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 717 async->events |= COMEDI_CB_ERROR;
827 comedi_handle_events(dev, s);
828 return; 718 return;
829 } 719 }
830 720
831 nsamples = this_board->fifo_half_size; 721 for (i = 0; i < devpriv->max_samples; i++) {
832 if (comedi_samples_to_bytes(s, nsamples) >= s->async->prealloc_bufsz) { 722 unsigned int val;
833 m = comedi_bytes_to_samples(s, s->async->prealloc_bufsz); 723 int ret;
834 if (move_block_from_fifo(dev, s, m, 0))
835 return;
836 nsamples -= m;
837 }
838 724
839 if (nsamples) { 725 ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val);
840 if (move_block_from_fifo(dev, s, nsamples, 1)) 726 if (ret) {
841 return; 727 s->async->events |= COMEDI_CB_ERROR;
842 } 728 break;
729 }
843 730
844 if (cmd->stop_src == TRIG_COUNT && 731 if (!comedi_buf_write_samples(s, &val, 1))
845 s->async->scans_done >= cmd->stop_arg) { 732 break;
846 s->async->events |= COMEDI_CB_EOA; 733
847 comedi_handle_events(dev, s); 734 if (cmd->stop_src == TRIG_COUNT &&
848 return; 735 async->scans_done >= cmd->stop_arg) {
736 async->events |= COMEDI_CB_EOA;
737 break;
738 }
849 } 739 }
850 outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */
851 740
852 comedi_handle_events(dev, s); 741 outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */
853} 742}
854 743
855/*
856==============================================================================
857*/
858static irqreturn_t interrupt_service_pci1710(int irq, void *d) 744static irqreturn_t interrupt_service_pci1710(int irq, void *d)
859{ 745{
860 struct comedi_device *dev = d; 746 struct comedi_device *dev = d;
@@ -891,6 +777,8 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
891 else 777 else
892 pci1710_handle_fifo(dev, s); 778 pci1710_handle_fifo(dev, s);
893 779
780 comedi_handle_events(dev, s);
781
894 return IRQ_HANDLED; 782 return IRQ_HANDLED;
895} 783}
896 784
@@ -901,8 +789,8 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
901 789
902 pci171x_start_pacer(dev, false); 790 pci171x_start_pacer(dev, false);
903 791
904 setup_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len, 792 pci171x_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len,
905 devpriv->saved_seglen); 793 devpriv->saved_seglen);
906 794
907 outb(0, dev->iobase + PCI171x_CLRFIFO); 795 outb(0, dev->iobase + PCI171x_CLRFIFO);
908 outb(0, dev->iobase + PCI171x_CLRINT); 796 outb(0, dev->iobase + PCI171x_CLRINT);
@@ -937,14 +825,10 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
937 return 0; 825 return 0;
938} 826}
939 827
940/*
941==============================================================================
942*/
943static int pci171x_ai_cmdtest(struct comedi_device *dev, 828static int pci171x_ai_cmdtest(struct comedi_device *dev,
944 struct comedi_subdevice *s, 829 struct comedi_subdevice *s,
945 struct comedi_cmd *cmd) 830 struct comedi_cmd *cmd)
946{ 831{
947 const struct boardtype *this_board = dev->board_ptr;
948 struct pci1710_private *devpriv = dev->private; 832 struct pci1710_private *devpriv = dev->private;
949 int err = 0; 833 int err = 0;
950 unsigned int arg; 834 unsigned int arg;
@@ -977,8 +861,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
977 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 861 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
978 862
979 if (cmd->convert_src == TRIG_TIMER) 863 if (cmd->convert_src == TRIG_TIMER)
980 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 864 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000);
981 this_board->ai_ns_min);
982 else /* TRIG_FOLLOW */ 865 else /* TRIG_FOLLOW */
983 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); 866 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
984 867
@@ -1016,12 +899,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
1016 return 0; 899 return 0;
1017} 900}
1018 901
1019/*
1020==============================================================================
1021*/
1022static int pci171x_reset(struct comedi_device *dev) 902static int pci171x_reset(struct comedi_device *dev)
1023{ 903{
1024 const struct boardtype *this_board = dev->board_ptr; 904 const struct boardtype *board = dev->board_ptr;
1025 struct pci1710_private *devpriv = dev->private; 905 struct pci1710_private *devpriv = dev->private;
1026 906
1027 outw(0x30, dev->iobase + PCI171x_CNTCTRL); 907 outw(0x30, dev->iobase + PCI171x_CNTCTRL);
@@ -1033,15 +913,11 @@ static int pci171x_reset(struct comedi_device *dev)
1033 outb(0, dev->iobase + PCI171x_CLRINT); /* clear INT request */ 913 outb(0, dev->iobase + PCI171x_CLRINT); /* clear INT request */
1034 pci171x_start_pacer(dev, false); 914 pci171x_start_pacer(dev, false);
1035 devpriv->da_ranges = 0; 915 devpriv->da_ranges = 0;
1036 if (this_board->n_aochan) { 916 if (board->has_ao) {
1037 /* set DACs to 0..5V */ 917 /* set DACs to 0..5V */
1038 outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); 918 outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
1039 outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */ 919 outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */
1040 devpriv->ao_data[0] = 0x0000; 920 outw(0, dev->iobase + PCI171x_DA2);
1041 if (this_board->n_aochan > 1) {
1042 outw(0, dev->iobase + PCI171x_DA2);
1043 devpriv->ao_data[1] = 0x0000;
1044 }
1045 } 921 }
1046 outw(0, dev->iobase + PCI171x_DO); /* digital outputs to 0 */ 922 outw(0, dev->iobase + PCI171x_DO); /* digital outputs to 0 */
1047 outb(0, dev->iobase + PCI171x_CLRFIFO); /* clear FIFO */ 923 outb(0, dev->iobase + PCI171x_CLRFIFO); /* clear FIFO */
@@ -1050,9 +926,6 @@ static int pci171x_reset(struct comedi_device *dev)
1050 return 0; 926 return 0;
1051} 927}
1052 928
1053/*
1054==============================================================================
1055*/
1056static int pci1720_reset(struct comedi_device *dev) 929static int pci1720_reset(struct comedi_device *dev)
1057{ 930{
1058 struct pci1710_private *devpriv = dev->private; 931 struct pci1710_private *devpriv = dev->private;
@@ -1066,43 +939,35 @@ static int pci1720_reset(struct comedi_device *dev)
1066 outw(0x0800, dev->iobase + PCI1720_DA2); 939 outw(0x0800, dev->iobase + PCI1720_DA2);
1067 outw(0x0800, dev->iobase + PCI1720_DA3); 940 outw(0x0800, dev->iobase + PCI1720_DA3);
1068 outb(0, dev->iobase + PCI1720_SYNCOUT); /* update outputs */ 941 outb(0, dev->iobase + PCI1720_SYNCOUT); /* update outputs */
1069 devpriv->ao_data[0] = 0x0800; 942
1070 devpriv->ao_data[1] = 0x0800;
1071 devpriv->ao_data[2] = 0x0800;
1072 devpriv->ao_data[3] = 0x0800;
1073 return 0; 943 return 0;
1074} 944}
1075 945
1076/*
1077==============================================================================
1078*/
1079static int pci1710_reset(struct comedi_device *dev) 946static int pci1710_reset(struct comedi_device *dev)
1080{ 947{
1081 const struct boardtype *this_board = dev->board_ptr; 948 const struct boardtype *board = dev->board_ptr;
1082 949
1083 switch (this_board->cardtype) { 950 if (board->is_pci1720)
1084 case TYPE_PCI1720:
1085 return pci1720_reset(dev); 951 return pci1720_reset(dev);
1086 default: 952
1087 return pci171x_reset(dev); 953 return pci171x_reset(dev);
1088 }
1089} 954}
1090 955
1091static int pci1710_auto_attach(struct comedi_device *dev, 956static int pci1710_auto_attach(struct comedi_device *dev,
1092 unsigned long context) 957 unsigned long context)
1093{ 958{
1094 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 959 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1095 const struct boardtype *this_board = NULL; 960 const struct boardtype *board = NULL;
1096 struct pci1710_private *devpriv; 961 struct pci1710_private *devpriv;
1097 struct comedi_subdevice *s; 962 struct comedi_subdevice *s;
1098 int ret, subdev, n_subdevices; 963 int ret, subdev, n_subdevices;
1099 964
1100 if (context < ARRAY_SIZE(boardtypes)) 965 if (context < ARRAY_SIZE(boardtypes))
1101 this_board = &boardtypes[context]; 966 board = &boardtypes[context];
1102 if (!this_board) 967 if (!board)
1103 return -ENODEV; 968 return -ENODEV;
1104 dev->board_ptr = this_board; 969 dev->board_ptr = board;
1105 dev->board_name = this_board->name; 970 dev->board_name = board->name;
1106 971
1107 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 972 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1108 if (!devpriv) 973 if (!devpriv)
@@ -1114,15 +979,13 @@ static int pci1710_auto_attach(struct comedi_device *dev,
1114 dev->iobase = pci_resource_start(pcidev, 2); 979 dev->iobase = pci_resource_start(pcidev, 2);
1115 980
1116 n_subdevices = 0; 981 n_subdevices = 0;
1117 if (this_board->n_aichan) 982 if (board->n_aichan)
1118 n_subdevices++;
1119 if (this_board->n_aochan)
1120 n_subdevices++;
1121 if (this_board->n_dichan)
1122 n_subdevices++; 983 n_subdevices++;
1123 if (this_board->n_dochan) 984 if (board->has_ao)
1124 n_subdevices++; 985 n_subdevices++;
1125 if (this_board->n_counter) 986 if (board->has_di_do)
987 n_subdevices += 2;
988 if (board->has_counter)
1126 n_subdevices++; 989 n_subdevices++;
1127 990
1128 ret = comedi_alloc_subdevices(dev, n_subdevices); 991 ret = comedi_alloc_subdevices(dev, n_subdevices);
@@ -1131,7 +994,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
1131 994
1132 pci1710_reset(dev); 995 pci1710_reset(dev);
1133 996
1134 if (this_board->have_irq && pcidev->irq) { 997 if (board->has_irq && pcidev->irq) {
1135 ret = request_irq(pcidev->irq, interrupt_service_pci1710, 998 ret = request_irq(pcidev->irq, interrupt_service_pci1710,
1136 IRQF_SHARED, dev->board_name, dev); 999 IRQF_SHARED, dev->board_name, dev);
1137 if (ret == 0) 1000 if (ret == 0)
@@ -1140,85 +1003,93 @@ static int pci1710_auto_attach(struct comedi_device *dev,
1140 1003
1141 subdev = 0; 1004 subdev = 0;
1142 1005
1143 if (this_board->n_aichan) { 1006 if (board->n_aichan) {
1144 s = &dev->subdevices[subdev]; 1007 s = &dev->subdevices[subdev];
1145 s->type = COMEDI_SUBD_AI; 1008 s->type = COMEDI_SUBD_AI;
1146 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; 1009 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
1147 if (this_board->n_aichand) 1010 if (board->has_diff_ai)
1148 s->subdev_flags |= SDF_DIFF; 1011 s->subdev_flags |= SDF_DIFF;
1149 s->n_chan = this_board->n_aichan; 1012 s->n_chan = board->n_aichan;
1150 s->maxdata = this_board->ai_maxdata; 1013 s->maxdata = 0x0fff;
1151 s->range_table = this_board->rangelist_ai; 1014 s->range_table = board->rangelist_ai;
1152 s->insn_read = pci171x_insn_read_ai; 1015 s->insn_read = pci171x_ai_insn_read;
1153 if (dev->irq) { 1016 if (dev->irq) {
1154 dev->read_subdev = s; 1017 dev->read_subdev = s;
1155 s->subdev_flags |= SDF_CMD_READ; 1018 s->subdev_flags |= SDF_CMD_READ;
1156 s->len_chanlist = s->n_chan; 1019 s->len_chanlist = s->n_chan;
1157 s->do_cmdtest = pci171x_ai_cmdtest; 1020 s->do_cmdtest = pci171x_ai_cmdtest;
1158 s->do_cmd = pci171x_ai_cmd; 1021 s->do_cmd = pci171x_ai_cmd;
1159 s->cancel = pci171x_ai_cancel; 1022 s->cancel = pci171x_ai_cancel;
1160 } 1023 }
1161 subdev++; 1024 subdev++;
1162 } 1025 }
1163 1026
1164 if (this_board->n_aochan) { 1027 if (board->has_ao) {
1165 s = &dev->subdevices[subdev]; 1028 s = &dev->subdevices[subdev];
1166 s->type = COMEDI_SUBD_AO; 1029 s->type = COMEDI_SUBD_AO;
1167 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; 1030 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1168 s->n_chan = this_board->n_aochan; 1031 s->maxdata = 0x0fff;
1169 s->maxdata = this_board->ao_maxdata; 1032 if (board->is_pci1720) {
1170 s->len_chanlist = this_board->n_aochan; 1033 s->n_chan = 4;
1171 s->range_table = this_board->rangelist_ao; 1034 s->range_table = &pci1720_ao_range;
1172 switch (this_board->cardtype) { 1035 s->insn_write = pci1720_ao_insn_write;
1173 case TYPE_PCI1720: 1036 } else {
1174 s->insn_write = pci1720_insn_write_ao; 1037 s->n_chan = 2;
1175 break; 1038 s->range_table = &pci171x_ao_range;
1176 default: 1039 s->insn_write = pci171x_ao_insn_write;
1177 s->insn_write = pci171x_insn_write_ao;
1178 break;
1179 } 1040 }
1180 s->insn_read = pci171x_insn_read_ao; 1041
1042 ret = comedi_alloc_subdev_readback(s);
1043 if (ret)
1044 return ret;
1045
1046 /* initialize the readback values to match the board reset */
1047 if (board->is_pci1720) {
1048 int i;
1049
1050 for (i = 0; i < s->n_chan; i++)
1051 s->readback[i] = 0x0800;
1052 }
1053
1181 subdev++; 1054 subdev++;
1182 } 1055 }
1183 1056
1184 if (this_board->n_dichan) { 1057 if (board->has_di_do) {
1185 s = &dev->subdevices[subdev]; 1058 s = &dev->subdevices[subdev];
1186 s->type = COMEDI_SUBD_DI; 1059 s->type = COMEDI_SUBD_DI;
1187 s->subdev_flags = SDF_READABLE; 1060 s->subdev_flags = SDF_READABLE;
1188 s->n_chan = this_board->n_dichan; 1061 s->n_chan = 16;
1189 s->maxdata = 1; 1062 s->maxdata = 1;
1190 s->len_chanlist = this_board->n_dichan; 1063 s->range_table = &range_digital;
1191 s->range_table = &range_digital; 1064 s->insn_bits = pci171x_di_insn_bits;
1192 s->insn_bits = pci171x_insn_bits_di;
1193 subdev++; 1065 subdev++;
1194 }
1195 1066
1196 if (this_board->n_dochan) {
1197 s = &dev->subdevices[subdev]; 1067 s = &dev->subdevices[subdev];
1198 s->type = COMEDI_SUBD_DO; 1068 s->type = COMEDI_SUBD_DO;
1199 s->subdev_flags = SDF_WRITABLE; 1069 s->subdev_flags = SDF_WRITABLE;
1200 s->n_chan = this_board->n_dochan; 1070 s->n_chan = 16;
1201 s->maxdata = 1; 1071 s->maxdata = 1;
1202 s->len_chanlist = this_board->n_dochan; 1072 s->range_table = &range_digital;
1203 s->range_table = &range_digital; 1073 s->insn_bits = pci171x_do_insn_bits;
1204 s->insn_bits = pci171x_insn_bits_do;
1205 subdev++; 1074 subdev++;
1206 } 1075 }
1207 1076
1208 if (this_board->n_counter) { 1077 if (board->has_counter) {
1209 s = &dev->subdevices[subdev]; 1078 s = &dev->subdevices[subdev];
1210 s->type = COMEDI_SUBD_COUNTER; 1079 s->type = COMEDI_SUBD_COUNTER;
1211 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1080 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1212 s->n_chan = this_board->n_counter; 1081 s->n_chan = 1;
1213 s->len_chanlist = this_board->n_counter; 1082 s->maxdata = 0xffff;
1214 s->maxdata = 0xffff; 1083 s->range_table = &range_unknown;
1215 s->range_table = &range_unknown; 1084 s->insn_read = pci171x_counter_insn_read;
1216 s->insn_read = pci171x_insn_counter_read; 1085 s->insn_write = pci171x_counter_insn_write;
1217 s->insn_write = pci171x_insn_counter_write; 1086 s->insn_config = pci171x_counter_insn_config;
1218 s->insn_config = pci171x_insn_counter_config;
1219 subdev++; 1087 subdev++;
1220 } 1088 }
1221 1089
1090 /* max_samples is half the FIFO size (2 bytes/sample) */
1091 devpriv->max_samples = (board->has_large_fifo) ? 2048 : 512;
1092
1222 return 0; 1093 return 0;
1223} 1094}
1224 1095
@@ -1312,5 +1183,5 @@ static struct pci_driver adv_pci1710_pci_driver = {
1312module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver); 1183module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver);
1313 1184
1314MODULE_AUTHOR("Comedi http://www.comedi.org"); 1185MODULE_AUTHOR("Comedi http://www.comedi.org");
1315MODULE_DESCRIPTION("Comedi low-level driver"); 1186MODULE_DESCRIPTION("Comedi: Advantech PCI-1710 Series Multifunction DAS Cards");
1316MODULE_LICENSE("GPL"); 1187MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index 65f854e1eb66..f1945be89eff 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -20,7 +20,7 @@
20 * Driver: adv_pci1723 20 * Driver: adv_pci1723
21 * Description: Advantech PCI-1723 21 * Description: Advantech PCI-1723
22 * Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk> 22 * Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk>
23 * Devices: (Advantech) PCI-1723 [adv_pci1723] 23 * Devices: [Advantech] PCI-1723 (adv_pci1723)
24 * Updated: Mon, 14 Apr 2008 15:12:56 +0100 24 * Updated: Mon, 14 Apr 2008 15:12:56 +0100
25 * Status: works 25 * Status: works
26 * 26 *
diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c
index a8d28403262e..a3573ea6f9c0 100644
--- a/drivers/staging/comedi/drivers/adv_pci1724.c
+++ b/drivers/staging/comedi/drivers/adv_pci1724.c
@@ -22,7 +22,7 @@
22/* 22/*
23 * Driver: adv_pci1724 23 * Driver: adv_pci1724
24 * Description: Advantech PCI-1724U 24 * Description: Advantech PCI-1724U
25 * Devices: (Advantech) PCI-1724U [adv_pci1724] 25 * Devices: [Advantech] PCI-1724U (adv_pci1724)
26 * Author: Frank Mori Hess <fmh6jj@gmail.com> 26 * Author: Frank Mori Hess <fmh6jj@gmail.com>
27 * Updated: 2013-02-09 27 * Updated: 2013-02-09
28 * Status: works 28 * Status: works
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 7b5ed439c164..1c7b325a373c 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -1,48 +1,155 @@
1/* 1/*
2 * aio_iiro_16.c
3 * Comedi driver for Access I/O Products 104-IIRO-16 board
4 * Copyright (C) 2006 C&C Technologies, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
2 16
3 comedi/drivers/aio_iiro_16.c 17/*
18 * Driver: aio_iiro_16
19 * Description: Access I/O Products PC/104 Isolated Input/Relay Output Board
20 * Author: Zachary Ware <zach.ware@cctechnol.com>
21 * Devices: [Access I/O] 104-IIRO-16 (aio_iiro_16)
22 * Status: experimental
23 *
24 * Configuration Options:
25 * [0] - I/O port base address
26 * [1] - IRQ (optional)
27 *
28 * The board supports interrupts on change of state of the digital inputs.
29 * The sample data returned by the async command indicates which inputs
30 * changed state and the current state of the inputs:
31 *
32 * Bit 23 - IRQ Enable (1) / Disable (0)
33 * Bit 17 - Input 8-15 Changed State (1 = Changed, 0 = No Change)
34 * Bit 16 - Input 0-7 Changed State (1 = Changed, 0 = No Change)
35 * Bit 15 - Digital input 15
36 * ...
37 * Bit 0 - Digital input 0
38 */
4 39
5 Driver for Access I/O Products PC-104 AIO-IIRO-16 Digital I/O board 40#include <linux/module.h>
6 Copyright (C) 2006 C&C Technologies, Inc. 41#include <linux/interrupt.h>
7 42
8 This program is free software; you can redistribute it and/or modify 43#include "../comedidev.h"
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 44
13 This program is distributed in the hope that it will be useful, 45#include "comedi_fc.h"
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17*/
18 46
19/* 47#define AIO_IIRO_16_RELAY_0_7 0x00
48#define AIO_IIRO_16_INPUT_0_7 0x01
49#define AIO_IIRO_16_IRQ 0x02
50#define AIO_IIRO_16_RELAY_8_15 0x04
51#define AIO_IIRO_16_INPUT_8_15 0x05
52#define AIO_IIRO_16_STATUS 0x07
53#define AIO_IIRO_16_STATUS_IRQE BIT(7)
54#define AIO_IIRO_16_STATUS_INPUT_8_15 BIT(1)
55#define AIO_IIRO_16_STATUS_INPUT_0_7 BIT(0)
20 56
21Driver: aio_iiro_16 57static unsigned int aio_iiro_16_read_inputs(struct comedi_device *dev)
22Description: Access I/O Products PC-104 IIRO16 Relay And Isolated Input Board 58{
23Author: Zachary Ware <zach.ware@cctechnol.com> 59 unsigned int val;
24Devices:
25 [Access I/O] PC-104 AIO12-8
26Status: experimental
27 60
28Configuration Options: 61 val = inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
29 [0] - I/O port base address 62 val |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
30 63
31*/ 64 return val;
65}
32 66
33#include <linux/module.h> 67static irqreturn_t aio_iiro_16_cos(int irq, void *d)
34#include "../comedidev.h" 68{
69 struct comedi_device *dev = d;
70 struct comedi_subdevice *s = dev->read_subdev;
71 unsigned int status;
72 unsigned int val;
73
74 status = inb(dev->iobase + AIO_IIRO_16_STATUS);
75 if (!(status & AIO_IIRO_16_STATUS_IRQE))
76 return IRQ_NONE;
77
78 val = aio_iiro_16_read_inputs(dev);
79 val |= (status << 16);
80
81 comedi_buf_write_samples(s, &val, 1);
82 comedi_handle_events(dev, s);
83
84 return IRQ_HANDLED;
85}
86
87static void aio_iiro_enable_irq(struct comedi_device *dev, bool enable)
88{
89 if (enable)
90 inb(dev->iobase + AIO_IIRO_16_IRQ);
91 else
92 outb(0, dev->iobase + AIO_IIRO_16_IRQ);
93}
94
95static int aio_iiro_16_cos_cancel(struct comedi_device *dev,
96 struct comedi_subdevice *s)
97{
98 aio_iiro_enable_irq(dev, false);
99
100 return 0;
101}
35 102
36#define AIO_IIRO_16_RELAY_0_7 0x00 103static int aio_iiro_16_cos_cmd(struct comedi_device *dev,
37#define AIO_IIRO_16_INPUT_0_7 0x01 104 struct comedi_subdevice *s)
38#define AIO_IIRO_16_IRQ 0x02 105{
39#define AIO_IIRO_16_RELAY_8_15 0x04 106 aio_iiro_enable_irq(dev, true);
40#define AIO_IIRO_16_INPUT_8_15 0x05 107
108 return 0;
109}
110
111static int aio_iiro_16_cos_cmdtest(struct comedi_device *dev,
112 struct comedi_subdevice *s,
113 struct comedi_cmd *cmd)
114{
115 int err = 0;
116
117 /* Step 1 : check if triggers are trivially valid */
118
119 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
120 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
121 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
122 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
123 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
124
125 if (err)
126 return 1;
127
128 /* Step 2a : make sure trigger sources are unique */
129 /* Step 2b : and mutually compatible */
130
131 /* Step 3: check if arguments are trivially valid */
41 132
42static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, 133 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
43 struct comedi_subdevice *s, 134 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
44 struct comedi_insn *insn, 135 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
45 unsigned int *data) 136 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
137 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
138
139 if (err)
140 return 3;
141
142 /* Step 4: fix up any arguments */
143
144 /* Step 5: check channel list if it exists */
145
146 return 0;
147}
148
149static int aio_iiro_16_do_insn_bits(struct comedi_device *dev,
150 struct comedi_subdevice *s,
151 struct comedi_insn *insn,
152 unsigned int *data)
46{ 153{
47 if (comedi_dio_update_state(s, data)) { 154 if (comedi_dio_update_state(s, data)) {
48 outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7); 155 outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
@@ -55,14 +162,12 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
55 return insn->n; 162 return insn->n;
56} 163}
57 164
58static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, 165static int aio_iiro_16_di_insn_bits(struct comedi_device *dev,
59 struct comedi_subdevice *s, 166 struct comedi_subdevice *s,
60 struct comedi_insn *insn, 167 struct comedi_insn *insn,
61 unsigned int *data) 168 unsigned int *data)
62{ 169{
63 data[1] = 0; 170 data[1] = aio_iiro_16_read_inputs(dev);
64 data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
65 data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
66 171
67 return insn->n; 172 return insn->n;
68} 173}
@@ -77,25 +182,52 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
77 if (ret) 182 if (ret)
78 return ret; 183 return ret;
79 184
185 aio_iiro_enable_irq(dev, false);
186
187 /*
188 * Digital input change of state interrupts are optionally supported
189 * using IRQ 2-7, 10-12, 14, or 15.
190 */
191 if ((1 << it->options[1]) & 0xdcfc) {
192 ret = request_irq(it->options[1], aio_iiro_16_cos, 0,
193 dev->board_name, dev);
194 if (ret == 0)
195 dev->irq = it->options[1];
196 }
197
80 ret = comedi_alloc_subdevices(dev, 2); 198 ret = comedi_alloc_subdevices(dev, 2);
81 if (ret) 199 if (ret)
82 return ret; 200 return ret;
83 201
202 /* Digital Output subdevice */
84 s = &dev->subdevices[0]; 203 s = &dev->subdevices[0];
85 s->type = COMEDI_SUBD_DIO; 204 s->type = COMEDI_SUBD_DO;
86 s->subdev_flags = SDF_WRITABLE; 205 s->subdev_flags = SDF_WRITABLE;
87 s->n_chan = 16; 206 s->n_chan = 16;
88 s->maxdata = 1; 207 s->maxdata = 1;
89 s->range_table = &range_digital; 208 s->range_table = &range_digital;
90 s->insn_bits = aio_iiro_16_dio_insn_bits_write; 209 s->insn_bits = aio_iiro_16_do_insn_bits;
91 210
211 /* get the initial state of the relays */
212 s->state = inb(dev->iobase + AIO_IIRO_16_RELAY_0_7) |
213 (inb(dev->iobase + AIO_IIRO_16_RELAY_8_15) << 8);
214
215 /* Digital Input subdevice */
92 s = &dev->subdevices[1]; 216 s = &dev->subdevices[1];
93 s->type = COMEDI_SUBD_DIO; 217 s->type = COMEDI_SUBD_DI;
94 s->subdev_flags = SDF_READABLE; 218 s->subdev_flags = SDF_READABLE;
95 s->n_chan = 16; 219 s->n_chan = 16;
96 s->maxdata = 1; 220 s->maxdata = 1;
97 s->range_table = &range_digital; 221 s->range_table = &range_digital;
98 s->insn_bits = aio_iiro_16_dio_insn_bits_read; 222 s->insn_bits = aio_iiro_16_di_insn_bits;
223 if (dev->irq) {
224 dev->read_subdev = s;
225 s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL;
226 s->len_chanlist = 1;
227 s->do_cmdtest = aio_iiro_16_cos_cmdtest;
228 s->do_cmd = aio_iiro_16_cos_cmd;
229 s->cancel = aio_iiro_16_cos_cancel;
230 }
99 231
100 return 0; 232 return 0;
101} 233}
@@ -109,5 +241,5 @@ static struct comedi_driver aio_iiro_16_driver = {
109module_comedi_driver(aio_iiro_16_driver); 241module_comedi_driver(aio_iiro_16_driver);
110 242
111MODULE_AUTHOR("Comedi http://www.comedi.org"); 243MODULE_AUTHOR("Comedi http://www.comedi.org");
112MODULE_DESCRIPTION("Comedi low-level driver"); 244MODULE_DESCRIPTION("Comedi driver for Access I/O Products 104-IIRO-16 board");
113MODULE_LICENSE("GPL"); 245MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
index e7cb7032a910..1a109e30d8ff 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -22,7 +22,7 @@
22 * Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card 22 * Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card
23 * Author: Dan Block 23 * Author: Dan Block
24 * Status: unknown 24 * Status: unknown
25 * Devices: (Mechatronic Systems Inc.) C6x_DIGIO DSP daughter card [c6xdigio] 25 * Devices: [Mechatronic Systems Inc.] C6x_DIGIO DSP daughter card (c6xdigio)
26 * Updated: Sun Nov 20 20:18:34 EST 2005 26 * Updated: Sun Nov 20 20:18:34 EST 2005
27 * 27 *
28 * Configuration Options: 28 * Configuration Options:
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 0a48d2a961d5..1079b6c72b15 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -38,10 +38,7 @@ Status: experimental
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/delay.h> 39#include <linux/delay.h>
40 40
41#include "../comedidev.h" 41#include "../comedi_pcmcia.h"
42
43#include <pcmcia/cistpl.h>
44#include <pcmcia/ds.h>
45 42
46#include "comedi_fc.h" 43#include "comedi_fc.h"
47#include "8253.h" 44#include "8253.h"
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 669b1703eb99..dd0c65a5b5a0 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -1355,7 +1355,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1355 outw(devpriv->adc_fifo_bits | LADFUL, 1355 outw(devpriv->adc_fifo_bits | LADFUL,
1356 devpriv->control_status + INT_ADCFIFO); 1356 devpriv->control_status + INT_ADCFIFO);
1357 spin_unlock_irqrestore(&dev->spinlock, flags); 1357 spin_unlock_irqrestore(&dev->spinlock, flags);
1358 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 1358 async->events |= COMEDI_CB_ERROR;
1359 } 1359 }
1360 1360
1361 comedi_handle_events(dev, s); 1361 comedi_handle_events(dev, s);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index eddb7ace43df..5b43e4e6d037 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -439,6 +439,29 @@ static const struct comedi_lrange ai_ranges_64xx = {
439 } 439 }
440}; 440};
441 441
442static const uint8_t ai_range_code_64xx[8] = {
443 0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */
444 0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */
445};
446
447/* analog input ranges for 64-Mx boards */
448static const struct comedi_lrange ai_ranges_64_mx = {
449 7, {
450 BIP_RANGE(5),
451 BIP_RANGE(2.5),
452 BIP_RANGE(1.25),
453 BIP_RANGE(0.625),
454 UNI_RANGE(5),
455 UNI_RANGE(2.5),
456 UNI_RANGE(1.25)
457 }
458};
459
460static const uint8_t ai_range_code_64_mx[7] = {
461 0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */
462 0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */
463};
464
442/* analog input ranges for 60xx boards */ 465/* analog input ranges for 60xx boards */
443static const struct comedi_lrange ai_ranges_60xx = { 466static const struct comedi_lrange ai_ranges_60xx = {
444 4, { 467 4, {
@@ -449,6 +472,10 @@ static const struct comedi_lrange ai_ranges_60xx = {
449 } 472 }
450}; 473};
451 474
475static const uint8_t ai_range_code_60xx[4] = {
476 0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */
477};
478
452/* analog input ranges for 6030, etc boards */ 479/* analog input ranges for 6030, etc boards */
453static const struct comedi_lrange ai_ranges_6030 = { 480static const struct comedi_lrange ai_ranges_6030 = {
454 14, { 481 14, {
@@ -469,6 +496,11 @@ static const struct comedi_lrange ai_ranges_6030 = {
469 } 496 }
470}; 497};
471 498
499static const uint8_t ai_range_code_6030[14] = {
500 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */
501 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */
502};
503
472/* analog input ranges for 6052, etc boards */ 504/* analog input ranges for 6052, etc boards */
473static const struct comedi_lrange ai_ranges_6052 = { 505static const struct comedi_lrange ai_ranges_6052 = {
474 15, { 506 15, {
@@ -490,6 +522,11 @@ static const struct comedi_lrange ai_ranges_6052 = {
490 } 522 }
491}; 523};
492 524
525static const uint8_t ai_range_code_6052[15] = {
526 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */
527 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */
528};
529
493/* analog input ranges for 4020 board */ 530/* analog input ranges for 4020 board */
494static const struct comedi_lrange ai_ranges_4020 = { 531static const struct comedi_lrange ai_ranges_4020 = {
495 2, { 532 2, {
@@ -593,6 +630,7 @@ struct pcidas64_board {
593 int ai_bits; /* analog input resolution */ 630 int ai_bits; /* analog input resolution */
594 int ai_speed; /* fastest conversion period in ns */ 631 int ai_speed; /* fastest conversion period in ns */
595 const struct comedi_lrange *ai_range_table; 632 const struct comedi_lrange *ai_range_table;
633 const uint8_t *ai_range_code;
596 int ao_nchan; /* number of analog out channels */ 634 int ao_nchan; /* number of analog out channels */
597 int ao_bits; /* analog output resolution */ 635 int ao_bits; /* analog output resolution */
598 int ao_scan_speed; /* analog output scan speed */ 636 int ao_scan_speed; /* analog output scan speed */
@@ -651,6 +689,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
651 .ao_scan_speed = 10000, 689 .ao_scan_speed = 10000,
652 .layout = LAYOUT_64XX, 690 .layout = LAYOUT_64XX,
653 .ai_range_table = &ai_ranges_64xx, 691 .ai_range_table = &ai_ranges_64xx,
692 .ai_range_code = ai_range_code_64xx,
654 .ao_range_table = &ao_ranges_64xx, 693 .ao_range_table = &ao_ranges_64xx,
655 .ao_range_code = ao_range_code_64xx, 694 .ao_range_code = ao_range_code_64xx,
656 .ai_fifo = &ai_fifo_64xx, 695 .ai_fifo = &ai_fifo_64xx,
@@ -666,6 +705,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
666 .ao_scan_speed = 10000, 705 .ao_scan_speed = 10000,
667 .layout = LAYOUT_64XX, 706 .layout = LAYOUT_64XX,
668 .ai_range_table = &ai_ranges_64xx, 707 .ai_range_table = &ai_ranges_64xx,
708 .ai_range_code = ai_range_code_64xx,
669 .ao_range_table = &ao_ranges_64xx, 709 .ao_range_table = &ao_ranges_64xx,
670 .ao_range_code = ao_range_code_64xx, 710 .ao_range_code = ao_range_code_64xx,
671 .ai_fifo = &ai_fifo_64xx, 711 .ai_fifo = &ai_fifo_64xx,
@@ -680,7 +720,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
680 .ao_bits = 16, 720 .ao_bits = 16,
681 .ao_scan_speed = 10000, 721 .ao_scan_speed = 10000,
682 .layout = LAYOUT_64XX, 722 .layout = LAYOUT_64XX,
683 .ai_range_table = &ai_ranges_64xx, 723 .ai_range_table = &ai_ranges_64_mx,
724 .ai_range_code = ai_range_code_64_mx,
684 .ao_range_table = &ao_ranges_64xx, 725 .ao_range_table = &ao_ranges_64xx,
685 .ao_range_code = ao_range_code_64xx, 726 .ao_range_code = ao_range_code_64xx,
686 .ai_fifo = &ai_fifo_64xx, 727 .ai_fifo = &ai_fifo_64xx,
@@ -695,7 +736,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
695 .ao_bits = 16, 736 .ao_bits = 16,
696 .ao_scan_speed = 10000, 737 .ao_scan_speed = 10000,
697 .layout = LAYOUT_64XX, 738 .layout = LAYOUT_64XX,
698 .ai_range_table = &ai_ranges_64xx, 739 .ai_range_table = &ai_ranges_64_mx,
740 .ai_range_code = ai_range_code_64_mx,
699 .ao_range_table = &ao_ranges_64xx, 741 .ao_range_table = &ao_ranges_64xx,
700 .ao_range_code = ao_range_code_64xx, 742 .ao_range_code = ao_range_code_64xx,
701 .ai_fifo = &ai_fifo_64xx, 743 .ai_fifo = &ai_fifo_64xx,
@@ -710,7 +752,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
710 .ao_bits = 16, 752 .ao_bits = 16,
711 .ao_scan_speed = 10000, 753 .ao_scan_speed = 10000,
712 .layout = LAYOUT_64XX, 754 .layout = LAYOUT_64XX,
713 .ai_range_table = &ai_ranges_64xx, 755 .ai_range_table = &ai_ranges_64_mx,
756 .ai_range_code = ai_range_code_64_mx,
714 .ao_range_table = &ao_ranges_64xx, 757 .ao_range_table = &ao_ranges_64xx,
715 .ao_range_code = ao_range_code_64xx, 758 .ao_range_code = ao_range_code_64xx,
716 .ai_fifo = &ai_fifo_64xx, 759 .ai_fifo = &ai_fifo_64xx,
@@ -725,6 +768,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
725 .ao_bits = 16, 768 .ao_bits = 16,
726 .layout = LAYOUT_60XX, 769 .layout = LAYOUT_60XX,
727 .ai_range_table = &ai_ranges_60xx, 770 .ai_range_table = &ai_ranges_60xx,
771 .ai_range_code = ai_range_code_60xx,
728 .ao_range_table = &range_bipolar10, 772 .ao_range_table = &range_bipolar10,
729 .ao_range_code = ao_range_code_60xx, 773 .ao_range_code = ao_range_code_60xx,
730 .ai_fifo = &ai_fifo_60xx, 774 .ai_fifo = &ai_fifo_60xx,
@@ -740,6 +784,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
740 .ao_scan_speed = 100000, 784 .ao_scan_speed = 100000,
741 .layout = LAYOUT_60XX, 785 .layout = LAYOUT_60XX,
742 .ai_range_table = &ai_ranges_60xx, 786 .ai_range_table = &ai_ranges_60xx,
787 .ai_range_code = ai_range_code_60xx,
743 .ao_range_table = &range_bipolar10, 788 .ao_range_table = &range_bipolar10,
744 .ao_range_code = ao_range_code_60xx, 789 .ao_range_code = ao_range_code_60xx,
745 .ai_fifo = &ai_fifo_60xx, 790 .ai_fifo = &ai_fifo_60xx,
@@ -754,6 +799,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
754 .ao_scan_speed = 100000, 799 .ao_scan_speed = 100000,
755 .layout = LAYOUT_60XX, 800 .layout = LAYOUT_60XX,
756 .ai_range_table = &ai_ranges_60xx, 801 .ai_range_table = &ai_ranges_60xx,
802 .ai_range_code = ai_range_code_60xx,
757 .ao_range_table = &range_bipolar10, 803 .ao_range_table = &range_bipolar10,
758 .ao_range_code = ao_range_code_60xx, 804 .ao_range_code = ao_range_code_60xx,
759 .ai_fifo = &ai_fifo_60xx, 805 .ai_fifo = &ai_fifo_60xx,
@@ -769,6 +815,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
769 .ao_scan_speed = 100000, 815 .ao_scan_speed = 100000,
770 .layout = LAYOUT_60XX, 816 .layout = LAYOUT_60XX,
771 .ai_range_table = &ai_ranges_60xx, 817 .ai_range_table = &ai_ranges_60xx,
818 .ai_range_code = ai_range_code_60xx,
772 .ao_range_table = &range_bipolar10, 819 .ao_range_table = &range_bipolar10,
773 .ao_range_code = ao_range_code_60xx, 820 .ao_range_code = ao_range_code_60xx,
774 .ai_fifo = &ai_fifo_60xx, 821 .ai_fifo = &ai_fifo_60xx,
@@ -784,6 +831,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
784 .ao_scan_speed = 10000, 831 .ao_scan_speed = 10000,
785 .layout = LAYOUT_60XX, 832 .layout = LAYOUT_60XX,
786 .ai_range_table = &ai_ranges_6030, 833 .ai_range_table = &ai_ranges_6030,
834 .ai_range_code = ai_range_code_6030,
787 .ao_range_table = &ao_ranges_6030, 835 .ao_range_table = &ao_ranges_6030,
788 .ao_range_code = ao_range_code_6030, 836 .ao_range_code = ao_range_code_6030,
789 .ai_fifo = &ai_fifo_60xx, 837 .ai_fifo = &ai_fifo_60xx,
@@ -799,6 +847,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
799 .ao_scan_speed = 10000, 847 .ao_scan_speed = 10000,
800 .layout = LAYOUT_60XX, 848 .layout = LAYOUT_60XX,
801 .ai_range_table = &ai_ranges_6030, 849 .ai_range_table = &ai_ranges_6030,
850 .ai_range_code = ai_range_code_6030,
802 .ao_range_table = &ao_ranges_6030, 851 .ao_range_table = &ao_ranges_6030,
803 .ao_range_code = ao_range_code_6030, 852 .ao_range_code = ao_range_code_6030,
804 .ai_fifo = &ai_fifo_60xx, 853 .ai_fifo = &ai_fifo_60xx,
@@ -812,6 +861,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
812 .ao_nchan = 0, 861 .ao_nchan = 0,
813 .layout = LAYOUT_60XX, 862 .layout = LAYOUT_60XX,
814 .ai_range_table = &ai_ranges_6030, 863 .ai_range_table = &ai_ranges_6030,
864 .ai_range_code = ai_range_code_6030,
815 .ai_fifo = &ai_fifo_60xx, 865 .ai_fifo = &ai_fifo_60xx,
816 .has_8255 = 0, 866 .has_8255 = 0,
817 }, 867 },
@@ -823,6 +873,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
823 .ao_nchan = 0, 873 .ao_nchan = 0,
824 .layout = LAYOUT_60XX, 874 .layout = LAYOUT_60XX,
825 .ai_range_table = &ai_ranges_6030, 875 .ai_range_table = &ai_ranges_6030,
876 .ai_range_code = ai_range_code_6030,
826 .ai_fifo = &ai_fifo_60xx, 877 .ai_fifo = &ai_fifo_60xx,
827 .has_8255 = 0, 878 .has_8255 = 0,
828 }, 879 },
@@ -835,6 +886,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
835 .ao_scan_speed = 0, 886 .ao_scan_speed = 0,
836 .layout = LAYOUT_60XX, 887 .layout = LAYOUT_60XX,
837 .ai_range_table = &ai_ranges_60xx, 888 .ai_range_table = &ai_ranges_60xx,
889 .ai_range_code = ai_range_code_60xx,
838 .ai_fifo = &ai_fifo_60xx, 890 .ai_fifo = &ai_fifo_60xx,
839 .has_8255 = 0, 891 .has_8255 = 0,
840 }, 892 },
@@ -848,6 +900,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
848 .ao_scan_speed = 100000, 900 .ao_scan_speed = 100000,
849 .layout = LAYOUT_60XX, 901 .layout = LAYOUT_60XX,
850 .ai_range_table = &ai_ranges_60xx, 902 .ai_range_table = &ai_ranges_60xx,
903 .ai_range_code = ai_range_code_60xx,
851 .ao_range_table = &range_bipolar10, 904 .ao_range_table = &range_bipolar10,
852 .ao_range_code = ao_range_code_60xx, 905 .ao_range_code = ao_range_code_60xx,
853 .ai_fifo = &ai_fifo_60xx, 906 .ai_fifo = &ai_fifo_60xx,
@@ -863,6 +916,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
863 .ao_scan_speed = 100000, 916 .ao_scan_speed = 100000,
864 .layout = LAYOUT_60XX, 917 .layout = LAYOUT_60XX,
865 .ai_range_table = &ai_ranges_60xx, 918 .ai_range_table = &ai_ranges_60xx,
919 .ai_range_code = ai_range_code_60xx,
866 .ao_range_table = &range_bipolar10, 920 .ao_range_table = &range_bipolar10,
867 .ao_range_code = ao_range_code_60xx, 921 .ao_range_code = ao_range_code_60xx,
868 .ai_fifo = &ai_fifo_60xx, 922 .ai_fifo = &ai_fifo_60xx,
@@ -878,6 +932,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
878 .ao_scan_speed = 1000, 932 .ao_scan_speed = 1000,
879 .layout = LAYOUT_60XX, 933 .layout = LAYOUT_60XX,
880 .ai_range_table = &ai_ranges_6052, 934 .ai_range_table = &ai_ranges_6052,
935 .ai_range_code = ai_range_code_6052,
881 .ao_range_table = &ao_ranges_6030, 936 .ao_range_table = &ao_ranges_6030,
882 .ao_range_code = ao_range_code_6030, 937 .ao_range_code = ao_range_code_6030,
883 .ai_fifo = &ai_fifo_60xx, 938 .ai_fifo = &ai_fifo_60xx,
@@ -893,6 +948,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
893 .ao_scan_speed = 3333, 948 .ao_scan_speed = 3333,
894 .layout = LAYOUT_60XX, 949 .layout = LAYOUT_60XX,
895 .ai_range_table = &ai_ranges_6052, 950 .ai_range_table = &ai_ranges_6052,
951 .ai_range_code = ai_range_code_6052,
896 .ao_range_table = &ao_ranges_6030, 952 .ao_range_table = &ao_ranges_6030,
897 .ao_range_code = ao_range_code_6030, 953 .ao_range_code = ao_range_code_6030,
898 .ai_fifo = &ai_fifo_60xx, 954 .ai_fifo = &ai_fifo_60xx,
@@ -908,6 +964,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
908 .ao_scan_speed = 1000, 964 .ao_scan_speed = 1000,
909 .layout = LAYOUT_60XX, 965 .layout = LAYOUT_60XX,
910 .ai_range_table = &ai_ranges_6052, 966 .ai_range_table = &ai_ranges_6052,
967 .ai_range_code = ai_range_code_6052,
911 .ao_range_table = &ao_ranges_6030, 968 .ao_range_table = &ao_ranges_6030,
912 .ao_range_code = ao_range_code_6030, 969 .ao_range_code = ao_range_code_6030,
913 .ai_fifo = &ai_fifo_60xx, 970 .ai_fifo = &ai_fifo_60xx,
@@ -923,6 +980,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
923 .ao_scan_speed = 1000, 980 .ao_scan_speed = 1000,
924 .layout = LAYOUT_60XX, 981 .layout = LAYOUT_60XX,
925 .ai_range_table = &ai_ranges_6052, 982 .ai_range_table = &ai_ranges_6052,
983 .ai_range_code = ai_range_code_6052,
926 .ao_range_table = &ao_ranges_6030, 984 .ao_range_table = &ao_ranges_6030,
927 .ao_range_code = ao_range_code_6030, 985 .ao_range_code = ao_range_code_6030,
928 .ai_fifo = &ai_fifo_60xx, 986 .ai_fifo = &ai_fifo_60xx,
@@ -957,6 +1015,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
957 .ao_scan_speed = 10000, 1015 .ao_scan_speed = 10000,
958 .layout = LAYOUT_64XX, 1016 .layout = LAYOUT_64XX,
959 .ai_range_table = &ai_ranges_64xx, 1017 .ai_range_table = &ai_ranges_64xx,
1018 .ai_range_code = ai_range_code_64xx,
960 .ai_fifo = ai_fifo_64xx, 1019 .ai_fifo = ai_fifo_64xx,
961 .has_8255 = 1, 1020 .has_8255 = 1,
962 }, 1021 },
@@ -968,7 +1027,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
968 .ao_nchan = 0, 1027 .ao_nchan = 0,
969 .ao_scan_speed = 10000, 1028 .ao_scan_speed = 10000,
970 .layout = LAYOUT_64XX, 1029 .layout = LAYOUT_64XX,
971 .ai_range_table = &ai_ranges_64xx, 1030 .ai_range_table = &ai_ranges_64_mx,
1031 .ai_range_code = ai_range_code_64_mx,
972 .ai_fifo = ai_fifo_64xx, 1032 .ai_fifo = ai_fifo_64xx,
973 .has_8255 = 1, 1033 .has_8255 = 1,
974 }, 1034 },
@@ -980,7 +1040,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
980 .ao_nchan = 0, 1040 .ao_nchan = 0,
981 .ao_scan_speed = 10000, 1041 .ao_scan_speed = 10000,
982 .layout = LAYOUT_64XX, 1042 .layout = LAYOUT_64XX,
983 .ai_range_table = &ai_ranges_64xx, 1043 .ai_range_table = &ai_ranges_64_mx,
1044 .ai_range_code = ai_range_code_64_mx,
984 .ai_fifo = ai_fifo_64xx, 1045 .ai_fifo = ai_fifo_64xx,
985 .has_8255 = 1, 1046 .has_8255 = 1,
986 }, 1047 },
@@ -992,7 +1053,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
992 .ao_nchan = 0, 1053 .ao_nchan = 0,
993 .ao_scan_speed = 10000, 1054 .ao_scan_speed = 10000,
994 .layout = LAYOUT_64XX, 1055 .layout = LAYOUT_64XX,
995 .ai_range_table = &ai_ranges_64xx, 1056 .ai_range_table = &ai_ranges_64_mx,
1057 .ai_range_code = ai_range_code_64_mx,
996 .ai_fifo = ai_fifo_64xx, 1058 .ai_fifo = ai_fifo_64xx,
997 .has_8255 = 1, 1059 .has_8255 = 1,
998 }, 1060 },
@@ -1004,7 +1066,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
1004 .ao_nchan = 2, 1066 .ao_nchan = 2,
1005 .ao_scan_speed = 10000, 1067 .ao_scan_speed = 10000,
1006 .layout = LAYOUT_64XX, 1068 .layout = LAYOUT_64XX,
1007 .ai_range_table = &ai_ranges_64xx, 1069 .ai_range_table = &ai_ranges_64_mx,
1070 .ai_range_code = ai_range_code_64_mx,
1008 .ai_fifo = ai_fifo_64xx, 1071 .ai_fifo = ai_fifo_64xx,
1009 .has_8255 = 1, 1072 .has_8255 = 1,
1010 }, 1073 },
@@ -1016,7 +1079,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
1016 .ao_nchan = 2, 1079 .ao_nchan = 2,
1017 .ao_scan_speed = 10000, 1080 .ao_scan_speed = 10000,
1018 .layout = LAYOUT_64XX, 1081 .layout = LAYOUT_64XX,
1019 .ai_range_table = &ai_ranges_64xx, 1082 .ai_range_table = &ai_ranges_64_mx,
1083 .ai_range_code = ai_range_code_64_mx,
1020 .ai_fifo = ai_fifo_64xx, 1084 .ai_fifo = ai_fifo_64xx,
1021 .has_8255 = 1, 1085 .has_8255 = 1,
1022 }, 1086 },
@@ -1028,7 +1092,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
1028 .ao_nchan = 2, 1092 .ao_nchan = 2,
1029 .ao_scan_speed = 10000, 1093 .ao_scan_speed = 10000,
1030 .layout = LAYOUT_64XX, 1094 .layout = LAYOUT_64XX,
1031 .ai_range_table = &ai_ranges_64xx, 1095 .ai_range_table = &ai_ranges_64_mx,
1096 .ai_range_code = ai_range_code_64_mx,
1032 .ai_fifo = ai_fifo_64xx, 1097 .ai_fifo = ai_fifo_64xx,
1033 .has_8255 = 1, 1098 .has_8255 = 1,
1034 }, 1099 },
@@ -1115,45 +1180,8 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
1115 unsigned int range_index) 1180 unsigned int range_index)
1116{ 1181{
1117 const struct pcidas64_board *thisboard = dev->board_ptr; 1182 const struct pcidas64_board *thisboard = dev->board_ptr;
1118 const struct comedi_krange *range =
1119 &thisboard->ai_range_table->range[range_index];
1120 unsigned int bits = 0;
1121 1183
1122 switch (range->max) { 1184 return thisboard->ai_range_code[range_index] << 8;
1123 case 10000000:
1124 bits = 0x000;
1125 break;
1126 case 5000000:
1127 bits = 0x100;
1128 break;
1129 case 2000000:
1130 case 2500000:
1131 bits = 0x200;
1132 break;
1133 case 1000000:
1134 case 1250000:
1135 bits = 0x300;
1136 break;
1137 case 500000:
1138 bits = 0x400;
1139 break;
1140 case 200000:
1141 case 250000:
1142 bits = 0x500;
1143 break;
1144 case 100000:
1145 bits = 0x600;
1146 break;
1147 case 50000:
1148 bits = 0x700;
1149 break;
1150 default:
1151 dev_err(dev->class_dev, "bug! in %s\n", __func__);
1152 break;
1153 }
1154 if (range->min == 0)
1155 bits += 0x900;
1156 return bits;
1157} 1185}
1158 1186
1159static unsigned int hw_revision(const struct comedi_device *dev, 1187static unsigned int hw_revision(const struct comedi_device *dev,
@@ -2776,7 +2804,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
2776 /* check for fifo overrun */ 2804 /* check for fifo overrun */
2777 if (status & ADC_OVERRUN_BIT) { 2805 if (status & ADC_OVERRUN_BIT) {
2778 dev_err(dev->class_dev, "fifo overrun\n"); 2806 dev_err(dev->class_dev, "fifo overrun\n");
2779 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 2807 async->events |= COMEDI_CB_ERROR;
2780 } 2808 }
2781 /* spin lock makes sure no one else changes plx dma control reg */ 2809 /* spin lock makes sure no one else changes plx dma control reg */
2782 spin_lock_irqsave(&dev->spinlock, flags); 2810 spin_lock_irqsave(&dev->spinlock, flags);
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 01875d7c376f..2b2cfcdda5bd 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -22,12 +22,10 @@
22/* 22/*
23 * Driver: cb_pcidda 23 * Driver: cb_pcidda
24 * Description: MeasurementComputing PCI-DDA series 24 * Description: MeasurementComputing PCI-DDA series
25 * Devices: (Measurement Computing) PCI-DDA08/12 [pci-dda08/12] 25 * Devices: [Measurement Computing] PCI-DDA08/12 (pci-dda08/12),
26 * (Measurement Computing) PCI-DDA04/12 [pci-dda04/12] 26 * PCI-DDA04/12 (pci-dda04/12), PCI-DDA02/12 (pci-dda02/12),
27 * (Measurement Computing) PCI-DDA02/12 [pci-dda02/12] 27 * PCI-DDA08/16 (pci-dda08/16), PCI-DDA04/16 (pci-dda04/16),
28 * (Measurement Computing) PCI-DDA08/16 [pci-dda08/16] 28 * PCI-DDA02/16 (pci-dda02/16)
29 * (Measurement Computing) PCI-DDA04/16 [pci-dda04/16]
30 * (Measurement Computing) PCI-DDA02/16 [pci-dda02/16]
31 * Author: Ivan Martinez <ivanmr@altavista.com> 29 * Author: Ivan Martinez <ivanmr@altavista.com>
32 * Frank Mori Hess <fmhess@users.sourceforge.net> 30 * Frank Mori Hess <fmhess@users.sourceforge.net>
33 * Status: works 31 * Status: works
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index 85b2f4ab1ba4..221d3819c967 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -261,6 +261,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
261 { 261 {
262 /* Append dev:subdev to devpriv->name */ 262 /* Append dev:subdev to devpriv->name */
263 char buf[20]; 263 char buf[20];
264
264 snprintf(buf, sizeof(buf), "%u:%u ", 265 snprintf(buf, sizeof(buf), "%u:%u ",
265 bdev->minor, bdev->subdev); 266 bdev->minor, bdev->subdev);
266 strlcat(devpriv->name, buf, 267 strlcat(devpriv->name, buf,
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.c b/drivers/staging/comedi/drivers/comedi_isadma.c
new file mode 100644
index 000000000000..dbdea71d6b95
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_isadma.c
@@ -0,0 +1,262 @@
1/*
2 * COMEDI ISA DMA support functions
3 * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/module.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/dma-mapping.h>
20#include <asm/dma.h>
21
22#include "../comedidev.h"
23
24#include "comedi_isadma.h"
25
26/**
27 * comedi_isadma_program - program and enable an ISA DMA transfer
28 * @desc: the ISA DMA cookie to program and enable
29 */
30void comedi_isadma_program(struct comedi_isadma_desc *desc)
31{
32 unsigned long flags;
33
34 flags = claim_dma_lock();
35 clear_dma_ff(desc->chan);
36 set_dma_mode(desc->chan, desc->mode);
37 set_dma_addr(desc->chan, desc->hw_addr);
38 set_dma_count(desc->chan, desc->size);
39 enable_dma(desc->chan);
40 release_dma_lock(flags);
41}
42EXPORT_SYMBOL_GPL(comedi_isadma_program);
43
44/**
45 * comedi_isadma_disable - disable the ISA DMA channel
46 * @dma_chan: the DMA channel to disable
47 *
48 * Returns the residue (remaining bytes) left in the DMA transfer.
49 */
50unsigned int comedi_isadma_disable(unsigned int dma_chan)
51{
52 unsigned long flags;
53 unsigned int residue;
54
55 flags = claim_dma_lock();
56 disable_dma(dma_chan);
57 residue = get_dma_residue(dma_chan);
58 release_dma_lock(flags);
59
60 return residue;
61}
62EXPORT_SYMBOL_GPL(comedi_isadma_disable);
63
64/**
65 * comedi_isadma_disable_on_sample - disable the ISA DMA channel
66 * @dma_chan: the DMA channel to disable
67 * @size: the sample size (in bytes)
68 *
69 * Returns the residue (remaining bytes) left in the DMA transfer.
70 */
71unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan,
72 unsigned int size)
73{
74 int stalled = 0;
75 unsigned long flags;
76 unsigned int residue;
77 unsigned int new_residue;
78
79 residue = comedi_isadma_disable(dma_chan);
80 while (residue % size) {
81 /* residue is a partial sample, enable DMA to allow more data */
82 flags = claim_dma_lock();
83 enable_dma(dma_chan);
84 release_dma_lock(flags);
85
86 udelay(2);
87 new_residue = comedi_isadma_disable(dma_chan);
88
89 /* is DMA stalled? */
90 if (new_residue == residue) {
91 stalled++;
92 if (stalled > 10)
93 break;
94 }
95 residue = new_residue;
96 stalled = 0;
97 }
98 return residue;
99}
100EXPORT_SYMBOL_GPL(comedi_isadma_disable_on_sample);
101
102/**
103 * comedi_isadma_poll - poll the current DMA transfer
104 * @dma: the ISA DMA to poll
105 *
106 * Returns the position (in bytes) of the current DMA transfer.
107 */
108unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
109{
110 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
111 unsigned long flags;
112 unsigned int result;
113 unsigned int result1;
114
115 flags = claim_dma_lock();
116 clear_dma_ff(desc->chan);
117 if (!isa_dma_bridge_buggy)
118 disable_dma(desc->chan);
119 result = get_dma_residue(desc->chan);
120 /*
121 * Read the counter again and choose higher value in order to
122 * avoid reading during counter lower byte roll over if the
123 * isa_dma_bridge_buggy is set.
124 */
125 result1 = get_dma_residue(desc->chan);
126 if (!isa_dma_bridge_buggy)
127 enable_dma(desc->chan);
128 release_dma_lock(flags);
129
130 if (result < result1)
131 result = result1;
132 if (result >= desc->size || result == 0)
133 return 0;
134 else
135 return desc->size - result;
136}
137EXPORT_SYMBOL_GPL(comedi_isadma_poll);
138
139/**
140 * comedi_isadma_set_mode - set the ISA DMA transfer direction
141 * @desc: the ISA DMA cookie to set
142 * @dma_dir: the DMA direction
143 */
144void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir)
145{
146 desc->mode = (dma_dir == COMEDI_ISADMA_READ) ? DMA_MODE_READ
147 : DMA_MODE_WRITE;
148}
149EXPORT_SYMBOL_GPL(comedi_isadma_set_mode);
150
151/**
152 * comedi_isadma_alloc - allocate and initialize the ISA DMA
153 * @dev: comedi_device struct
154 * @n_desc: the number of cookies to allocate
155 * @dma_chan: DMA channel for the first cookie
156 * @dma_chan2: DMA channel for the second cookie
157 * @maxsize: the size of the buffer to allocate for each cookie
158 * @dma_dir: the DMA direction
159 *
160 * Returns the allocated and initialized ISA DMA or NULL if anything fails.
161 */
162struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev,
163 int n_desc, unsigned int dma_chan1,
164 unsigned int dma_chan2,
165 unsigned int maxsize, char dma_dir)
166{
167 struct comedi_isadma *dma = NULL;
168 struct comedi_isadma_desc *desc;
169 unsigned int dma_chans[2];
170 int i;
171
172 if (n_desc < 1 || n_desc > 2)
173 goto no_dma;
174
175 dma = kzalloc(sizeof(*dma), GFP_KERNEL);
176 if (!dma)
177 goto no_dma;
178
179 desc = kcalloc(n_desc, sizeof(*desc), GFP_KERNEL);
180 if (!desc)
181 goto no_dma;
182 dma->desc = desc;
183 dma->n_desc = n_desc;
184
185 dma_chans[0] = dma_chan1;
186 if (dma_chan2 == 0 || dma_chan2 == dma_chan1)
187 dma_chans[1] = dma_chan1;
188 else
189 dma_chans[1] = dma_chan2;
190
191 if (request_dma(dma_chans[0], dev->board_name))
192 goto no_dma;
193 dma->chan = dma_chans[0];
194 if (dma_chans[1] != dma_chans[0]) {
195 if (request_dma(dma_chans[1], dev->board_name))
196 goto no_dma;
197 }
198 dma->chan2 = dma_chans[1];
199
200 for (i = 0; i < n_desc; i++) {
201 desc = &dma->desc[i];
202 desc->chan = dma_chans[i];
203 desc->maxsize = maxsize;
204 desc->virt_addr = dma_alloc_coherent(NULL, desc->maxsize,
205 &desc->hw_addr,
206 GFP_KERNEL);
207 if (!desc->virt_addr)
208 goto no_dma;
209 comedi_isadma_set_mode(desc, dma_dir);
210 }
211
212 return dma;
213
214no_dma:
215 comedi_isadma_free(dma);
216 return NULL;
217}
218EXPORT_SYMBOL_GPL(comedi_isadma_alloc);
219
220/**
221 * comedi_isadma_free - free the ISA DMA
222 * @dma: the ISA DMA to free
223 */
224void comedi_isadma_free(struct comedi_isadma *dma)
225{
226 struct comedi_isadma_desc *desc;
227 int i;
228
229 if (!dma)
230 return;
231
232 if (dma->desc) {
233 for (i = 0; i < dma->n_desc; i++) {
234 desc = &dma->desc[i];
235 if (desc->virt_addr)
236 dma_free_coherent(NULL, desc->maxsize,
237 desc->virt_addr, desc->hw_addr);
238 }
239 kfree(dma->desc);
240 }
241 if (dma->chan2 && dma->chan2 != dma->chan)
242 free_dma(dma->chan2);
243 if (dma->chan)
244 free_dma(dma->chan);
245 kfree(dma);
246}
247EXPORT_SYMBOL_GPL(comedi_isadma_free);
248
249static int __init comedi_isadma_init(void)
250{
251 return 0;
252}
253module_init(comedi_isadma_init);
254
255static void __exit comedi_isadma_exit(void)
256{
257}
258module_exit(comedi_isadma_exit);
259
260MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
261MODULE_DESCRIPTION("Comedi ISA DMA support");
262MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h
new file mode 100644
index 000000000000..c7c524faf595
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_isadma.h
@@ -0,0 +1,116 @@
1/*
2 * COMEDI ISA DMA support functions
3 * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _COMEDI_ISADMA_H
17#define _COMEDI_ISADMA_H
18
19/*
20 * These are used to avoid issues when <asm/dma.h> and the DMA_MODE_
21 * defines are not available.
22 */
23#define COMEDI_ISADMA_READ 0
24#define COMEDI_ISADMA_WRITE 1
25
26/**
27 * struct comedi_isadma_desc - cookie for ISA DMA
28 * @virt_addr: virtual address of buffer
29 * @hw_addr: hardware (bus) address of buffer
30 * @chan: DMA channel
31 * @maxsize: allocated size of buffer (in bytes)
32 * @size: transfer size (in bytes)
33 * @mode: DMA_MODE_READ or DMA_MODE_WRITE
34 */
35struct comedi_isadma_desc {
36 void *virt_addr;
37 dma_addr_t hw_addr;
38 unsigned int chan;
39 unsigned int maxsize;
40 unsigned int size;
41 char mode;
42};
43
44/**
45 * struct comedi_isadma - ISA DMA data
46 * @desc: cookie for each DMA buffer
47 * @n_desc: the number of cookies
48 * @cur_dma: the current cookie in use
49 * @chan: the first DMA channel requested
50 * @chan2: the second DMA channel requested
51 */
52struct comedi_isadma {
53 struct comedi_isadma_desc *desc;
54 int n_desc;
55 int cur_dma;
56 unsigned int chan;
57 unsigned int chan2;
58};
59
60#if IS_ENABLED(CONFIG_ISA_DMA_API)
61
62void comedi_isadma_program(struct comedi_isadma_desc *);
63unsigned int comedi_isadma_disable(unsigned int dma_chan);
64unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan,
65 unsigned int size);
66unsigned int comedi_isadma_poll(struct comedi_isadma *);
67void comedi_isadma_set_mode(struct comedi_isadma_desc *, char dma_dir);
68
69struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *,
70 int n_desc, unsigned int dma_chan1,
71 unsigned int dma_chan2,
72 unsigned int maxsize, char dma_dir);
73void comedi_isadma_free(struct comedi_isadma *);
74
75#else /* !IS_ENABLED(CONFIG_ISA_DMA_API) */
76
77static inline void comedi_isadma_program(struct comedi_isadma_desc *desc)
78{
79}
80
81static inline unsigned int comedi_isadma_disable(unsigned int dma_chan)
82{
83 return 0;
84}
85
86static inline unsigned int
87comedi_isadma_disable_on_sample(unsigned int dma_chan, unsigned int size)
88{
89 return 0;
90}
91
92static inline unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
93{
94 return 0;
95}
96
97static inline void comedi_isadma_set_mode(struct comedi_isadma_desc *desc,
98 char dma_dir)
99{
100}
101
102static inline struct comedi_isadma *
103comedi_isadma_alloc(struct comedi_device *dev, int n_desc,
104 unsigned int dma_chan1, unsigned int dma_chan2,
105 unsigned int maxsize, char dma_dir)
106{
107 return NULL;
108}
109
110static inline void comedi_isadma_free(struct comedi_isadma *dma)
111{
112}
113
114#endif /* !IS_ENABLED(CONFIG_ISA_DMA_API) */
115
116#endif /* #ifndef _COMEDI_ISADMA_H */
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index 3bac903c8627..ceef6931edbe 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -24,7 +24,7 @@
24 * Description: Standard PC parallel port 24 * Description: Standard PC parallel port
25 * Author: ds 25 * Author: ds
26 * Status: works in immediate mode 26 * Status: works in immediate mode
27 * Devices: (standard) parallel port [comedi_parport] 27 * Devices: [standard] parallel port (comedi_parport)
28 * Updated: Tue, 30 Apr 2002 21:11:45 -0700 28 * Updated: Tue, 30 Apr 2002 21:11:45 -0700
29 * 29 *
30 * A cheap and easy way to get a few more digital I/O lines. Steal 30 * A cheap and easy way to get a few more digital I/O lines. Steal
diff --git a/drivers/staging/comedi/drivers/dac02.c b/drivers/staging/comedi/drivers/dac02.c
index beb36c8dd00a..a6798ad8fa7f 100644
--- a/drivers/staging/comedi/drivers/dac02.c
+++ b/drivers/staging/comedi/drivers/dac02.c
@@ -24,7 +24,7 @@
24/* 24/*
25 * Driver: dac02 25 * Driver: dac02
26 * Description: Comedi driver for DAC02 compatible boards 26 * Description: Comedi driver for DAC02 compatible boards
27 * Devices: (Keithley Metrabyte) DAC-02 [dac02] 27 * Devices: [Keithley Metrabyte] DAC-02 (dac02)
28 * Author: H Hartley Sweeten <hsweeten@visionengravers.com> 28 * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
29 * Updated: Tue, 11 Mar 2014 11:27:19 -0700 29 * Updated: Tue, 11 Mar 2014 11:27:19 -0700
30 * Status: unknown 30 * Status: unknown
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index 20a9f0eb72b5..c78c0df9bbe3 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * comedi/drivers/das08.c 2 * comedi/drivers/das08.c
3 * comedi driver for common DAS08 support (used by ISA/PCI/PCMCIA drivers) 3 * comedi module for common DAS08 support (used by ISA/PCI/PCMCIA drivers)
4 * 4 *
5 * COMEDI - Linux Control and Measurement Device Interface 5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org> 6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
@@ -18,21 +18,6 @@
18 * GNU General Public License for more details. 18 * GNU General Public License for more details.
19 */ 19 */
20 20
21/*
22 * Driver: das08
23 * Description: DAS-08 compatible boards
24 * Devices: various, see das08_isa, das08_cs, and das08_pci drivers
25 * Author: Warren Jasper, ds, Frank Hess
26 * Updated: Fri, 31 Aug 2012 19:19:06 +0100
27 * Status: works
28 *
29 * This driver is used by the das08_isa, das08_cs, and das08_pci
30 * drivers to provide the common support for the DAS-08 hardware.
31 *
32 * The driver doesn't support asynchronous commands, since the
33 * cheap das08 hardware doesn't really support them.
34 */
35
36#include <linux/module.h> 21#include <linux/module.h>
37 22
38#include "../comedidev.h" 23#include "../comedidev.h"
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index f3ccc2ce6d49..93fab6890161 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -41,10 +41,7 @@ Command support does not exist, but could be added for this board.
41 41
42#include <linux/module.h> 42#include <linux/module.h>
43 43
44#include "../comedidev.h" 44#include "../comedi_pcmcia.h"
45
46#include <pcmcia/cistpl.h>
47#include <pcmcia/ds.h>
48 45
49#include "das08.h" 46#include "das08.h"
50 47
diff --git a/drivers/staging/comedi/drivers/das08_isa.c b/drivers/staging/comedi/drivers/das08_isa.c
index e4ba268e78ab..2d9a31dab552 100644
--- a/drivers/staging/comedi/drivers/das08_isa.c
+++ b/drivers/staging/comedi/drivers/das08_isa.c
@@ -21,18 +21,12 @@
21/* 21/*
22 * Driver: das08_isa 22 * Driver: das08_isa
23 * Description: DAS-08 ISA/PC-104 compatible boards 23 * Description: DAS-08 ISA/PC-104 compatible boards
24 * Devices: (Keithley Metrabyte) DAS08 [isa-das08], 24 * Devices: [Keithley Metrabyte] DAS08 (isa-das08),
25 * (ComputerBoards) DAS08 [isa-das08] 25 * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
26 * (ComputerBoards) DAS08-PGM [das08-pgm] 26 * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
27 * (ComputerBoards) DAS08-PGH [das08-pgh] 27 * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
28 * (ComputerBoards) DAS08-PGL [das08-pgl] 28 * DAS08/JR-16-AO (das08jr-16-ao), PC104-DAS08 (pc104-das08),
29 * (ComputerBoards) DAS08-AOH [das08-aoh] 29 * DAS08/JR/16 (das08jr/16)
30 * (ComputerBoards) DAS08-AOL [das08-aol]
31 * (ComputerBoards) DAS08-AOM [das08-aom]
32 * (ComputerBoards) DAS08/JR-AO [das08/jr-ao]
33 * (ComputerBoards) DAS08/JR-16-AO [das08jr-16-ao]
34 * (ComputerBoards) PC104-DAS08 [pc104-das08]
35 * (ComputerBoards) DAS08/JR/16 [das08jr/16]
36 * Author: Warren Jasper, ds, Frank Hess 30 * Author: Warren Jasper, ds, Frank Hess
37 * Updated: Fri, 31 Aug 2012 19:19:06 +0100 31 * Updated: Fri, 31 Aug 2012 19:19:06 +0100
38 * Status: works 32 * Status: works
diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c
index 0987ce554945..b2ea10b848c3 100644
--- a/drivers/staging/comedi/drivers/das08_pci.c
+++ b/drivers/staging/comedi/drivers/das08_pci.c
@@ -21,7 +21,7 @@
21/* 21/*
22 * Driver: das08_pci 22 * Driver: das08_pci
23 * Description: DAS-08 PCI compatible boards 23 * Description: DAS-08 PCI compatible boards
24 * Devices: (ComputerBoards) PCI-DAS08 [pci-das08] 24 * Devices: [ComputerBoards] PCI-DAS08 (pci-das08)
25 * Author: Warren Jasper, ds, Frank Hess 25 * Author: Warren Jasper, ds, Frank Hess
26 * Updated: Fri, 31 Aug 2012 19:19:06 +0100 26 * Updated: Fri, 31 Aug 2012 19:19:06 +0100
27 * Status: works 27 * Status: works
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 2436057304a3..2c20311120f1 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -22,28 +22,17 @@
22 * Driver: das16 22 * Driver: das16
23 * Description: DAS16 compatible boards 23 * Description: DAS16 compatible boards
24 * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze 24 * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
25 * Devices: (Keithley Metrabyte) DAS-16 [das-16] 25 * Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
26 * (Keithley Metrabyte) DAS-16G [das-16g] 26 * DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
27 * (Keithley Metrabyte) DAS-16F [das-16f] 27 * DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
28 * (Keithley Metrabyte) DAS-1201 [das-1201] 28 * DAS-1602 (das-1602),
29 * (Keithley Metrabyte) DAS-1202 [das-1202] 29 * [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
30 * (Keithley Metrabyte) DAS-1401 [das-1401] 30 * PC104-DAS16JR/16 (pc104-das16jr/16), CIO-DAS16 (cio-das16),
31 * (Keithley Metrabyte) DAS-1402 [das-1402] 31 * CIO-DAS16F (cio-das16/f), CIO-DAS16/JR (cio-das16/jr),
32 * (Keithley Metrabyte) DAS-1601 [das-1601] 32 * CIO-DAS16JR/16 (cio-das16jr/16), CIO-DAS1401/12 (cio-das1401/12),
33 * (Keithley Metrabyte) DAS-1602 [das-1602] 33 * CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
34 * (ComputerBoards) PC104-DAS16/JR [pc104-das16jr] 34 * CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
35 * (ComputerBoards) PC104-DAS16JR/16 [pc104-das16jr/16] 35 * CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
36 * (ComputerBoards) CIO-DAS16 [cio-das16]
37 * (ComputerBoards) CIO-DAS16F [cio-das16/f]
38 * (ComputerBoards) CIO-DAS16/JR [cio-das16/jr]
39 * (ComputerBoards) CIO-DAS16JR/16 [cio-das16jr/16]
40 * (ComputerBoards) CIO-DAS1401/12 [cio-das1401/12]
41 * (ComputerBoards) CIO-DAS1402/12 [cio-das1402/12]
42 * (ComputerBoards) CIO-DAS1402/16 [cio-das1402/16]
43 * (ComputerBoards) CIO-DAS1601/12 [cio-das1601/12]
44 * (ComputerBoards) CIO-DAS1602/12 [cio-das1602/12]
45 * (ComputerBoards) CIO-DAS1602/16 [cio-das1602/16]
46 * (ComputerBoards) CIO-DAS16/330 [cio-das16/330]
47 * Status: works 36 * Status: works
48 * Updated: 2003-10-12 37 * Updated: 2003-10-12
49 * 38 *
@@ -82,17 +71,14 @@
82 71
83#include <linux/module.h> 72#include <linux/module.h>
84#include <linux/slab.h> 73#include <linux/slab.h>
85#include <linux/delay.h>
86#include <linux/pci.h>
87#include <linux/interrupt.h> 74#include <linux/interrupt.h>
88 75
89#include <asm/dma.h>
90
91#include "../comedidev.h" 76#include "../comedidev.h"
92 77
78#include "comedi_isadma.h"
79#include "comedi_fc.h"
93#include "8253.h" 80#include "8253.h"
94#include "8255.h" 81#include "8255.h"
95#include "comedi_fc.h"
96 82
97#define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */ 83#define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */
98 84
@@ -451,86 +437,37 @@ static inline int timer_period(void)
451} 437}
452 438
453struct das16_private_struct { 439struct das16_private_struct {
440 struct comedi_isadma *dma;
454 unsigned int clockbase; 441 unsigned int clockbase;
455 unsigned int ctrl_reg; 442 unsigned int ctrl_reg;
456 unsigned long adc_byte_count;
457 unsigned int divisor1; 443 unsigned int divisor1;
458 unsigned int divisor2; 444 unsigned int divisor2;
459 unsigned int dma_chan;
460 uint16_t *dma_buffer[2];
461 dma_addr_t dma_buffer_addr[2];
462 unsigned int current_buffer;
463 unsigned int dma_transfer_size;
464 struct comedi_lrange *user_ai_range_table;
465 struct comedi_lrange *user_ao_range_table;
466 struct timer_list timer; 445 struct timer_list timer;
467 short timer_running;
468 unsigned long extra_iobase; 446 unsigned long extra_iobase;
469 unsigned int can_burst:1; 447 unsigned int can_burst:1;
448 unsigned int timer_running:1;
470}; 449};
471 450
472static void das16_ai_enable(struct comedi_device *dev, 451static void das16_ai_setup_dma(struct comedi_device *dev,
473 unsigned int mode, unsigned int src) 452 struct comedi_subdevice *s,
474{ 453 unsigned int unread_samples)
475 struct das16_private_struct *devpriv = dev->private;
476
477 devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE |
478 DAS16_CTRL_DMAE |
479 DAS16_CTRL_PACING_MASK);
480 devpriv->ctrl_reg |= mode;
481
482 if (src == TRIG_EXT)
483 devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER;
484 else
485 devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER;
486 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
487}
488
489static void das16_ai_disable(struct comedi_device *dev)
490{ 454{
491 struct das16_private_struct *devpriv = dev->private; 455 struct das16_private_struct *devpriv = dev->private;
456 struct comedi_isadma *dma = devpriv->dma;
457 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
458 unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
459 unsigned int nsamples;
492 460
493 /* disable interrupts, dma and pacer clocked conversions */ 461 /*
494 devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | 462 * Determine dma size based on the buffer size plus the number of
495 DAS16_CTRL_DMAE | 463 * unread samples and the number of samples remaining in the command.
496 DAS16_CTRL_PACING_MASK); 464 */
497 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG); 465 nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
498} 466 if (nsamples > unread_samples) {
499 467 nsamples -= unread_samples;
500/* the pc104-das16jr (at least) has problems if the dma 468 desc->size = comedi_samples_to_bytes(s, nsamples);
501 transfer is interrupted in the middle of transferring 469 comedi_isadma_program(desc);
502 a 16 bit sample, so this function takes care to get
503 an even transfer count after disabling dma
504 channel.
505*/
506static int disable_dma_on_even(struct comedi_device *dev)
507{
508 struct das16_private_struct *devpriv = dev->private;
509 static const int disable_limit = 100;
510 static const int enable_timeout = 100;
511 int residue;
512 int new_residue;
513 int i;
514 int j;
515
516 disable_dma(devpriv->dma_chan);
517 residue = get_dma_residue(devpriv->dma_chan);
518 for (i = 0; i < disable_limit && (residue % 2); ++i) {
519 enable_dma(devpriv->dma_chan);
520 for (j = 0; j < enable_timeout; ++j) {
521 udelay(2);
522 new_residue = get_dma_residue(devpriv->dma_chan);
523 if (new_residue != residue)
524 break;
525 }
526 disable_dma(devpriv->dma_chan);
527 residue = get_dma_residue(devpriv->dma_chan);
528 }
529 if (i == disable_limit) {
530 dev_err(dev->class_dev,
531 "failed to get an even dma transfer, could be trouble\n");
532 } 470 }
533 return residue;
534} 471}
535 472
536static void das16_interrupt(struct comedi_device *dev) 473static void das16_interrupt(struct comedi_device *dev)
@@ -539,11 +476,12 @@ static void das16_interrupt(struct comedi_device *dev)
539 struct comedi_subdevice *s = dev->read_subdev; 476 struct comedi_subdevice *s = dev->read_subdev;
540 struct comedi_async *async = s->async; 477 struct comedi_async *async = s->async;
541 struct comedi_cmd *cmd = &async->cmd; 478 struct comedi_cmd *cmd = &async->cmd;
479 struct comedi_isadma *dma = devpriv->dma;
480 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
542 unsigned long spin_flags; 481 unsigned long spin_flags;
543 unsigned long dma_flags; 482 unsigned int residue;
483 unsigned int nbytes;
544 unsigned int nsamples; 484 unsigned int nsamples;
545 int num_bytes, residue;
546 int buffer_index;
547 485
548 spin_lock_irqsave(&dev->spinlock, spin_flags); 486 spin_lock_irqsave(&dev->spinlock, spin_flags);
549 if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) { 487 if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) {
@@ -551,42 +489,36 @@ static void das16_interrupt(struct comedi_device *dev)
551 return; 489 return;
552 } 490 }
553 491
554 dma_flags = claim_dma_lock(); 492 /*
555 clear_dma_ff(devpriv->dma_chan); 493 * The pc104-das16jr (at least) has problems if the dma
556 residue = disable_dma_on_even(dev); 494 * transfer is interrupted in the middle of transferring
495 * a 16 bit sample.
496 */
497 residue = comedi_isadma_disable_on_sample(desc->chan,
498 comedi_bytes_per_sample(s));
557 499
558 /* figure out how many points to read */ 500 /* figure out how many samples to read */
559 if (residue > devpriv->dma_transfer_size) { 501 if (residue > desc->size) {
560 dev_err(dev->class_dev, "residue > transfer size!\n"); 502 dev_err(dev->class_dev, "residue > transfer size!\n");
561 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 503 async->events |= COMEDI_CB_ERROR;
562 num_bytes = 0; 504 nbytes = 0;
563 } else 505 } else {
564 num_bytes = devpriv->dma_transfer_size - residue; 506 nbytes = desc->size - residue;
565
566 if (cmd->stop_src == TRIG_COUNT &&
567 num_bytes >= devpriv->adc_byte_count) {
568 num_bytes = devpriv->adc_byte_count;
569 async->events |= COMEDI_CB_EOA;
570 } 507 }
508 nsamples = comedi_bytes_to_samples(s, nbytes);
571 509
572 buffer_index = devpriv->current_buffer; 510 /* restart DMA if more samples are needed */
573 devpriv->current_buffer = (devpriv->current_buffer + 1) % 2; 511 if (nsamples) {
574 devpriv->adc_byte_count -= num_bytes; 512 dma->cur_dma = 1 - dma->cur_dma;
575 513 das16_ai_setup_dma(dev, s, nsamples);
576 /* re-enable dma */
577 if ((async->events & COMEDI_CB_EOA) == 0) {
578 set_dma_addr(devpriv->dma_chan,
579 devpriv->dma_buffer_addr[devpriv->current_buffer]);
580 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
581 enable_dma(devpriv->dma_chan);
582 } 514 }
583 release_dma_lock(dma_flags);
584 515
585 spin_unlock_irqrestore(&dev->spinlock, spin_flags); 516 spin_unlock_irqrestore(&dev->spinlock, spin_flags);
586 517
587 nsamples = comedi_bytes_to_samples(s, num_bytes); 518 comedi_buf_write_samples(s, desc->virt_addr, nsamples);
588 comedi_buf_write_samples(s, devpriv->dma_buffer[buffer_index], 519
589 nsamples); 520 if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
521 async->events |= COMEDI_CB_EOA;
590 522
591 comedi_handle_events(dev, s); 523 comedi_handle_events(dev, s);
592} 524}
@@ -605,6 +537,29 @@ static void das16_timer_interrupt(unsigned long arg)
605 spin_unlock_irqrestore(&dev->spinlock, flags); 537 spin_unlock_irqrestore(&dev->spinlock, flags);
606} 538}
607 539
540static void das16_ai_set_mux_range(struct comedi_device *dev,
541 unsigned int first_chan,
542 unsigned int last_chan,
543 unsigned int range)
544{
545 const struct das16_board *board = dev->board_ptr;
546
547 /* set multiplexer */
548 outb(first_chan | (last_chan << 4), dev->iobase + DAS16_MUX_REG);
549
550 /* some boards do not have programmable gain */
551 if (board->ai_pg == das16_pg_none)
552 return;
553
554 /*
555 * Set gain (this is also burst rate register but according to
556 * computer boards manual, burst rate does nothing, even on
557 * keithley cards).
558 */
559 outb((das16_gainlists[board->ai_pg])[range],
560 dev->iobase + DAS16_GAIN_REG);
561}
562
608static int das16_ai_check_chanlist(struct comedi_device *dev, 563static int das16_ai_check_chanlist(struct comedi_device *dev,
609 struct comedi_subdevice *s, 564 struct comedi_subdevice *s,
610 struct comedi_cmd *cmd) 565 struct comedi_cmd *cmd)
@@ -755,13 +710,15 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
755 710
756static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) 711static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
757{ 712{
758 const struct das16_board *board = dev->board_ptr;
759 struct das16_private_struct *devpriv = dev->private; 713 struct das16_private_struct *devpriv = dev->private;
714 struct comedi_isadma *dma = devpriv->dma;
760 struct comedi_async *async = s->async; 715 struct comedi_async *async = s->async;
761 struct comedi_cmd *cmd = &async->cmd; 716 struct comedi_cmd *cmd = &async->cmd;
717 unsigned int first_chan = CR_CHAN(cmd->chanlist[0]);
718 unsigned int last_chan = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
719 unsigned int range = CR_RANGE(cmd->chanlist[0]);
762 unsigned int byte; 720 unsigned int byte;
763 unsigned long flags; 721 unsigned long flags;
764 int range;
765 722
766 if (cmd->flags & CMDF_PRIORITY) { 723 if (cmd->flags & CMDF_PRIORITY) {
767 dev_err(dev->class_dev, 724 dev_err(dev->class_dev,
@@ -769,24 +726,11 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
769 return -1; 726 return -1;
770 } 727 }
771 728
772 devpriv->adc_byte_count = cmd->stop_arg * comedi_bytes_per_scan(s);
773
774 if (devpriv->can_burst) 729 if (devpriv->can_burst)
775 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG); 730 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG);
776 731
777 /* set scan limits */ 732 /* set mux and range for chanlist scan */
778 byte = CR_CHAN(cmd->chanlist[0]); 733 das16_ai_set_mux_range(dev, first_chan, last_chan, range);
779 byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
780 outb(byte, dev->iobase + DAS16_MUX_REG);
781
782 /* set gain (this is also burst rate register but according to
783 * computer boards manual, burst rate does nothing, even on
784 * keithley cards) */
785 if (board->ai_pg != das16_pg_none) {
786 range = CR_RANGE(cmd->chanlist[0]);
787 outb((das16_gainlists[board->ai_pg])[range],
788 dev->iobase + DAS16_GAIN_REG);
789 }
790 734
791 /* set counter mode and counts */ 735 /* set counter mode and counts */
792 cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags); 736 cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags);
@@ -805,19 +749,9 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
805 } 749 }
806 outb(byte, dev->iobase + DAS16_PACER_REG); 750 outb(byte, dev->iobase + DAS16_PACER_REG);
807 751
808 /* set up dma transfer */ 752 /* set up dma transfer */
809 flags = claim_dma_lock(); 753 dma->cur_dma = 0;
810 disable_dma(devpriv->dma_chan); 754 das16_ai_setup_dma(dev, s, 0);
811 /* clear flip-flop to make sure 2-byte registers for
812 * count and address get set correctly */
813 clear_dma_ff(devpriv->dma_chan);
814 devpriv->current_buffer = 0;
815 set_dma_addr(devpriv->dma_chan,
816 devpriv->dma_buffer_addr[devpriv->current_buffer]);
817 devpriv->dma_transfer_size = DAS16_DMA_SIZE;
818 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
819 enable_dma(devpriv->dma_chan);
820 release_dma_lock(flags);
821 755
822 /* set up timer */ 756 /* set up timer */
823 spin_lock_irqsave(&dev->spinlock, flags); 757 spin_lock_irqsave(&dev->spinlock, flags);
@@ -825,7 +759,14 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
825 devpriv->timer.expires = jiffies + timer_period(); 759 devpriv->timer.expires = jiffies + timer_period();
826 add_timer(&devpriv->timer); 760 add_timer(&devpriv->timer);
827 761
828 das16_ai_enable(dev, DAS16_CTRL_DMAE, cmd->convert_src); 762 /* enable DMA interrupt with external or internal pacing */
763 devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | DAS16_CTRL_PACING_MASK);
764 devpriv->ctrl_reg |= DAS16_CTRL_DMAE;
765 if (cmd->convert_src == TRIG_EXT)
766 devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER;
767 else
768 devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER;
769 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
829 770
830 if (devpriv->can_burst) 771 if (devpriv->can_burst)
831 outb(0, dev->iobase + DAS1600_CONV_REG); 772 outb(0, dev->iobase + DAS1600_CONV_REG);
@@ -837,12 +778,17 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
837static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 778static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
838{ 779{
839 struct das16_private_struct *devpriv = dev->private; 780 struct das16_private_struct *devpriv = dev->private;
781 struct comedi_isadma *dma = devpriv->dma;
840 unsigned long flags; 782 unsigned long flags;
841 783
842 spin_lock_irqsave(&dev->spinlock, flags); 784 spin_lock_irqsave(&dev->spinlock, flags);
843 785
844 das16_ai_disable(dev); 786 /* disable interrupts, dma and pacer clocked conversions */
845 disable_dma(devpriv->dma_chan); 787 devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | DAS16_CTRL_DMAE |
788 DAS16_CTRL_PACING_MASK);
789 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
790
791 comedi_isadma_disable(dma->chan);
846 792
847 /* disable SW timer */ 793 /* disable SW timer */
848 if (devpriv->timer_running) { 794 if (devpriv->timer_running) {
@@ -893,23 +839,14 @@ static int das16_ai_insn_read(struct comedi_device *dev,
893 struct comedi_insn *insn, 839 struct comedi_insn *insn,
894 unsigned int *data) 840 unsigned int *data)
895{ 841{
896 const struct das16_board *board = dev->board_ptr;
897 unsigned int chan = CR_CHAN(insn->chanspec); 842 unsigned int chan = CR_CHAN(insn->chanspec);
898 unsigned int range = CR_RANGE(insn->chanspec); 843 unsigned int range = CR_RANGE(insn->chanspec);
899 unsigned int val; 844 unsigned int val;
900 int ret; 845 int ret;
901 int i; 846 int i;
902 847
903 das16_ai_disable(dev); 848 /* set mux and range for single channel */
904 849 das16_ai_set_mux_range(dev, chan, chan, range);
905 /* set multiplexer */
906 outb(chan | (chan << 4), dev->iobase + DAS16_MUX_REG);
907
908 /* set gain */
909 if (board->ai_pg != das16_pg_none) {
910 outb((das16_gainlists[board->ai_pg])[range],
911 dev->iobase + DAS16_GAIN_REG);
912 }
913 850
914 for (i = 0; i < insn->n; i++) { 851 for (i = 0; i < insn->n; i++) {
915 /* trigger conversion */ 852 /* trigger conversion */
@@ -1001,14 +938,107 @@ static void das16_reset(struct comedi_device *dev)
1001 outb(0, dev->iobase + DAS16_TIMER_BASE_REG + i8254_control_reg); 938 outb(0, dev->iobase + DAS16_TIMER_BASE_REG + i8254_control_reg);
1002} 939}
1003 940
941static void das16_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
942{
943 struct das16_private_struct *devpriv = dev->private;
944
945 /* only DMA channels 3 and 1 are valid */
946 if (!(dma_chan == 1 || dma_chan == 3))
947 return;
948
949 /* DMA uses two buffers */
950 devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
951 DAS16_DMA_SIZE, COMEDI_ISADMA_READ);
952 if (devpriv->dma) {
953 init_timer(&devpriv->timer);
954 devpriv->timer.function = das16_timer_interrupt;
955 devpriv->timer.data = (unsigned long)dev;
956 }
957}
958
959static void das16_free_dma(struct comedi_device *dev)
960{
961 struct das16_private_struct *devpriv = dev->private;
962
963 if (devpriv) {
964 if (devpriv->timer.data)
965 del_timer_sync(&devpriv->timer);
966 comedi_isadma_free(devpriv->dma);
967 }
968}
969
970static const struct comedi_lrange *das16_ai_range(struct comedi_device *dev,
971 struct comedi_subdevice *s,
972 struct comedi_devconfig *it,
973 unsigned int pg_type,
974 unsigned int status)
975{
976 unsigned int min = it->options[4];
977 unsigned int max = it->options[5];
978
979 /* get any user-defined input range */
980 if (pg_type == das16_pg_none && (min || max)) {
981 struct comedi_lrange *lrange;
982 struct comedi_krange *krange;
983
984 /* allocate single-range range table */
985 lrange = comedi_alloc_spriv(s,
986 sizeof(*lrange) + sizeof(*krange));
987 if (!lrange)
988 return &range_unknown;
989
990 /* initialize ai range */
991 lrange->length = 1;
992 krange = lrange->range;
993 krange->min = min;
994 krange->max = max;
995 krange->flags = UNIT_volt;
996
997 return lrange;
998 }
999
1000 /* use software programmable range */
1001 if (status & DAS16_STATUS_UNIPOLAR)
1002 return das16_ai_uni_lranges[pg_type];
1003 return das16_ai_bip_lranges[pg_type];
1004}
1005
1006static const struct comedi_lrange *das16_ao_range(struct comedi_device *dev,
1007 struct comedi_subdevice *s,
1008 struct comedi_devconfig *it)
1009{
1010 unsigned int min = it->options[6];
1011 unsigned int max = it->options[7];
1012
1013 /* get any user-defined output range */
1014 if (min || max) {
1015 struct comedi_lrange *lrange;
1016 struct comedi_krange *krange;
1017
1018 /* allocate single-range range table */
1019 lrange = comedi_alloc_spriv(s,
1020 sizeof(*lrange) + sizeof(*krange));
1021 if (!lrange)
1022 return &range_unknown;
1023
1024 /* initialize ao range */
1025 lrange->length = 1;
1026 krange = lrange->range;
1027 krange->min = min;
1028 krange->max = max;
1029 krange->flags = UNIT_volt;
1030
1031 return lrange;
1032 }
1033
1034 return &range_unknown;
1035}
1036
1004static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1037static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1005{ 1038{
1006 const struct das16_board *board = dev->board_ptr; 1039 const struct das16_board *board = dev->board_ptr;
1007 struct das16_private_struct *devpriv; 1040 struct das16_private_struct *devpriv;
1008 struct comedi_subdevice *s; 1041 struct comedi_subdevice *s;
1009 struct comedi_lrange *lrange;
1010 struct comedi_krange *krange;
1011 unsigned int dma_chan = it->options[2];
1012 unsigned int status; 1042 unsigned int status;
1013 int ret; 1043 int ret;
1014 1044
@@ -1063,72 +1093,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1063 devpriv->clockbase = I8254_OSC_BASE_1MHZ; 1093 devpriv->clockbase = I8254_OSC_BASE_1MHZ;
1064 } 1094 }
1065 1095
1066 /* initialize dma */ 1096 das16_alloc_dma(dev, it->options[2]);
1067 if (dma_chan == 1 || dma_chan == 3) {
1068 unsigned long flags;
1069 int i;
1070
1071 if (request_dma(dma_chan, dev->board_name)) {
1072 dev_err(dev->class_dev,
1073 "failed to request dma channel %i\n",
1074 dma_chan);
1075 return -EINVAL;
1076 }
1077 devpriv->dma_chan = dma_chan;
1078
1079 /* allocate dma buffers */
1080 for (i = 0; i < 2; i++) {
1081 void *p;
1082
1083 p = pci_alloc_consistent(NULL, DAS16_DMA_SIZE,
1084 &devpriv->dma_buffer_addr[i]);
1085 if (!p)
1086 return -ENOMEM;
1087 devpriv->dma_buffer[i] = p;
1088 }
1089
1090 flags = claim_dma_lock();
1091 disable_dma(devpriv->dma_chan);
1092 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1093 release_dma_lock(flags);
1094
1095 init_timer(&devpriv->timer);
1096 devpriv->timer.function = das16_timer_interrupt;
1097 devpriv->timer.data = (unsigned long)dev;
1098 }
1099
1100 /* get any user-defined input range */
1101 if (board->ai_pg == das16_pg_none &&
1102 (it->options[4] || it->options[5])) {
1103 /* allocate single-range range table */
1104 lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL);
1105 if (!lrange)
1106 return -ENOMEM;
1107
1108 /* initialize ai range */
1109 devpriv->user_ai_range_table = lrange;
1110 lrange->length = 1;
1111 krange = devpriv->user_ai_range_table->range;
1112 krange->min = it->options[4];
1113 krange->max = it->options[5];
1114 krange->flags = UNIT_volt;
1115 }
1116
1117 /* get any user-defined output range */
1118 if (it->options[6] || it->options[7]) {
1119 /* allocate single-range range table */
1120 lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL);
1121 if (!lrange)
1122 return -ENOMEM;
1123
1124 /* initialize ao range */
1125 devpriv->user_ao_range_table = lrange;
1126 lrange->length = 1;
1127 krange = devpriv->user_ao_range_table->range;
1128 krange->min = it->options[6];
1129 krange->max = it->options[7];
1130 krange->flags = UNIT_volt;
1131 }
1132 1097
1133 ret = comedi_alloc_subdevices(dev, 4 + board->has_8255); 1098 ret = comedi_alloc_subdevices(dev, 4 + board->has_8255);
1134 if (ret) 1099 if (ret)
@@ -1149,15 +1114,9 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1149 } 1114 }
1150 s->len_chanlist = s->n_chan; 1115 s->len_chanlist = s->n_chan;
1151 s->maxdata = board->ai_maxdata; 1116 s->maxdata = board->ai_maxdata;
1152 if (devpriv->user_ai_range_table) { /* user defined ai range */ 1117 s->range_table = das16_ai_range(dev, s, it, board->ai_pg, status);
1153 s->range_table = devpriv->user_ai_range_table;
1154 } else if (status & DAS16_STATUS_UNIPOLAR) {
1155 s->range_table = das16_ai_uni_lranges[board->ai_pg];
1156 } else {
1157 s->range_table = das16_ai_bip_lranges[board->ai_pg];
1158 }
1159 s->insn_read = das16_ai_insn_read; 1118 s->insn_read = das16_ai_insn_read;
1160 if (devpriv->dma_chan) { 1119 if (devpriv->dma) {
1161 dev->read_subdev = s; 1120 dev->read_subdev = s;
1162 s->subdev_flags |= SDF_CMD_READ; 1121 s->subdev_flags |= SDF_CMD_READ;
1163 s->do_cmdtest = das16_cmd_test; 1122 s->do_cmdtest = das16_cmd_test;
@@ -1173,7 +1132,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1173 s->subdev_flags = SDF_WRITABLE; 1132 s->subdev_flags = SDF_WRITABLE;
1174 s->n_chan = 2; 1133 s->n_chan = 2;
1175 s->maxdata = 0x0fff; 1134 s->maxdata = 0x0fff;
1176 s->range_table = devpriv->user_ao_range_table; 1135 s->range_table = das16_ao_range(dev, s, it);
1177 s->insn_write = das16_ao_insn_write; 1136 s->insn_write = das16_ao_insn_write;
1178 1137
1179 ret = comedi_alloc_subdev_readback(s); 1138 ret = comedi_alloc_subdev_readback(s);
@@ -1230,25 +1189,11 @@ static void das16_detach(struct comedi_device *dev)
1230{ 1189{
1231 const struct das16_board *board = dev->board_ptr; 1190 const struct das16_board *board = dev->board_ptr;
1232 struct das16_private_struct *devpriv = dev->private; 1191 struct das16_private_struct *devpriv = dev->private;
1233 int i;
1234 1192
1235 if (devpriv) { 1193 if (devpriv) {
1236 if (devpriv->timer.data)
1237 del_timer_sync(&devpriv->timer);
1238 if (dev->iobase) 1194 if (dev->iobase)
1239 das16_reset(dev); 1195 das16_reset(dev);
1240 1196 das16_free_dma(dev);
1241 for (i = 0; i < 2; i++) {
1242 if (devpriv->dma_buffer[i])
1243 pci_free_consistent(NULL, DAS16_DMA_SIZE,
1244 devpriv->dma_buffer[i],
1245 devpriv->
1246 dma_buffer_addr[i]);
1247 }
1248 if (devpriv->dma_chan)
1249 free_dma(devpriv->dma_chan);
1250 kfree(devpriv->user_ai_range_table);
1251 kfree(devpriv->user_ao_range_table);
1252 1197
1253 if (devpriv->extra_iobase) 1198 if (devpriv->extra_iobase)
1254 release_region(devpriv->extra_iobase, 1199 release_region(devpriv->extra_iobase,
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index 80f41b7e8273..3666a68979fb 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -455,7 +455,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
455 /* this probably won't catch overruns since the card doesn't generate 455 /* this probably won't catch overruns since the card doesn't generate
456 * overrun interrupts, but we might as well try */ 456 * overrun interrupts, but we might as well try */
457 if (status & OVRUN) { 457 if (status & OVRUN) {
458 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 458 async->events |= COMEDI_CB_ERROR;
459 dev_err(dev->class_dev, "fifo overflow\n"); 459 dev_err(dev->class_dev, "fifo overflow\n");
460 } 460 }
461 461
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index be825d21a185..0790a28828de 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -98,12 +98,12 @@ TODO:
98#include <linux/interrupt.h> 98#include <linux/interrupt.h>
99#include <linux/slab.h> 99#include <linux/slab.h>
100#include <linux/io.h> 100#include <linux/io.h>
101#include "../comedidev.h"
102 101
103#include <asm/dma.h> 102#include "../comedidev.h"
104 103
105#include "8253.h" 104#include "comedi_isadma.h"
106#include "comedi_fc.h" 105#include "comedi_fc.h"
106#include "8253.h"
107 107
108/* misc. defines */ 108/* misc. defines */
109#define DAS1800_SIZE 16 /* uses 16 io addresses */ 109#define DAS1800_SIZE 16 /* uses 16 io addresses */
@@ -421,19 +421,14 @@ static const struct das1800_board das1800_boards[] = {
421}; 421};
422 422
423struct das1800_private { 423struct das1800_private {
424 struct comedi_isadma *dma;
424 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ 425 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
425 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ 426 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
426 int irq_dma_bits; /* bits for control register b */ 427 int irq_dma_bits; /* bits for control register b */
427 /* dma bits for control register b, stored so that dma can be 428 /* dma bits for control register b, stored so that dma can be
428 * turned on and off */ 429 * turned on and off */
429 int dma_bits; 430 int dma_bits;
430 unsigned int dma0; /* dma channels used */ 431 uint16_t *fifo_buf; /* bounce buffer for analog input FIFO */
431 unsigned int dma1;
432 unsigned int dma_current; /* dma channel currently in use */
433 uint16_t *ai_buf0; /* pointers to dma buffers */
434 uint16_t *ai_buf1;
435 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
436 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
437 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ 432 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
438 unsigned short ao_update_bits; /* remembers the last write to the 433 unsigned short ao_update_bits; /* remembers the last write to the
439 * 'update' dac */ 434 * 'update' dac */
@@ -480,9 +475,9 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev,
480 struct das1800_private *devpriv = dev->private; 475 struct das1800_private *devpriv = dev->private;
481 unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2); 476 unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
482 477
483 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, nsamples); 478 insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
484 munge_data(dev, devpriv->ai_buf0, nsamples); 479 munge_data(dev, devpriv->fifo_buf, nsamples);
485 comedi_buf_write_samples(s, devpriv->ai_buf0, nsamples); 480 comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
486} 481}
487 482
488static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 483static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
@@ -508,29 +503,21 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
508 } 503 }
509} 504}
510 505
511/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 506/* Utility function used by das1800_flush_dma() and das1800_handle_dma() */
512 * Assumes dma lock is held */
513static void das1800_flush_dma_channel(struct comedi_device *dev, 507static void das1800_flush_dma_channel(struct comedi_device *dev,
514 struct comedi_subdevice *s, 508 struct comedi_subdevice *s,
515 unsigned int channel, uint16_t *buffer) 509 struct comedi_isadma_desc *desc)
516{ 510{
517 struct das1800_private *devpriv = dev->private; 511 unsigned int residue = comedi_isadma_disable(desc->chan);
518 unsigned int nbytes; 512 unsigned int nbytes = desc->size - residue;
519 unsigned int nsamples; 513 unsigned int nsamples;
520 514
521 disable_dma(channel);
522
523 /* clear flip-flop to make sure 2-byte registers
524 * get set correctly */
525 clear_dma_ff(channel);
526
527 /* figure out how many points to read */ 515 /* figure out how many points to read */
528 nbytes = devpriv->dma_transfer_size - get_dma_residue(channel);
529 nsamples = comedi_bytes_to_samples(s, nbytes); 516 nsamples = comedi_bytes_to_samples(s, nbytes);
530 nsamples = comedi_nsamples_left(s, nsamples); 517 nsamples = comedi_nsamples_left(s, nsamples);
531 518
532 munge_data(dev, buffer, nsamples); 519 munge_data(dev, desc->virt_addr, nsamples);
533 comedi_buf_write_samples(s, buffer, nsamples); 520 comedi_buf_write_samples(s, desc->virt_addr, nsamples);
534} 521}
535 522
536/* flushes remaining data from board when external trigger has stopped acquisition 523/* flushes remaining data from board when external trigger has stopped acquisition
@@ -539,28 +526,19 @@ static void das1800_flush_dma(struct comedi_device *dev,
539 struct comedi_subdevice *s) 526 struct comedi_subdevice *s)
540{ 527{
541 struct das1800_private *devpriv = dev->private; 528 struct das1800_private *devpriv = dev->private;
542 unsigned long flags; 529 struct comedi_isadma *dma = devpriv->dma;
530 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
543 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 531 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
544 532
545 flags = claim_dma_lock(); 533 das1800_flush_dma_channel(dev, s, desc);
546 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
547 devpriv->dma_current_buf);
548 534
549 if (dual_dma) { 535 if (dual_dma) {
550 /* switch to other channel and flush it */ 536 /* switch to other channel and flush it */
551 if (devpriv->dma_current == devpriv->dma0) { 537 dma->cur_dma = 1 - dma->cur_dma;
552 devpriv->dma_current = devpriv->dma1; 538 desc = &dma->desc[dma->cur_dma];
553 devpriv->dma_current_buf = devpriv->ai_buf1; 539 das1800_flush_dma_channel(dev, s, desc);
554 } else {
555 devpriv->dma_current = devpriv->dma0;
556 devpriv->dma_current_buf = devpriv->ai_buf0;
557 }
558 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
559 devpriv->dma_current_buf);
560 } 540 }
561 541
562 release_dma_lock(flags);
563
564 /* get any remaining samples in fifo */ 542 /* get any remaining samples in fifo */
565 das1800_handle_fifo_not_empty(dev, s); 543 das1800_handle_fifo_not_empty(dev, s);
566} 544}
@@ -569,47 +547,41 @@ static void das1800_handle_dma(struct comedi_device *dev,
569 struct comedi_subdevice *s, unsigned int status) 547 struct comedi_subdevice *s, unsigned int status)
570{ 548{
571 struct das1800_private *devpriv = dev->private; 549 struct das1800_private *devpriv = dev->private;
572 unsigned long flags; 550 struct comedi_isadma *dma = devpriv->dma;
551 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
573 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 552 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
574 553
575 flags = claim_dma_lock(); 554 das1800_flush_dma_channel(dev, s, desc);
576 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 555
577 devpriv->dma_current_buf); 556 /* re-enable dma channel */
578 /* re-enable dma channel */ 557 comedi_isadma_program(desc);
579 set_dma_addr(devpriv->dma_current,
580 virt_to_bus(devpriv->dma_current_buf));
581 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
582 enable_dma(devpriv->dma_current);
583 release_dma_lock(flags);
584 558
585 if (status & DMATC) { 559 if (status & DMATC) {
586 /* clear DMATC interrupt bit */ 560 /* clear DMATC interrupt bit */
587 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 561 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
588 /* switch dma channels for next time, if appropriate */ 562 /* switch dma channels for next time, if appropriate */
589 if (dual_dma) { 563 if (dual_dma)
590 /* read data from the other channel next time */ 564 dma->cur_dma = 1 - dma->cur_dma;
591 if (devpriv->dma_current == devpriv->dma0) {
592 devpriv->dma_current = devpriv->dma1;
593 devpriv->dma_current_buf = devpriv->ai_buf1;
594 } else {
595 devpriv->dma_current = devpriv->dma0;
596 devpriv->dma_current_buf = devpriv->ai_buf0;
597 }
598 }
599 } 565 }
600} 566}
601 567
602static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 568static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
603{ 569{
604 struct das1800_private *devpriv = dev->private; 570 struct das1800_private *devpriv = dev->private;
571 struct comedi_isadma *dma = devpriv->dma;
572 struct comedi_isadma_desc *desc;
573 int i;
605 574
606 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 575 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
607 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 576 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
608 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 577 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
609 if (devpriv->dma0) 578
610 disable_dma(devpriv->dma0); 579 for (i = 0; i < 2; i++) {
611 if (devpriv->dma1) 580 desc = &dma->desc[i];
612 disable_dma(devpriv->dma1); 581 if (desc->chan)
582 comedi_isadma_disable(desc->chan);
583 }
584
613 return 0; 585 return 0;
614} 586}
615 587
@@ -639,7 +611,7 @@ static void das1800_ai_handler(struct comedi_device *dev)
639 /* clear OVF interrupt bit */ 611 /* clear OVF interrupt bit */
640 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 612 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
641 dev_err(dev->class_dev, "FIFO overflow\n"); 613 dev_err(dev->class_dev, "FIFO overflow\n");
642 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 614 async->events |= COMEDI_CB_ERROR;
643 comedi_handle_events(dev, s); 615 comedi_handle_events(dev, s);
644 return; 616 return;
645 } 617 }
@@ -963,79 +935,64 @@ static void das1800_setup_counters(struct comedi_device *dev,
963 } 935 }
964} 936}
965 937
966/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 938static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
967static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd) 939 struct comedi_subdevice *s,
940 unsigned int maxbytes,
941 unsigned int ns)
968{ 942{
969 unsigned int size = DMA_BUF_SIZE; 943 struct comedi_cmd *cmd = &s->async->cmd;
970 static const int sample_size = 2; /* size in bytes of one sample from board */ 944 unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
971 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 945 unsigned int samples;
972 unsigned int max_size; /* maximum size we will allow for a transfer */ 946
947 samples = max_samples;
973 948
974 /* make dma buffer fill in 0.3 seconds for timed modes */ 949 /* for timed modes, make dma buffer fill in 'ns' time */
975 switch (cmd->scan_begin_src) { 950 switch (cmd->scan_begin_src) {
976 case TRIG_FOLLOW: /* not in burst mode */ 951 case TRIG_FOLLOW: /* not in burst mode */
977 if (cmd->convert_src == TRIG_TIMER) 952 if (cmd->convert_src == TRIG_TIMER)
978 size = (fill_time / cmd->convert_arg) * sample_size; 953 samples = ns / cmd->convert_arg;
979 break; 954 break;
980 case TRIG_TIMER: 955 case TRIG_TIMER:
981 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 956 samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
982 sample_size;
983 break;
984 default:
985 size = DMA_BUF_SIZE;
986 break; 957 break;
987 } 958 }
988 959
989 /* set a minimum and maximum size allowed */ 960 /* limit samples to what is remaining in the command */
990 max_size = DMA_BUF_SIZE; 961 samples = comedi_nsamples_left(s, samples);
991 /* if we are taking limited number of conversions, limit transfer size to that */
992 if (cmd->stop_src == TRIG_COUNT &&
993 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
994 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
995 962
996 if (size > max_size) 963 if (samples > max_samples)
997 size = max_size; 964 samples = max_samples;
998 if (size < sample_size) 965 if (samples < 1)
999 size = sample_size; 966 samples = 1;
1000 967
1001 return size; 968 return comedi_samples_to_bytes(s, samples);
1002} 969}
1003 970
1004/* sets up dma */ 971static void das1800_ai_setup_dma(struct comedi_device *dev,
1005static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) 972 struct comedi_subdevice *s)
1006{ 973{
1007 struct das1800_private *devpriv = dev->private; 974 struct das1800_private *devpriv = dev->private;
1008 unsigned long lock_flags; 975 struct comedi_isadma *dma = devpriv->dma;
1009 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 976 struct comedi_isadma_desc *desc = &dma->desc[0];
977 unsigned int bytes;
1010 978
1011 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 979 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1012 return; 980 return;
1013 981
1014 /* determine a reasonable dma transfer size */ 982 dma->cur_dma = 0;
1015 devpriv->dma_transfer_size = suggest_transfer_size(cmd); 983
1016 lock_flags = claim_dma_lock(); 984 /* determine a dma transfer size to fill buffer in 0.3 sec */
1017 disable_dma(devpriv->dma0); 985 bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
1018 /* clear flip-flop to make sure 2-byte registers for 986
1019 * count and address get set correctly */ 987 desc->size = bytes;
1020 clear_dma_ff(devpriv->dma0); 988 comedi_isadma_program(desc);
1021 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 989
1022 /* set appropriate size of transfer */ 990 /* set up dual dma if appropriate */
1023 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 991 if (devpriv->irq_dma_bits & DMA_DUAL) {
1024 devpriv->dma_current = devpriv->dma0; 992 desc = &dma->desc[1];
1025 devpriv->dma_current_buf = devpriv->ai_buf0; 993 desc->size = bytes;
1026 enable_dma(devpriv->dma0); 994 comedi_isadma_program(desc);
1027 /* set up dual dma if appropriate */
1028 if (dual_dma) {
1029 disable_dma(devpriv->dma1);
1030 /* clear flip-flop to make sure 2-byte registers for
1031 * count and address get set correctly */
1032 clear_dma_ff(devpriv->dma1);
1033 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1034 /* set appropriate size of transfer */
1035 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1036 enable_dma(devpriv->dma1);
1037 } 995 }
1038 release_dma_lock(lock_flags);
1039} 996}
1040 997
1041/* programs channel/gain list into card */ 998/* programs channel/gain list into card */
@@ -1097,7 +1054,7 @@ static int das1800_ai_do_cmd(struct comedi_device *dev,
1097 /* setup card and start */ 1054 /* setup card and start */
1098 program_chanlist(dev, cmd); 1055 program_chanlist(dev, cmd);
1099 das1800_setup_counters(dev, cmd); 1056 das1800_setup_counters(dev, cmd);
1100 setup_dma(dev, cmd); 1057 das1800_ai_setup_dma(dev, s);
1101 outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1058 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1102 /* set conversion rate and length for burst mode */ 1059 /* set conversion rate and length for burst mode */
1103 if (control_c & BMDE) { 1060 if (control_c & BMDE) {
@@ -1234,79 +1191,57 @@ static int das1800_do_wbits(struct comedi_device *dev,
1234 return insn->n; 1191 return insn->n;
1235} 1192}
1236 1193
1237static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, 1194static void das1800_init_dma(struct comedi_device *dev,
1238 unsigned int dma1) 1195 struct comedi_devconfig *it)
1239{ 1196{
1240 struct das1800_private *devpriv = dev->private; 1197 struct das1800_private *devpriv = dev->private;
1241 unsigned long flags; 1198 unsigned int *dma_chan;
1242 1199
1243 /* need an irq to do dma */ 1200 /*
1244 if (dev->irq && dma0) { 1201 * it->options[2] is DMA channel 0
1245 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ 1202 * it->options[3] is DMA channel 1
1246 switch ((dma0 & 0x7) | (dma1 << 4)) { 1203 *
1247 case 0x5: /* dma0 == 5 */ 1204 * Encode the DMA channels into 2 digit hexadecimal for switch.
1248 devpriv->dma_bits |= DMA_CH5; 1205 */
1249 break; 1206 dma_chan = &it->options[2];
1250 case 0x6: /* dma0 == 6 */ 1207
1251 devpriv->dma_bits |= DMA_CH6; 1208 switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
1252 break; 1209 case 0x5: /* dma0 == 5 */
1253 case 0x7: /* dma0 == 7 */ 1210 devpriv->dma_bits = DMA_CH5;
1254 devpriv->dma_bits |= DMA_CH7; 1211 break;
1255 break; 1212 case 0x6: /* dma0 == 6 */
1256 case 0x65: /* dma0 == 5, dma1 == 6 */ 1213 devpriv->dma_bits = DMA_CH6;
1257 devpriv->dma_bits |= DMA_CH5_CH6; 1214 break;
1258 break; 1215 case 0x7: /* dma0 == 7 */
1259 case 0x76: /* dma0 == 6, dma1 == 7 */ 1216 devpriv->dma_bits = DMA_CH7;
1260 devpriv->dma_bits |= DMA_CH6_CH7; 1217 break;
1261 break; 1218 case 0x65: /* dma0 == 5, dma1 == 6 */
1262 case 0x57: /* dma0 == 7, dma1 == 5 */ 1219 devpriv->dma_bits = DMA_CH5_CH6;
1263 devpriv->dma_bits |= DMA_CH7_CH5; 1220 break;
1264 break; 1221 case 0x76: /* dma0 == 6, dma1 == 7 */
1265 default: 1222 devpriv->dma_bits = DMA_CH6_CH7;
1266 dev_err(dev->class_dev, 1223 break;
1267 "only supports dma channels 5 through 7\n"); 1224 case 0x57: /* dma0 == 7, dma1 == 5 */
1268 dev_err(dev->class_dev, 1225 devpriv->dma_bits = DMA_CH7_CH5;
1269 "Dual dma only allows the following combinations:\n"); 1226 break;
1270 dev_err(dev->class_dev, 1227 default:
1271 "dma 5,6 / 6,7 / or 7,5\n"); 1228 return;
1272 return -EINVAL;
1273 }
1274 if (request_dma(dma0, dev->driver->driver_name)) {
1275 dev_err(dev->class_dev,
1276 "failed to allocate dma channel %i\n", dma0);
1277 return -EINVAL;
1278 }
1279 devpriv->dma0 = dma0;
1280 devpriv->dma_current = dma0;
1281 if (dma1) {
1282 if (request_dma(dma1, dev->driver->driver_name)) {
1283 dev_err(dev->class_dev,
1284 "failed to allocate dma channel %i\n",
1285 dma1);
1286 return -EINVAL;
1287 }
1288 devpriv->dma1 = dma1;
1289 }
1290 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1291 if (devpriv->ai_buf0 == NULL)
1292 return -ENOMEM;
1293 devpriv->dma_current_buf = devpriv->ai_buf0;
1294 if (dma1) {
1295 devpriv->ai_buf1 =
1296 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1297 if (devpriv->ai_buf1 == NULL)
1298 return -ENOMEM;
1299 }
1300 flags = claim_dma_lock();
1301 disable_dma(devpriv->dma0);
1302 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1303 if (dma1) {
1304 disable_dma(devpriv->dma1);
1305 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1306 }
1307 release_dma_lock(flags);
1308 } 1229 }
1309 return 0; 1230
1231 /* DMA can use 1 or 2 buffers, each with a separate channel */
1232 devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
1233 dma_chan[0], dma_chan[1],
1234 DMA_BUF_SIZE, COMEDI_ISADMA_READ);
1235 if (!devpriv->dma)
1236 devpriv->dma_bits = 0;
1237}
1238
1239static void das1800_free_dma(struct comedi_device *dev)
1240{
1241 struct das1800_private *devpriv = dev->private;
1242
1243 if (devpriv)
1244 comedi_isadma_free(devpriv->dma);
1310} 1245}
1311 1246
1312static int das1800_probe(struct comedi_device *dev) 1247static int das1800_probe(struct comedi_device *dev)
@@ -1374,8 +1309,6 @@ static int das1800_attach(struct comedi_device *dev,
1374 struct das1800_private *devpriv; 1309 struct das1800_private *devpriv;
1375 struct comedi_subdevice *s; 1310 struct comedi_subdevice *s;
1376 unsigned int irq = it->options[1]; 1311 unsigned int irq = it->options[1];
1377 unsigned int dma0 = it->options[2];
1378 unsigned int dma1 = it->options[3];
1379 int board; 1312 int board;
1380 int ret; 1313 int ret;
1381 1314
@@ -1437,16 +1370,13 @@ static int das1800_attach(struct comedi_device *dev,
1437 } 1370 }
1438 } 1371 }
1439 1372
1440 ret = das1800_init_dma(dev, dma0, dma1); 1373 /* an irq and one dma channel is required to use dma */
1441 if (ret < 0) 1374 if (dev->irq & it->options[2])
1442 return ret; 1375 das1800_init_dma(dev, it);
1443 1376
1444 if (devpriv->ai_buf0 == NULL) { 1377 devpriv->fifo_buf = kmalloc_array(FIFO_SIZE, sizeof(uint16_t), GFP_KERNEL);
1445 devpriv->ai_buf0 = 1378 if (!devpriv->fifo_buf)
1446 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 1379 return -ENOMEM;
1447 if (devpriv->ai_buf0 == NULL)
1448 return -ENOMEM;
1449 }
1450 1380
1451 ret = comedi_alloc_subdevices(dev, 4); 1381 ret = comedi_alloc_subdevices(dev, 4);
1452 if (ret) 1382 if (ret)
@@ -1523,13 +1453,9 @@ static void das1800_detach(struct comedi_device *dev)
1523{ 1453{
1524 struct das1800_private *devpriv = dev->private; 1454 struct das1800_private *devpriv = dev->private;
1525 1455
1456 das1800_free_dma(dev);
1526 if (devpriv) { 1457 if (devpriv) {
1527 if (devpriv->dma0) 1458 kfree(devpriv->fifo_buf);
1528 free_dma(devpriv->dma0);
1529 if (devpriv->dma1)
1530 free_dma(devpriv->dma1);
1531 kfree(devpriv->ai_buf0);
1532 kfree(devpriv->ai_buf1);
1533 if (devpriv->iobase2) 1459 if (devpriv->iobase2)
1534 release_region(devpriv->iobase2, DAS1800_SIZE); 1460 release_region(devpriv->iobase2, DAS1800_SIZE);
1535 } 1461 }
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 780f4f646ea0..b8755b50a11e 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -20,8 +20,8 @@
20/* 20/*
21 * Driver: das6402 21 * Driver: das6402
22 * Description: Keithley Metrabyte DAS6402 (& compatibles) 22 * Description: Keithley Metrabyte DAS6402 (& compatibles)
23 * Devices: (Keithley Metrabyte) DAS6402-12 (das6402-12) 23 * Devices: [Keithley Metrabyte] DAS6402-12 (das6402-12),
24 * (Keithley Metrabyte) DAS6402-16 (das6402-16) 24 * DAS6402-16 (das6402-16)
25 * Author: H Hartley Sweeten <hsweeten@visionengravers.com> 25 * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
26 * Updated: Fri, 14 Mar 2014 10:18:43 -0700 26 * Updated: Fri, 14 Mar 2014 10:18:43 -0700
27 * Status: unknown 27 * Status: unknown
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index e5bdc2423445..ff7f4be3f314 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -511,7 +511,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
511 511
512 if (fifo_overflow) { 512 if (fifo_overflow) {
513 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 513 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
514 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 514 async->events |= COMEDI_CB_ERROR;
515 comedi_handle_events(dev, s); 515 comedi_handle_events(dev, s);
516 return IRQ_HANDLED; 516 return IRQ_HANDLED;
517 } 517 }
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 6df298a99cc6..1af006609fc1 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -19,7 +19,7 @@
19/* 19/*
20 * Driver: dmm32at 20 * Driver: dmm32at
21 * Description: Diamond Systems Diamond-MM-32-AT 21 * Description: Diamond Systems Diamond-MM-32-AT
22 * Devices: (Diamond Systems) Diamond-MM-32-AT [dmm32at] 22 * Devices: [Diamond Systems] Diamond-MM-32-AT (dmm32at)
23 * Author: Perry J. Piplani <perry.j.piplani@nasa.gov> 23 * Author: Perry J. Piplani <perry.j.piplani@nasa.gov>
24 * Updated: Fri Jun 4 09:13:24 CDT 2004 24 * Updated: Fri Jun 4 09:13:24 CDT 2004
25 * Status: experimental 25 * Status: experimental
@@ -365,7 +365,7 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
365 /* enable the ai conversion interrupt and the clock to start scans */ 365 /* enable the ai conversion interrupt and the clock to start scans */
366 outb(DMM32AT_INTCLK_ADINT | 366 outb(DMM32AT_INTCLK_ADINT |
367 DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL, 367 DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL,
368 dev->iobase + DMM32AT_INTCLK_REG); 368 dev->iobase + DMM32AT_INTCLK_REG);
369} 369}
370 370
371static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 371static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 2be98bb9a809..db21d2135856 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -20,22 +20,12 @@
20 * Driver: dt282x 20 * Driver: dt282x
21 * Description: Data Translation DT2821 series (including DT-EZ) 21 * Description: Data Translation DT2821 series (including DT-EZ)
22 * Author: ds 22 * Author: ds
23 * Devices: (Data Translation) DT2821 [dt2821] 23 * Devices: [Data Translation] DT2821 (dt2821), DT2821-F-16SE (dt2821-f),
24 * (Data Translation) DT2821-F-16SE [dt2821-f] 24 * DT2821-F-8DI (dt2821-f), DT2821-G-16SE (dt2821-g),
25 * (Data Translation) DT2821-F-8DI [dt2821-f] 25 * DT2821-G-8DI (dt2821-g), DT2823 (dt2823), DT2824-PGH (dt2824-pgh),
26 * (Data Translation) DT2821-G-16SE [dt2821-g] 26 * DT2824-PGL (dt2824-pgl), DT2825 (dt2825), DT2827 (dt2827),
27 * (Data Translation) DT2821-G-8DI [dt2821-g] 27 * DT2828 (dt2828), DT2928 (dt2829), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
28 * (Data Translation) DT2823 [dt2823] 28 * DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
29 * (Data Translation) DT2824-PGH [dt2824-pgh]
30 * (Data Translation) DT2824-PGL [dt2824-pgl]
31 * (Data Translation) DT2825 [dt2825]
32 * (Data Translation) DT2827 [dt2827]
33 * (Data Translation) DT2828 [dt2828]
34 * (Data Translation) DT2928 [dt2829]
35 * (Data Translation) DT21-EZ [dt21-ez]
36 * (Data Translation) DT23-EZ [dt23-ez]
37 * (Data Translation) DT24-EZ [dt24-ez]
38 * (Data Translation) DT24-EZ-PGL [dt24-ez-pgl]
39 * Status: complete 29 * Status: complete
40 * Updated: Wed, 22 Aug 2001 17:11:34 -0700 30 * Updated: Wed, 22 Aug 2001 17:11:34 -0700
41 * 31 *
@@ -66,15 +56,14 @@
66 */ 56 */
67 57
68#include <linux/module.h> 58#include <linux/module.h>
69#include "../comedidev.h"
70
71#include <linux/delay.h> 59#include <linux/delay.h>
72#include <linux/gfp.h> 60#include <linux/gfp.h>
73#include <linux/interrupt.h> 61#include <linux/interrupt.h>
74#include <linux/io.h> 62#include <linux/io.h>
75 63
76#include <asm/dma.h> 64#include "../comedidev.h"
77 65
66#include "comedi_isadma.h"
78#include "comedi_fc.h" 67#include "comedi_fc.h"
79 68
80/* 69/*
@@ -311,55 +300,36 @@ static const struct dt282x_board boardtypes[] = {
311}; 300};
312 301
313struct dt282x_private { 302struct dt282x_private {
303 struct comedi_isadma *dma;
314 unsigned int ad_2scomp:1; 304 unsigned int ad_2scomp:1;
315
316 unsigned int divisor; 305 unsigned int divisor;
317
318 int dacsr; /* software copies of registers */ 306 int dacsr; /* software copies of registers */
319 int adcsr; 307 int adcsr;
320 int supcsr; 308 int supcsr;
321
322 int ntrig; 309 int ntrig;
323 int nread; 310 int nread;
324
325 struct {
326 int chan;
327 unsigned short *buf; /* DMA buffer */
328 int size; /* size of current transfer */
329 } dma[2];
330 int dma_maxsize; /* max size of DMA transfer (in bytes) */
331 int current_dma_index;
332 int dma_dir; 311 int dma_dir;
333}; 312};
334 313
335static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n) 314static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
336{ 315{
337 struct dt282x_private *devpriv = dev->private; 316 struct dt282x_private *devpriv = dev->private;
338 int dma_chan; 317 struct comedi_isadma *dma = devpriv->dma;
339 unsigned long dma_ptr; 318 struct comedi_isadma_desc *desc = &dma->desc[dma_index];
340 unsigned long flags;
341 319
342 if (!devpriv->ntrig) 320 if (!devpriv->ntrig)
343 return 0; 321 return 0;
344 322
345 if (n == 0) 323 if (n == 0)
346 n = devpriv->dma_maxsize; 324 n = desc->maxsize;
347 if (n > devpriv->ntrig * 2) 325 if (n > devpriv->ntrig * 2)
348 n = devpriv->ntrig * 2; 326 n = devpriv->ntrig * 2;
349 devpriv->ntrig -= n / 2; 327 devpriv->ntrig -= n / 2;
350 328
351 devpriv->dma[dma_index].size = n; 329 desc->size = n;
352 dma_chan = devpriv->dma[dma_index].chan; 330 comedi_isadma_set_mode(desc, devpriv->dma_dir);
353 dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
354
355 set_dma_mode(dma_chan, DMA_MODE_READ);
356 flags = claim_dma_lock();
357 clear_dma_ff(dma_chan);
358 set_dma_addr(dma_chan, dma_ptr);
359 set_dma_count(dma_chan, n);
360 release_dma_lock(flags);
361 331
362 enable_dma(dma_chan); 332 comedi_isadma_program(desc);
363 333
364 return n; 334 return n;
365} 335}
@@ -367,22 +337,13 @@ static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
367static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n) 337static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
368{ 338{
369 struct dt282x_private *devpriv = dev->private; 339 struct dt282x_private *devpriv = dev->private;
370 int dma_chan; 340 struct comedi_isadma *dma = devpriv->dma;
371 unsigned long dma_ptr; 341 struct comedi_isadma_desc *desc = &dma->desc[dma_index];
372 unsigned long flags;
373 342
374 devpriv->dma[dma_index].size = n; 343 desc->size = n;
375 dma_chan = devpriv->dma[dma_index].chan; 344 comedi_isadma_set_mode(desc, devpriv->dma_dir);
376 dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
377 345
378 set_dma_mode(dma_chan, DMA_MODE_WRITE); 346 comedi_isadma_program(desc);
379 flags = claim_dma_lock();
380 clear_dma_ff(dma_chan);
381 set_dma_addr(dma_chan, dma_ptr);
382 set_dma_count(dma_chan, n);
383 release_dma_lock(flags);
384
385 enable_dma(dma_chan);
386 347
387 return n; 348 return n;
388} 349}
@@ -390,9 +351,14 @@ static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
390static void dt282x_disable_dma(struct comedi_device *dev) 351static void dt282x_disable_dma(struct comedi_device *dev)
391{ 352{
392 struct dt282x_private *devpriv = dev->private; 353 struct dt282x_private *devpriv = dev->private;
354 struct comedi_isadma *dma = devpriv->dma;
355 struct comedi_isadma_desc *desc;
356 int i;
393 357
394 disable_dma(devpriv->dma[0].chan); 358 for (i = 0; i < 2; i++) {
395 disable_dma(devpriv->dma[1].chan); 359 desc = &dma->desc[i];
360 comedi_isadma_disable(desc->chan);
361 }
396} 362}
397 363
398static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags) 364static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
@@ -454,11 +420,12 @@ static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev,
454 int cur_dma) 420 int cur_dma)
455{ 421{
456 struct dt282x_private *devpriv = dev->private; 422 struct dt282x_private *devpriv = dev->private;
457 void *ptr = devpriv->dma[cur_dma].buf; 423 struct comedi_isadma *dma = devpriv->dma;
458 unsigned int nsamples = comedi_bytes_to_samples(s, devpriv->dma_maxsize); 424 struct comedi_isadma_desc *desc = &dma->desc[cur_dma];
425 unsigned int nsamples = comedi_bytes_to_samples(s, desc->maxsize);
459 unsigned int nbytes; 426 unsigned int nbytes;
460 427
461 nbytes = comedi_buf_read_samples(s, ptr, nsamples); 428 nbytes = comedi_buf_read_samples(s, desc->virt_addr, nsamples);
462 if (nbytes) 429 if (nbytes)
463 dt282x_prep_ao_dma(dev, cur_dma, nbytes); 430 dt282x_prep_ao_dma(dev, cur_dma, nbytes);
464 else 431 else
@@ -471,39 +438,37 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
471 struct comedi_subdevice *s) 438 struct comedi_subdevice *s)
472{ 439{
473 struct dt282x_private *devpriv = dev->private; 440 struct dt282x_private *devpriv = dev->private;
474 int cur_dma = devpriv->current_dma_index; 441 struct comedi_isadma *dma = devpriv->dma;
442 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
475 443
476 outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, 444 outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
477 dev->iobase + DT2821_SUPCSR_REG); 445 dev->iobase + DT2821_SUPCSR_REG);
478 446
479 disable_dma(devpriv->dma[cur_dma].chan); 447 comedi_isadma_disable(desc->chan);
480
481 devpriv->current_dma_index = 1 - cur_dma;
482 448
483 if (!dt282x_ao_setup_dma(dev, s, cur_dma)) 449 if (!dt282x_ao_setup_dma(dev, s, dma->cur_dma))
484 s->async->events |= COMEDI_CB_OVERFLOW; 450 s->async->events |= COMEDI_CB_OVERFLOW;
451
452 dma->cur_dma = 1 - dma->cur_dma;
485} 453}
486 454
487static void dt282x_ai_dma_interrupt(struct comedi_device *dev, 455static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
488 struct comedi_subdevice *s) 456 struct comedi_subdevice *s)
489{ 457{
490 struct dt282x_private *devpriv = dev->private; 458 struct dt282x_private *devpriv = dev->private;
491 int cur_dma = devpriv->current_dma_index; 459 struct comedi_isadma *dma = devpriv->dma;
492 void *ptr = devpriv->dma[cur_dma].buf; 460 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
493 int size = devpriv->dma[cur_dma].size; 461 unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
494 unsigned int nsamples = comedi_bytes_to_samples(s, size);
495 int ret; 462 int ret;
496 463
497 outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, 464 outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
498 dev->iobase + DT2821_SUPCSR_REG); 465 dev->iobase + DT2821_SUPCSR_REG);
499 466
500 disable_dma(devpriv->dma[cur_dma].chan); 467 comedi_isadma_disable(desc->chan);
501
502 devpriv->current_dma_index = 1 - cur_dma;
503 468
504 dt282x_munge(dev, s, ptr, size); 469 dt282x_munge(dev, s, desc->virt_addr, desc->size);
505 ret = comedi_buf_write_samples(s, ptr, nsamples); 470 ret = comedi_buf_write_samples(s, desc->virt_addr, nsamples);
506 if (ret != size) 471 if (ret != desc->size)
507 return; 472 return;
508 473
509 devpriv->nread -= nsamples; 474 devpriv->nread -= nsamples;
@@ -524,7 +489,9 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
524 } 489 }
525#endif 490#endif
526 /* restart the channel */ 491 /* restart the channel */
527 dt282x_prep_ai_dma(dev, cur_dma, 0); 492 dt282x_prep_ai_dma(dev, dma->cur_dma, 0);
493
494 dma->cur_dma = 1 - dma->cur_dma;
528} 495}
529 496
530static irqreturn_t dt282x_interrupt(int irq, void *d) 497static irqreturn_t dt282x_interrupt(int irq, void *d)
@@ -545,7 +512,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
545 dacsr = inw(dev->iobase + DT2821_DACSR_REG); 512 dacsr = inw(dev->iobase + DT2821_DACSR_REG);
546 supcsr = inw(dev->iobase + DT2821_SUPCSR_REG); 513 supcsr = inw(dev->iobase + DT2821_SUPCSR_REG);
547 if (supcsr & DT2821_SUPCSR_DMAD) { 514 if (supcsr & DT2821_SUPCSR_DMAD) {
548 if (devpriv->dma_dir == DMA_MODE_READ) 515 if (devpriv->dma_dir == COMEDI_ISADMA_READ)
549 dt282x_ai_dma_interrupt(dev, s); 516 dt282x_ai_dma_interrupt(dev, s);
550 else 517 else
551 dt282x_ao_dma_interrupt(dev, s_ao); 518 dt282x_ao_dma_interrupt(dev, s_ao);
@@ -718,14 +685,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
718 685
719 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 686 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
720 687
721 if (cmd->scan_begin_src == TRIG_FOLLOW) { 688 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
722 /* internal trigger */
723 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
724 } else {
725 /* external trigger */
726 /* should be level/edge, hi/lo specification here */
727 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
728 }
729 689
730 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 4000); 690 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 4000);
731 691
@@ -757,6 +717,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
757static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 717static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
758{ 718{
759 struct dt282x_private *devpriv = dev->private; 719 struct dt282x_private *devpriv = dev->private;
720 struct comedi_isadma *dma = devpriv->dma;
760 struct comedi_cmd *cmd = &s->async->cmd; 721 struct comedi_cmd *cmd = &s->async->cmd;
761 int ret; 722 int ret;
762 723
@@ -778,8 +739,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
778 devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg; 739 devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
779 devpriv->nread = devpriv->ntrig; 740 devpriv->nread = devpriv->ntrig;
780 741
781 devpriv->dma_dir = DMA_MODE_READ; 742 devpriv->dma_dir = COMEDI_ISADMA_READ;
782 devpriv->current_dma_index = 0; 743 dma->cur_dma = 0;
783 dt282x_prep_ai_dma(dev, 0, 0); 744 dt282x_prep_ai_dma(dev, 0, 0);
784 if (devpriv->ntrig) { 745 if (devpriv->ntrig) {
785 dt282x_prep_ai_dma(dev, 1, 0); 746 dt282x_prep_ai_dma(dev, 1, 0);
@@ -942,6 +903,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
942static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 903static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
943{ 904{
944 struct dt282x_private *devpriv = dev->private; 905 struct dt282x_private *devpriv = dev->private;
906 struct comedi_isadma *dma = devpriv->dma;
945 struct comedi_cmd *cmd = &s->async->cmd; 907 struct comedi_cmd *cmd = &s->async->cmd;
946 908
947 dt282x_disable_dma(dev); 909 dt282x_disable_dma(dev);
@@ -958,8 +920,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
958 devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len; 920 devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
959 devpriv->nread = devpriv->ntrig; 921 devpriv->nread = devpriv->ntrig;
960 922
961 devpriv->dma_dir = DMA_MODE_WRITE; 923 devpriv->dma_dir = COMEDI_ISADMA_WRITE;
962 devpriv->current_dma_index = 0; 924 dma->cur_dma = 0;
963 925
964 outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG); 926 outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
965 927
@@ -1063,46 +1025,42 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
1063 return ai_range_table[x]; 1025 return ai_range_table[x];
1064} 1026}
1065 1027
1066static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) 1028static void dt282x_alloc_dma(struct comedi_device *dev,
1029 struct comedi_devconfig *it)
1067{ 1030{
1068 struct dt282x_private *devpriv = dev->private; 1031 struct dt282x_private *devpriv = dev->private;
1069 int ret; 1032 unsigned int irq_num = it->options[1];
1033 unsigned int dma_chan[2];
1070 1034
1071 ret = request_dma(dma1, "dt282x A"); 1035 if (it->options[2] < it->options[3]) {
1072 if (ret) 1036 dma_chan[0] = it->options[2];
1073 return -EBUSY; 1037 dma_chan[1] = it->options[3];
1074 devpriv->dma[0].chan = dma1; 1038 } else {
1039 dma_chan[0] = it->options[3];
1040 dma_chan[1] = it->options[2];
1041 }
1075 1042
1076 ret = request_dma(dma2, "dt282x B"); 1043 if (!irq_num || dma_chan[0] == dma_chan[1] ||
1077 if (ret) 1044 dma_chan[0] < 5 || dma_chan[0] > 7 ||
1078 return -EBUSY; 1045 dma_chan[1] < 5 || dma_chan[1] > 7)
1079 devpriv->dma[1].chan = dma2; 1046 return;
1080 1047
1081 devpriv->dma_maxsize = PAGE_SIZE; 1048 if (request_irq(irq_num, dt282x_interrupt, 0, dev->board_name, dev))
1082 devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); 1049 return;
1083 devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
1084 if (!devpriv->dma[0].buf || !devpriv->dma[1].buf)
1085 return -ENOMEM;
1086 1050
1087 return 0; 1051 /* DMA uses two 4K buffers with separate DMA channels */
1052 devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan[0], dma_chan[1],
1053 PAGE_SIZE, 0);
1054 if (!devpriv->dma)
1055 free_irq(irq_num, dev);
1088} 1056}
1089 1057
1090static void dt282x_free_dma(struct comedi_device *dev) 1058static void dt282x_free_dma(struct comedi_device *dev)
1091{ 1059{
1092 struct dt282x_private *devpriv = dev->private; 1060 struct dt282x_private *devpriv = dev->private;
1093 int i;
1094
1095 if (!devpriv)
1096 return;
1097 1061
1098 for (i = 0; i < 2; i++) { 1062 if (devpriv)
1099 if (devpriv->dma[i].chan) 1063 comedi_isadma_free(devpriv->dma);
1100 free_dma(devpriv->dma[i].chan);
1101 if (devpriv->dma[i].buf)
1102 free_page((unsigned long)devpriv->dma[i].buf);
1103 devpriv->dma[i].chan = 0;
1104 devpriv->dma[i].buf = NULL;
1105 }
1106} 1064}
1107 1065
1108static int dt282x_initialize(struct comedi_device *dev) 1066static int dt282x_initialize(struct comedi_device *dev)
@@ -1160,36 +1118,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1160 return -ENOMEM; 1118 return -ENOMEM;
1161 1119
1162 /* an IRQ and 2 DMA channels are required for async command support */ 1120 /* an IRQ and 2 DMA channels are required for async command support */
1163 if (it->options[1] && it->options[2] && it->options[3]) { 1121 dt282x_alloc_dma(dev, it);
1164 unsigned int irq = it->options[1];
1165 unsigned int dma1 = it->options[2];
1166 unsigned int dma2 = it->options[3];
1167
1168 if (dma2 < dma1) {
1169 unsigned int swap;
1170
1171 swap = dma1;
1172 dma1 = dma2;
1173 dma2 = swap;
1174 }
1175
1176 if (dma1 != dma2 &&
1177 dma1 >= 5 && dma1 <= 7 &&
1178 dma2 >= 5 && dma2 <= 7) {
1179 ret = request_irq(irq, dt282x_interrupt, 0,
1180 dev->board_name, dev);
1181 if (ret == 0) {
1182 dev->irq = irq;
1183
1184 ret = dt282x_grab_dma(dev, dma1, dma2);
1185 if (ret < 0) {
1186 dt282x_free_dma(dev);
1187 free_irq(dev->irq, dev);
1188 dev->irq = 0;
1189 }
1190 }
1191 }
1192 }
1193 1122
1194 ret = comedi_alloc_subdevices(dev, 3); 1123 ret = comedi_alloc_subdevices(dev, 3);
1195 if (ret) 1124 if (ret)
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 1d9a7a63e06f..0aa51980e327 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -355,7 +355,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d)
355 dt3k_ai_empty_fifo(dev, s); 355 dt3k_ai_empty_fifo(dev, s);
356 356
357 if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) 357 if (status & (DT3000_ADSWERR | DT3000_ADHWERR))
358 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 358 s->async->events |= COMEDI_CB_ERROR;
359 359
360 debug_n_ints++; 360 debug_n_ints++;
361 if (debug_n_ints >= 10) 361 if (debug_n_ints >= 10)
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 06c601d8fdff..e11c216a4c85 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -42,9 +42,8 @@ for my needs.
42#include <linux/module.h> 42#include <linux/module.h>
43#include <linux/errno.h> 43#include <linux/errno.h>
44#include <linux/uaccess.h> 44#include <linux/uaccess.h>
45#include <linux/usb.h>
46 45
47#include "../comedidev.h" 46#include "../comedi_usb.h"
48 47
49#define DT9812_DIAGS_BOARD_INFO_ADDR 0xFBFF 48#define DT9812_DIAGS_BOARD_INFO_ADDR 0xFBFF
50#define DT9812_MAX_WRITE_CMD_PIPE_SIZE 32 49#define DT9812_MAX_WRITE_CMD_PIPE_SIZE 32
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c
index 1b6324c6eb29..6c1e442f6c81 100644
--- a/drivers/staging/comedi/drivers/dyna_pci10xx.c
+++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c
@@ -14,24 +14,23 @@
14 */ 14 */
15 15
16/* 16/*
17 Driver: dyna_pci10xx 17 * Driver: dyna_pci10xx
18 Devices: Dynalog India PCI DAQ Cards, http://www.dynalogindia.com/ 18 * Description: Dynalog India PCI DAQ Cards, http://www.dynalogindia.com/
19 Author: Prashant Shah <pshah.mumbai@gmail.com> 19 * Devices: [Dynalog] PCI-1050 (dyna_pci1050)
20 Developed at Automation Labs, Chemical Dept., IIT Bombay, India. 20 * Author: Prashant Shah <pshah.mumbai@gmail.com>
21 Prof. Kannan Moudgalya <kannan@iitb.ac.in> 21 * Status: Stable
22 http://www.iitb.ac.in 22 *
23 Status: Stable 23 * Developed at Automation Labs, Chemical Dept., IIT Bombay, India.
24 Version: 1.0 24 * Prof. Kannan Moudgalya <kannan@iitb.ac.in>
25 Device Supported : 25 * http://www.iitb.ac.in
26 - Dynalog PCI 1050 26 *
27 27 * Notes :
28 Notes : 28 * - Dynalog India Pvt. Ltd. does not have a registered PCI Vendor ID and
29 - Dynalog India Pvt. Ltd. does not have a registered PCI Vendor ID and 29 * they are using the PLX Technlogies Vendor ID since that is the PCI Chip
30 they are using the PLX Technlogies Vendor ID since that is the PCI Chip used 30 * used in the card.
31 in the card. 31 * - Dynalog India Pvt. Ltd. has provided the internal register specification
32 - Dynalog India Pvt. Ltd. has provided the internal register specification for 32 * for their cards in their manuals.
33 their cards in their manuals. 33 */
34*/
35 34
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/delay.h> 36#include <linux/delay.h>
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 0979f536ed39..deada9784b69 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -261,12 +261,12 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
261 261
262 if (hpdi_board_status & RX_OVERRUN_BIT) { 262 if (hpdi_board_status & RX_OVERRUN_BIT) {
263 dev_err(dev->class_dev, "rx fifo overrun\n"); 263 dev_err(dev->class_dev, "rx fifo overrun\n");
264 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 264 async->events |= COMEDI_CB_ERROR;
265 } 265 }
266 266
267 if (hpdi_board_status & RX_UNDERRUN_BIT) { 267 if (hpdi_board_status & RX_UNDERRUN_BIT) {
268 dev_err(dev->class_dev, "rx fifo underrun\n"); 268 dev_err(dev->class_dev, "rx fifo underrun\n");
269 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 269 async->events |= COMEDI_CB_ERROR;
270 } 270 }
271 271
272 if (devpriv->dio_count == 0) 272 if (devpriv->dio_count == 0)
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 1085d66935fe..0768bc42a5db 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -9,7 +9,7 @@
9/* 9/*
10 * Driver: ii_pci20kc 10 * Driver: ii_pci20kc
11 * Description: Intelligent Instruments PCI-20001C carrier board 11 * Description: Intelligent Instruments PCI-20001C carrier board
12 * Devices: (Intelligent Instrumentation) PCI-20001C [ii_pci20kc] 12 * Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)
13 * Author: Markus Kempf <kempf@matsci.uni-sb.de> 13 * Author: Markus Kempf <kempf@matsci.uni-sb.de>
14 * Status: works 14 * Status: works
15 * 15 *
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
index 20478ae8fad6..356811defaf4 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.h
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -261,8 +261,9 @@ struct intern_transform {
261 } link[8]; 261 } link[8];
262}; 262};
263 263
264/* JR3 force/torque sensor data definition. For more information see sensor and */ 264/* JR3 force/torque sensor data definition. For more information see sensor
265/* hardware manuals. */ 265 * and hardware manuals.
266 */
266 267
267struct jr3_channel { 268struct jr3_channel {
268 /* Raw_channels is the area used to store the raw data coming from */ 269 /* Raw_channels is the area used to store the raw data coming from */
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index 77e94a34b51e..3c19e0f178ca 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -19,7 +19,7 @@
19/* 19/*
20 * Driver: ke_counter 20 * Driver: ke_counter
21 * Description: Driver for Kolter Electronic Counter Card 21 * Description: Driver for Kolter Electronic Counter Card
22 * Devices: (Kolter Electronic) PCI Counter Card [ke_counter] 22 * Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
23 * Author: Michael Hillmann 23 * Author: Michael Hillmann
24 * Updated: Mon, 14 Apr 2008 15:42:42 +0100 24 * Updated: Mon, 14 Apr 2008 15:42:42 +0100
25 * Status: tested 25 * Status: tested
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 915685c1c85c..d120aa244cf9 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -1068,7 +1068,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1068 ME4000_AI_CTRL_BIT_SC_IRQ); 1068 ME4000_AI_CTRL_BIT_SC_IRQ);
1069 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); 1069 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1070 1070
1071 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1071 s->async->events |= COMEDI_CB_ERROR;
1072 1072
1073 dev_err(dev->class_dev, "FIFO overflow\n"); 1073 dev_err(dev->class_dev, "FIFO overflow\n");
1074 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) 1074 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
@@ -1089,7 +1089,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1089 ME4000_AI_CTRL_BIT_SC_IRQ); 1089 ME4000_AI_CTRL_BIT_SC_IRQ);
1090 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); 1090 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1091 1091
1092 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1092 s->async->events |= COMEDI_CB_ERROR;
1093 1093
1094 dev_err(dev->class_dev, "Undefined FIFO state\n"); 1094 dev_err(dev->class_dev, "Undefined FIFO state\n");
1095 } 1095 }
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index b5278c11e622..92e23527f2cb 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: me_daq 20 * Driver: me_daq
21 * Description: Meilhaus PCI data acquisition cards 21 * Description: Meilhaus PCI data acquisition cards
22 * Devices: (Meilhaus) ME-2600i [me-2600i] 22 * Devices: [Meilhaus] ME-2600i (me-2600i), ME-2000i (me-2000i)
23 * (Meilhaus) ME-2000i [me-2000i]
24 * Author: Michael Hillmann <hillmann@syscongroup.de> 23 * Author: Michael Hillmann <hillmann@syscongroup.de>
25 * Status: experimental 24 * Status: experimental
26 * 25 *
@@ -175,7 +174,7 @@ struct me_private_data {
175 174
176static inline void sleep(unsigned sec) 175static inline void sleep(unsigned sec)
177{ 176{
178 current->state = TASK_INTERRUPTIBLE; 177 __set_current_state(TASK_INTERRUPTIBLE);
179 schedule_timeout(sec * HZ); 178 schedule_timeout(sec * HZ);
180} 179}
181 180
diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c
index af21bc180c46..db972bce2b5b 100644
--- a/drivers/staging/comedi/drivers/mf6x4.c
+++ b/drivers/staging/comedi/drivers/mf6x4.c
@@ -18,7 +18,7 @@
18/* 18/*
19 * Driver: mf6x4 19 * Driver: mf6x4
20 * Description: Humusoft MF634 and MF624 Data acquisition card driver 20 * Description: Humusoft MF634 and MF624 Data acquisition card driver
21 * Devices: Humusoft MF634, Humusoft MF624 21 * Devices: [Humusoft] MF634 (mf634), MF624 (mf624)
22 * Author: Rostislav Lisovy <lisovy@gmail.com> 22 * Author: Rostislav Lisovy <lisovy@gmail.com>
23 * Status: works 23 * Status: works
24 * Updated: 24 * Updated:
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index ffc9e61d6cdd..1e537a5cf862 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -494,9 +494,7 @@ EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_ub);
494unsigned mite_dma_tcr(struct mite_channel *mite_chan) 494unsigned mite_dma_tcr(struct mite_channel *mite_chan)
495{ 495{
496 struct mite_struct *mite = mite_chan->mite; 496 struct mite_struct *mite = mite_chan->mite;
497 int lkar;
498 497
499 lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
500 return readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); 498 return readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel));
501} 499}
502EXPORT_SYMBOL_GPL(mite_dma_tcr); 500EXPORT_SYMBOL_GPL(mite_dma_tcr);
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index f99847f3999f..530f716f6586 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: ni_6527 20 * Driver: ni_6527
21 * Description: National Instruments 6527 21 * Description: National Instruments 6527
22 * Devices: (National Instruments) PCI-6527 [pci-6527] 22 * Devices: [National Instruments] PCI-6527 (pci-6527), PXI-6527 (pxi-6527)
23 * (National Instruments) PXI-6527 [pxi-6527]
24 * Author: David A. Schleef <ds@schleef.org> 23 * Author: David A. Schleef <ds@schleef.org>
25 * Updated: Sat, 25 Jan 2003 13:24:40 -0800 24 * Updated: Sat, 25 Jan 2003 13:24:40 -0800
26 * Status: works 25 * Status: works
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index bcb326e31562..67cb758eb0cd 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -25,28 +25,14 @@
25 * Author: Jon Grierson <jd@renko.co.uk>, 25 * Author: Jon Grierson <jd@renko.co.uk>,
26 * Frank Mori Hess <fmhess@users.sourceforge.net> 26 * Frank Mori Hess <fmhess@users.sourceforge.net>
27 * Status: testing 27 * Status: testing
28 * Devices: (National Instruments) PCI-6509 [ni_65xx] 28 * Devices: [National Instruments] PCI-6509 (pci-6509), PXI-6509 (pxi-6509),
29 * (National Instruments) PXI-6509 [ni_65xx] 29 * PCI-6510 (pci-6510), PCI-6511 (pci-6511), PXI-6511 (pxi-6511),
30 * (National Instruments) PCI-6510 [ni_65xx] 30 * PCI-6512 (pci-6512), PXI-6512 (pxi-6512), PCI-6513 (pci-6513),
31 * (National Instruments) PCI-6511 [ni_65xx] 31 * PXI-6513 (pxi-6513), PCI-6514 (pci-6514), PXI-6514 (pxi-6514),
32 * (National Instruments) PXI-6511 [ni_65xx] 32 * PCI-6515 (pxi-6515), PXI-6515 (pxi-6515), PCI-6516 (pci-6516),
33 * (National Instruments) PCI-6512 [ni_65xx] 33 * PCI-6517 (pci-6517), PCI-6518 (pci-6518), PCI-6519 (pci-6519),
34 * (National Instruments) PXI-6512 [ni_65xx] 34 * PCI-6520 (pci-6520), PCI-6521 (pci-6521), PXI-6521 (pxi-6521),
35 * (National Instruments) PCI-6513 [ni_65xx] 35 * PCI-6528 (pci-6528), PXI-6528 (pxi-6528)
36 * (National Instruments) PXI-6513 [ni_65xx]
37 * (National Instruments) PCI-6514 [ni_65xx]
38 * (National Instruments) PXI-6514 [ni_65xx]
39 * (National Instruments) PCI-6515 [ni_65xx]
40 * (National Instruments) PXI-6515 [ni_65xx]
41 * (National Instruments) PCI-6516 [ni_65xx]
42 * (National Instruments) PCI-6517 [ni_65xx]
43 * (National Instruments) PCI-6518 [ni_65xx]
44 * (National Instruments) PCI-6519 [ni_65xx]
45 * (National Instruments) PCI-6520 [ni_65xx]
46 * (National Instruments) PCI-6521 [ni_65xx]
47 * (National Instruments) PXI-6521 [ni_65xx]
48 * (National Instruments) PCI-6528 [ni_65xx]
49 * (National Instruments) PXI-6528 [ni_65xx]
50 * Updated: Mon, 21 Jul 2014 12:49:58 +0000 36 * Updated: Mon, 21 Jul 2014 12:49:58 +0000
51 * 37 *
52 * Configuration Options: not applicable, uses PCI auto config 38 * Configuration Options: not applicable, uses PCI auto config
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 69e543a0bf22..a1ce0b0b8c41 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -62,14 +62,13 @@ TRIG_WAKE_EOS
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/slab.h> 64#include <linux/slab.h>
65#include "../comedidev.h"
66
67#include <linux/io.h> 65#include <linux/io.h>
68 66
69#include <asm/dma.h> 67#include "../comedidev.h"
70 68
71#include "8253.h" 69#include "comedi_isadma.h"
72#include "comedi_fc.h" 70#include "comedi_fc.h"
71#include "8253.h"
73 72
74#define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */ 73#define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
75 74
@@ -146,11 +145,8 @@ static const struct a2150_board a2150_boards[] = {
146}; 145};
147 146
148struct a2150_private { 147struct a2150_private {
149 148 struct comedi_isadma *dma;
150 volatile unsigned int count; /* number of data points left to be taken */ 149 unsigned int count; /* number of data points left to be taken */
151 unsigned int dma; /* dma channel */
152 uint16_t *dma_buffer; /* dma buffer */
153 unsigned int dma_transfer_size; /* size in bytes of dma transfers */
154 int irq_dma_bits; /* irq/dma register bits */ 150 int irq_dma_bits; /* irq/dma register bits */
155 int config_bits; /* config register bits */ 151 int config_bits; /* config register bits */
156}; 152};
@@ -158,68 +154,54 @@ struct a2150_private {
158/* interrupt service routine */ 154/* interrupt service routine */
159static irqreturn_t a2150_interrupt(int irq, void *d) 155static irqreturn_t a2150_interrupt(int irq, void *d)
160{ 156{
161 int i;
162 int status;
163 unsigned long flags;
164 struct comedi_device *dev = d; 157 struct comedi_device *dev = d;
165 struct a2150_private *devpriv = dev->private; 158 struct a2150_private *devpriv = dev->private;
159 struct comedi_isadma *dma = devpriv->dma;
160 struct comedi_isadma_desc *desc = &dma->desc[0];
166 struct comedi_subdevice *s = dev->read_subdev; 161 struct comedi_subdevice *s = dev->read_subdev;
167 struct comedi_async *async; 162 struct comedi_async *async = s->async;
168 struct comedi_cmd *cmd; 163 struct comedi_cmd *cmd = &async->cmd;
164 unsigned short *buf = desc->virt_addr;
169 unsigned int max_points, num_points, residue, leftover; 165 unsigned int max_points, num_points, residue, leftover;
170 unsigned short dpnt; 166 unsigned short dpnt;
167 int status;
168 int i;
171 169
172 if (!dev->attached) { 170 if (!dev->attached)
173 dev_err(dev->class_dev, "premature interrupt\n");
174 return IRQ_HANDLED; 171 return IRQ_HANDLED;
175 }
176 /* initialize async here to make sure s is not NULL */
177 async = s->async;
178 cmd = &async->cmd;
179 172
180 status = inw(dev->iobase + STATUS_REG); 173 status = inw(dev->iobase + STATUS_REG);
181 174 if ((status & INTR_BIT) == 0)
182 if ((status & INTR_BIT) == 0) {
183 dev_err(dev->class_dev, "spurious interrupt\n");
184 return IRQ_NONE; 175 return IRQ_NONE;
185 }
186 176
187 if (status & OVFL_BIT) { 177 if (status & OVFL_BIT) {
188 dev_err(dev->class_dev, "fifo overflow\n"); 178 async->events |= COMEDI_CB_ERROR;
189 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
190 comedi_handle_events(dev, s); 179 comedi_handle_events(dev, s);
191 } 180 }
192 181
193 if ((status & DMA_TC_BIT) == 0) { 182 if ((status & DMA_TC_BIT) == 0) {
194 dev_err(dev->class_dev, 183 async->events |= COMEDI_CB_ERROR;
195 "caught non-dma interrupt? Aborting.\n");
196 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
197 comedi_handle_events(dev, s); 184 comedi_handle_events(dev, s);
198 return IRQ_HANDLED; 185 return IRQ_HANDLED;
199 } 186 }
200 187
201 flags = claim_dma_lock(); 188 /*
202 disable_dma(devpriv->dma); 189 * residue is the number of bytes left to be done on the dma
203 /* clear flip-flop to make sure 2-byte registers for
204 * count and address get set correctly */
205 clear_dma_ff(devpriv->dma);
206
207 /* figure out how many points to read */
208 max_points = comedi_bytes_to_samples(s, devpriv->dma_transfer_size);
209 /* residue is the number of points left to be done on the dma
210 * transfer. It should always be zero at this point unless 190 * transfer. It should always be zero at this point unless
211 * the stop_src is set to external triggering. 191 * the stop_src is set to external triggering.
212 */ 192 */
213 residue = comedi_bytes_to_samples(s, get_dma_residue(devpriv->dma)); 193 residue = comedi_isadma_disable(desc->chan);
214 num_points = max_points - residue; 194
195 /* figure out how many points to read */
196 max_points = comedi_bytes_to_samples(s, desc->size);
197 num_points = max_points - comedi_bytes_to_samples(s, residue);
215 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT) 198 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
216 num_points = devpriv->count; 199 num_points = devpriv->count;
217 200
218 /* figure out how many points will be stored next time */ 201 /* figure out how many points will be stored next time */
219 leftover = 0; 202 leftover = 0;
220 if (cmd->stop_src == TRIG_NONE) { 203 if (cmd->stop_src == TRIG_NONE) {
221 leftover = comedi_bytes_to_samples(s, 204 leftover = comedi_bytes_to_samples(s, desc->size);
222 devpriv->dma_transfer_size);
223 } else if (devpriv->count > max_points) { 205 } else if (devpriv->count > max_points) {
224 leftover = devpriv->count - max_points; 206 leftover = devpriv->count - max_points;
225 if (leftover > max_points) 207 if (leftover > max_points)
@@ -234,7 +216,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
234 216
235 for (i = 0; i < num_points; i++) { 217 for (i = 0; i < num_points; i++) {
236 /* write data point to comedi buffer */ 218 /* write data point to comedi buffer */
237 dpnt = devpriv->dma_buffer[i]; 219 dpnt = buf[i];
238 /* convert from 2's complement to unsigned coding */ 220 /* convert from 2's complement to unsigned coding */
239 dpnt ^= 0x8000; 221 dpnt ^= 0x8000;
240 comedi_buf_write_samples(s, &dpnt, 1); 222 comedi_buf_write_samples(s, &dpnt, 1);
@@ -245,14 +227,11 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
245 } 227 }
246 } 228 }
247 } 229 }
248 /* re-enable dma */ 230 /* re-enable dma */
249 if (leftover) { 231 if (leftover) {
250 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer)); 232 desc->size = comedi_samples_to_bytes(s, leftover);
251 set_dma_count(devpriv->dma, 233 comedi_isadma_program(desc);
252 comedi_samples_to_bytes(s, leftover));
253 enable_dma(devpriv->dma);
254 } 234 }
255 release_dma_lock(flags);
256 235
257 comedi_handle_events(dev, s); 236 comedi_handle_events(dev, s);
258 237
@@ -265,13 +244,15 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
265static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 244static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
266{ 245{
267 struct a2150_private *devpriv = dev->private; 246 struct a2150_private *devpriv = dev->private;
247 struct comedi_isadma *dma = devpriv->dma;
248 struct comedi_isadma_desc *desc = &dma->desc[0];
268 249
269 /* disable dma on card */ 250 /* disable dma on card */
270 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT; 251 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
271 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); 252 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
272 253
273 /* disable computer's dma */ 254 /* disable computer's dma */
274 disable_dma(devpriv->dma); 255 comedi_isadma_disable(desc->chan);
275 256
276 /* clear fifo and reset triggering circuitry */ 257 /* clear fifo and reset triggering circuitry */
277 outw(0, dev->iobase + FIFO_RESET_REG); 258 outw(0, dev->iobase + FIFO_RESET_REG);
@@ -503,10 +484,11 @@ static int a2150_ai_cmdtest(struct comedi_device *dev,
503static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 484static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
504{ 485{
505 struct a2150_private *devpriv = dev->private; 486 struct a2150_private *devpriv = dev->private;
487 struct comedi_isadma *dma = devpriv->dma;
488 struct comedi_isadma_desc *desc = &dma->desc[0];
506 struct comedi_async *async = s->async; 489 struct comedi_async *async = s->async;
507 struct comedi_cmd *cmd = &async->cmd; 490 struct comedi_cmd *cmd = &async->cmd;
508 unsigned long timer_base = dev->iobase + I8253_BASE_REG; 491 unsigned long timer_base = dev->iobase + I8253_BASE_REG;
509 unsigned long lock_flags;
510 unsigned int old_config_bits = devpriv->config_bits; 492 unsigned int old_config_bits = devpriv->config_bits;
511 unsigned int trigger_bits; 493 unsigned int trigger_bits;
512 494
@@ -542,27 +524,19 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
542 /* initialize number of samples remaining */ 524 /* initialize number of samples remaining */
543 devpriv->count = cmd->stop_arg * cmd->chanlist_len; 525 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
544 526
545 /* enable computer's dma */ 527 comedi_isadma_disable(desc->chan);
546 lock_flags = claim_dma_lock(); 528
547 disable_dma(devpriv->dma);
548 /* clear flip-flop to make sure 2-byte registers for
549 * count and address get set correctly */
550 clear_dma_ff(devpriv->dma);
551 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
552 /* set size of transfer to fill in 1/3 second */ 529 /* set size of transfer to fill in 1/3 second */
553#define ONE_THIRD_SECOND 333333333 530#define ONE_THIRD_SECOND 333333333
554 devpriv->dma_transfer_size = 531 desc->size = comedi_bytes_per_sample(s) * cmd->chanlist_len *
555 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len * 532 ONE_THIRD_SECOND / cmd->scan_begin_arg;
556 ONE_THIRD_SECOND / cmd->scan_begin_arg; 533 if (desc->size > desc->maxsize)
557 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE) 534 desc->size = desc->maxsize;
558 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE; 535 if (desc->size < comedi_bytes_per_sample(s))
559 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0])) 536 desc->size = comedi_bytes_per_sample(s);
560 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]); 537 desc->size -= desc->size % comedi_bytes_per_sample(s);
561 devpriv->dma_transfer_size -= 538
562 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]); 539 comedi_isadma_program(desc);
563 set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
564 enable_dma(devpriv->dma);
565 release_dma_lock(lock_flags);
566 540
567 /* clear dma interrupt before enabling it, to try and get rid of that 541 /* clear dma interrupt before enabling it, to try and get rid of that
568 * one spurious interrupt that has been happening */ 542 * one spurious interrupt that has been happening */
@@ -677,6 +651,45 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
677 return n; 651 return n;
678} 652}
679 653
654static void a2150_alloc_irq_and_dma(struct comedi_device *dev,
655 struct comedi_devconfig *it)
656{
657 struct a2150_private *devpriv = dev->private;
658 unsigned int irq_num = it->options[1];
659 unsigned int dma_chan = it->options[2];
660
661 /*
662 * Only IRQs 15, 14, 12-9, and 7-3 are valid.
663 * Only DMA channels 7-5 and 3-0 are valid.
664 */
665 if (irq_num > 15 || dma_chan > 7 ||
666 !((1 << irq_num) & 0xdef8) || !((1 << dma_chan) & 0xef))
667 return;
668
669 if (request_irq(irq_num, a2150_interrupt, 0, dev->board_name, dev))
670 return;
671
672 /* DMA uses 1 buffer */
673 devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
674 A2150_DMA_BUFFER_SIZE,
675 COMEDI_ISADMA_READ);
676 if (!devpriv->dma) {
677 free_irq(irq_num, dev);
678 } else {
679 dev->irq = irq_num;
680 devpriv->irq_dma_bits = IRQ_LVL_BITS(irq_num) |
681 DMA_CHAN_BITS(dma_chan);
682 }
683}
684
685static void a2150_free_dma(struct comedi_device *dev)
686{
687 struct a2150_private *devpriv = dev->private;
688
689 if (devpriv)
690 comedi_isadma_free(devpriv->dma);
691}
692
680/* probes board type, returns offset */ 693/* probes board type, returns offset */
681static int a2150_probe(struct comedi_device *dev) 694static int a2150_probe(struct comedi_device *dev)
682{ 695{
@@ -690,8 +703,6 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
690 const struct a2150_board *thisboard; 703 const struct a2150_board *thisboard;
691 struct a2150_private *devpriv; 704 struct a2150_private *devpriv;
692 struct comedi_subdevice *s; 705 struct comedi_subdevice *s;
693 unsigned int irq = it->options[1];
694 unsigned int dma = it->options[2];
695 static const int timeout = 2000; 706 static const int timeout = 2000;
696 int i; 707 int i;
697 int ret; 708 int ret;
@@ -712,31 +723,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
712 thisboard = dev->board_ptr; 723 thisboard = dev->board_ptr;
713 dev->board_name = thisboard->name; 724 dev->board_name = thisboard->name;
714 725
715 if ((irq >= 3 && irq <= 7) || (irq >= 9 && irq <= 12) || 726 /* an IRQ and DMA are required to support async commands */
716 irq == 14 || irq == 15) { 727 a2150_alloc_irq_and_dma(dev, it);
717 ret = request_irq(irq, a2150_interrupt, 0,
718 dev->board_name, dev);
719 if (ret == 0) {
720 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
721 dev->irq = irq;
722 }
723 }
724
725 if (dev->irq && dma <= 7 && dma != 4) {
726 ret = request_dma(dma, dev->board_name);
727 if (ret == 0) {
728 devpriv->dma = dma;
729 devpriv->dma_buffer = kmalloc(A2150_DMA_BUFFER_SIZE,
730 GFP_KERNEL | GFP_DMA);
731 if (!devpriv->dma_buffer)
732 return -ENOMEM;
733
734 disable_dma(dma);
735 set_dma_mode(dma, DMA_MODE_READ);
736
737 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
738 }
739 }
740 728
741 ret = comedi_alloc_subdevices(dev, 1); 729 ret = comedi_alloc_subdevices(dev, 1);
742 if (ret) 730 if (ret)
@@ -750,7 +738,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
750 s->maxdata = 0xffff; 738 s->maxdata = 0xffff;
751 s->range_table = &range_a2150; 739 s->range_table = &range_a2150;
752 s->insn_read = a2150_ai_rinsn; 740 s->insn_read = a2150_ai_rinsn;
753 if (dev->irq && devpriv->dma) { 741 if (dev->irq) {
754 dev->read_subdev = s; 742 dev->read_subdev = s;
755 s->subdev_flags |= SDF_CMD_READ; 743 s->subdev_flags |= SDF_CMD_READ;
756 s->len_chanlist = s->n_chan; 744 s->len_chanlist = s->n_chan;
@@ -791,15 +779,9 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
791 779
792static void a2150_detach(struct comedi_device *dev) 780static void a2150_detach(struct comedi_device *dev)
793{ 781{
794 struct a2150_private *devpriv = dev->private;
795
796 if (dev->iobase) 782 if (dev->iobase)
797 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); 783 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
798 if (devpriv) { 784 a2150_free_dma(dev);
799 if (devpriv->dma)
800 free_dma(devpriv->dma);
801 kfree(devpriv->dma_buffer);
802 }
803 comedi_legacy_detach(dev); 785 comedi_legacy_detach(dev);
804}; 786};
805 787
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index 05370a4a74a5..9eeaf3c5a858 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: ni_at_ao 20 * Driver: ni_at_ao
21 * Description: National Instruments AT-AO-6/10 21 * Description: National Instruments AT-AO-6/10
22 * Devices: (National Instruments) AT-AO-6 [at-ao-6] 22 * Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
23 * (National Instruments) AT-AO-10 [at-ao-10]
24 * Status: should work 23 * Status: should work
25 * Author: David A. Schleef <ds@schleef.org> 24 * Author: David A. Schleef <ds@schleef.org>
26 * Updated: Sun Dec 26 12:26:28 EST 2004 25 * Updated: Sun Dec 26 12:26:28 EST 2004
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index 0c5ff287dcef..301f154be813 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -300,7 +300,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
300 struct comedi_devconfig *it) 300 struct comedi_devconfig *it)
301{ 301{
302 const struct ni_board_struct *boardtype; 302 const struct ni_board_struct *boardtype;
303 struct ni_private *devpriv;
304 struct pnp_dev *isapnp_dev; 303 struct pnp_dev *isapnp_dev;
305 int ret; 304 int ret;
306 unsigned long iobase; 305 unsigned long iobase;
@@ -310,7 +309,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
310 ret = ni_alloc_private(dev); 309 ret = ni_alloc_private(dev);
311 if (ret) 310 if (ret)
312 return ret; 311 return ret;
313 devpriv = dev->private;
314 312
315 iobase = it->options[0]; 313 iobase = it->options[0];
316 irq = it->options[1]; 314 irq = it->options[1];
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 5e472cb7fbd7..8f6396edd21c 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -51,10 +51,7 @@
51#include <linux/delay.h> 51#include <linux/delay.h>
52#include <linux/interrupt.h> 52#include <linux/interrupt.h>
53 53
54#include "../comedidev.h" 54#include "../comedi_pcmcia.h"
55
56#include <pcmcia/cistpl.h>
57#include <pcmcia/ds.h>
58 55
59/* daqcard700 registers */ 56/* daqcard700 registers */
60#define DIO_W 0x04 /* WO 8bit */ 57#define DIO_W 0x04 /* WO 8bit */
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 8cfabdbaa30c..a208cb348437 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -32,11 +32,7 @@ the PCMCIA interface.
32*/ 32*/
33 33
34#include <linux/module.h> 34#include <linux/module.h>
35#include "../comedidev.h" 35#include "../comedi_pcmcia.h"
36
37#include <pcmcia/cistpl.h>
38#include <pcmcia/cisreg.h>
39#include <pcmcia/ds.h>
40 36
41#include "8255.h" 37#include "8255.h"
42 38
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 1fbfdb4c80c0..a916047791b8 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -17,9 +17,8 @@
17/* 17/*
18 * Driver: ni_labpc 18 * Driver: ni_labpc
19 * Description: National Instruments Lab-PC (& compatibles) 19 * Description: National Instruments Lab-PC (& compatibles)
20 * Devices: (National Instruments) Lab-PC-1200 [lab-pc-1200] 20 * Devices: [National Instruments] Lab-PC-1200 (lab-pc-1200),
21 * (National Instruments) Lab-PC-1200AI [lab-pc-1200ai] 21 * Lab-PC-1200AI (lab-pc-1200ai), Lab-PC+ (lab-pc+)
22 * (National Instruments) Lab-PC+ [lab-pc+]
23 * Author: Frank Mori Hess <fmhess@users.sourceforge.net> 22 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
24 * Status: works 23 * Status: works
25 * 24 *
@@ -85,15 +84,10 @@ static const struct labpc_boardinfo labpc_boards[] = {
85 84
86static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) 85static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
87{ 86{
88 struct labpc_private *devpriv;
89 unsigned int irq = it->options[1]; 87 unsigned int irq = it->options[1];
90 unsigned int dma_chan = it->options[2]; 88 unsigned int dma_chan = it->options[2];
91 int ret; 89 int ret;
92 90
93 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
94 if (!devpriv)
95 return -ENOMEM;
96
97 ret = comedi_request_region(dev, it->options[0], 0x20); 91 ret = comedi_request_region(dev, it->options[0], 0x20);
98 if (ret) 92 if (ret)
99 return ret; 93 return ret;
@@ -110,11 +104,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
110 104
111static void labpc_detach(struct comedi_device *dev) 105static void labpc_detach(struct comedi_device *dev)
112{ 106{
113 struct labpc_private *devpriv = dev->private; 107 labpc_free_dma_chan(dev);
114
115 if (devpriv)
116 labpc_free_dma_chan(dev);
117
118 comedi_legacy_detach(dev); 108 comedi_legacy_detach(dev);
119} 109}
120 110
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index ac2c01f9dfdc..be89ae479afc 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -35,6 +35,8 @@ struct labpc_boardinfo {
35}; 35};
36 36
37struct labpc_private { 37struct labpc_private {
38 struct comedi_isadma *dma;
39
38 /* number of data points left to be taken */ 40 /* number of data points left to be taken */
39 unsigned long long count; 41 unsigned long long count;
40 /* software copys of bits written to command registers */ 42 /* software copys of bits written to command registers */
@@ -61,11 +63,7 @@ struct labpc_private {
61 * conversions 63 * conversions
62 */ 64 */
63 unsigned int divisor_b1; 65 unsigned int divisor_b1;
64 unsigned int dma_chan; /* dma channel to use */ 66
65 u16 *dma_buffer; /* buffer ai will dma into */
66 phys_addr_t dma_addr;
67 /* transfer size in bytes for current transfer */
68 unsigned int dma_transfer_size;
69 /* we are using dma/fifo-half-full/etc. */ 67 /* we are using dma/fifo-half-full/etc. */
70 enum transfer_type current_transfer; 68 enum transfer_type current_transfer;
71 /* 69 /*
diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c
index d89d5852aeea..b88ee2614bfe 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_common.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_common.c
@@ -368,10 +368,6 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
368 enum scan_mode mode) 368 enum scan_mode mode)
369{ 369{
370 struct labpc_private *devpriv = dev->private; 370 struct labpc_private *devpriv = dev->private;
371 /* max value for 16 bit counter in mode 2 */
372 const int max_counter_value = 0x10000;
373 /* min value for 16 bit counter in mode 2 */
374 const int min_counter_value = 2;
375 unsigned int base_period; 371 unsigned int base_period;
376 unsigned int scan_period; 372 unsigned int scan_period;
377 unsigned int convert_period; 373 unsigned int convert_period;
@@ -388,11 +384,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
388 * clock speed on convert and scan counters) 384 * clock speed on convert and scan counters)
389 */ 385 */
390 devpriv->divisor_b0 = (scan_period - 1) / 386 devpriv->divisor_b0 = (scan_period - 1) /
391 (I8254_OSC_BASE_2MHZ * max_counter_value) + 1; 387 (I8254_OSC_BASE_2MHZ * 0x10000) + 1;
392 if (devpriv->divisor_b0 < min_counter_value) 388
393 devpriv->divisor_b0 = min_counter_value; 389 cfc_check_trigger_arg_min(&devpriv->divisor_b0, 2);
394 if (devpriv->divisor_b0 > max_counter_value) 390 cfc_check_trigger_arg_max(&devpriv->divisor_b0, 0x10000);
395 devpriv->divisor_b0 = max_counter_value;
396 391
397 base_period = I8254_OSC_BASE_2MHZ * devpriv->divisor_b0; 392 base_period = I8254_OSC_BASE_2MHZ * devpriv->divisor_b0;
398 393
@@ -400,16 +395,16 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
400 switch (cmd->flags & CMDF_ROUND_MASK) { 395 switch (cmd->flags & CMDF_ROUND_MASK) {
401 default: 396 default:
402 case CMDF_ROUND_NEAREST: 397 case CMDF_ROUND_NEAREST:
403 devpriv->divisor_a0 = 398 devpriv->divisor_a0 = DIV_ROUND_CLOSEST(convert_period,
404 (convert_period + (base_period / 2)) / base_period; 399 base_period);
405 devpriv->divisor_b1 = 400 devpriv->divisor_b1 = DIV_ROUND_CLOSEST(scan_period,
406 (scan_period + (base_period / 2)) / base_period; 401 base_period);
407 break; 402 break;
408 case CMDF_ROUND_UP: 403 case CMDF_ROUND_UP:
409 devpriv->divisor_a0 = 404 devpriv->divisor_a0 = DIV_ROUND_UP(convert_period,
410 (convert_period + (base_period - 1)) / base_period; 405 base_period);
411 devpriv->divisor_b1 = 406 devpriv->divisor_b1 = DIV_ROUND_UP(scan_period,
412 (scan_period + (base_period - 1)) / base_period; 407 base_period);
413 break; 408 break;
414 case CMDF_ROUND_DOWN: 409 case CMDF_ROUND_DOWN:
415 devpriv->divisor_a0 = convert_period / base_period; 410 devpriv->divisor_a0 = convert_period / base_period;
@@ -417,14 +412,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
417 break; 412 break;
418 } 413 }
419 /* make sure a0 and b1 values are acceptable */ 414 /* make sure a0 and b1 values are acceptable */
420 if (devpriv->divisor_a0 < min_counter_value) 415 cfc_check_trigger_arg_min(&devpriv->divisor_a0, 2);
421 devpriv->divisor_a0 = min_counter_value; 416 cfc_check_trigger_arg_max(&devpriv->divisor_a0, 0x10000);
422 if (devpriv->divisor_a0 > max_counter_value) 417 cfc_check_trigger_arg_min(&devpriv->divisor_b1, 2);
423 devpriv->divisor_a0 = max_counter_value; 418 cfc_check_trigger_arg_max(&devpriv->divisor_b1, 0x10000);
424 if (devpriv->divisor_b1 < min_counter_value)
425 devpriv->divisor_b1 = min_counter_value;
426 if (devpriv->divisor_b1 > max_counter_value)
427 devpriv->divisor_b1 = max_counter_value;
428 /* write corrected timings to command */ 419 /* write corrected timings to command */
429 labpc_set_ai_convert_period(cmd, mode, 420 labpc_set_ai_convert_period(cmd, mode,
430 base_period * devpriv->divisor_a0); 421 base_period * devpriv->divisor_a0);
@@ -687,7 +678,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
687 } 678 }
688 679
689 /* figure out what method we will use to transfer data */ 680 /* figure out what method we will use to transfer data */
690 if (labpc_have_dma_chan(dev) && 681 if (devpriv->dma &&
691 /* dma unsafe at RT priority, 682 /* dma unsafe at RT priority,
692 * and too much setup time for CMDF_WAKE_EOS */ 683 * and too much setup time for CMDF_WAKE_EOS */
693 (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) 684 (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0)
@@ -823,7 +814,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
823 } 814 }
824 if (i == timeout) { 815 if (i == timeout) {
825 dev_err(dev->class_dev, "ai timeout, fifo never empties\n"); 816 dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
826 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 817 async->events |= COMEDI_CB_ERROR;
827 return -1; 818 return -1;
828 } 819 }
829 820
@@ -875,7 +866,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
875 if (devpriv->stat1 & STAT1_OVERRUN) { 866 if (devpriv->stat1 & STAT1_OVERRUN) {
876 /* clear error interrupt */ 867 /* clear error interrupt */
877 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); 868 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
878 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 869 async->events |= COMEDI_CB_ERROR;
879 comedi_handle_events(dev, s); 870 comedi_handle_events(dev, s);
880 dev_err(dev->class_dev, "overrun\n"); 871 dev_err(dev->class_dev, "overrun\n");
881 return IRQ_HANDLED; 872 return IRQ_HANDLED;
@@ -895,7 +886,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
895 if (devpriv->stat1 & STAT1_OVERFLOW) { 886 if (devpriv->stat1 & STAT1_OVERFLOW) {
896 /* clear error interrupt */ 887 /* clear error interrupt */
897 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); 888 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
898 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 889 async->events |= COMEDI_CB_ERROR;
899 comedi_handle_events(dev, s); 890 comedi_handle_events(dev, s);
900 dev_err(dev->class_dev, "overflow\n"); 891 dev_err(dev->class_dev, "overflow\n");
901 return IRQ_HANDLED; 892 return IRQ_HANDLED;
@@ -1215,11 +1206,15 @@ int labpc_common_attach(struct comedi_device *dev,
1215 unsigned int irq, unsigned long isr_flags) 1206 unsigned int irq, unsigned long isr_flags)
1216{ 1207{
1217 const struct labpc_boardinfo *board = dev->board_ptr; 1208 const struct labpc_boardinfo *board = dev->board_ptr;
1218 struct labpc_private *devpriv = dev->private; 1209 struct labpc_private *devpriv;
1219 struct comedi_subdevice *s; 1210 struct comedi_subdevice *s;
1220 int ret; 1211 int ret;
1221 int i; 1212 int i;
1222 1213
1214 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1215 if (!devpriv)
1216 return -ENOMEM;
1217
1223 if (dev->mmio) { 1218 if (dev->mmio) {
1224 devpriv->read_byte = labpc_readb; 1219 devpriv->read_byte = labpc_readb;
1225 devpriv->write_byte = labpc_writeb; 1220 devpriv->write_byte = labpc_writeb;
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 0a8b3223f74e..746c4cd9978d 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -54,19 +54,11 @@ NI manuals:
54*/ 54*/
55 55
56#include <linux/module.h> 56#include <linux/module.h>
57#include "../comedidev.h"
58 57
59#include <linux/delay.h> 58#include "../comedi_pcmcia.h"
60 59
61#include "8253.h"
62#include "8255.h"
63#include "comedi_fc.h"
64#include "ni_labpc.h" 60#include "ni_labpc.h"
65 61
66#include <pcmcia/cistpl.h>
67#include <pcmcia/cisreg.h>
68#include <pcmcia/ds.h>
69
70static const struct labpc_boardinfo labpc_cs_boards[] = { 62static const struct labpc_boardinfo labpc_cs_boards[] = {
71 { 63 {
72 .name = "daqcard-1200", 64 .name = "daqcard-1200",
@@ -80,7 +72,6 @@ static int labpc_auto_attach(struct comedi_device *dev,
80 unsigned long context) 72 unsigned long context)
81{ 73{
82 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); 74 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
83 struct labpc_private *devpriv;
84 int ret; 75 int ret;
85 76
86 /* The ni_labpc driver needs the board_ptr */ 77 /* The ni_labpc driver needs the board_ptr */
@@ -96,10 +87,6 @@ static int labpc_auto_attach(struct comedi_device *dev,
96 if (!link->irq) 87 if (!link->irq)
97 return -EINVAL; 88 return -EINVAL;
98 89
99 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
100 if (!devpriv)
101 return -ENOMEM;
102
103 return labpc_common_attach(dev, link->irq, IRQF_SHARED); 90 return labpc_common_attach(dev, link->irq, IRQF_SHARED);
104} 91}
105 92
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
index 6d386050e59d..6b4ccd86b3d0 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
@@ -19,23 +19,25 @@
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include "../comedidev.h"
23 22
24#include <asm/dma.h> 23#include "../comedidev.h"
25 24
25#include "comedi_isadma.h"
26#include "comedi_fc.h" 26#include "comedi_fc.h"
27#include "ni_labpc.h" 27#include "ni_labpc.h"
28#include "ni_labpc_regs.h" 28#include "ni_labpc_regs.h"
29#include "ni_labpc_isadma.h" 29#include "ni_labpc_isadma.h"
30 30
31/* size in bytes of dma buffer */ 31/* size in bytes of dma buffer */
32static const int dma_buffer_size = 0xff00; 32#define LABPC_ISADMA_BUFFER_SIZE 0xff00
33/* 2 bytes per sample */
34static const int sample_size = 2;
35 33
36/* utility function that suggests a dma transfer size in bytes */ 34/* utility function that suggests a dma transfer size in bytes */
37static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd) 35static unsigned int labpc_suggest_transfer_size(struct comedi_device *dev,
36 struct comedi_subdevice *s,
37 unsigned int maxbytes)
38{ 38{
39 struct comedi_cmd *cmd = &s->async->cmd;
40 unsigned int sample_size = comedi_bytes_per_sample(s);
39 unsigned int size; 41 unsigned int size;
40 unsigned int freq; 42 unsigned int freq;
41 43
@@ -49,8 +51,8 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
49 size = (freq / 3) * sample_size; 51 size = (freq / 3) * sample_size;
50 52
51 /* set a minimum and maximum size allowed */ 53 /* set a minimum and maximum size allowed */
52 if (size > dma_buffer_size) 54 if (size > maxbytes)
53 size = dma_buffer_size - dma_buffer_size % sample_size; 55 size = maxbytes;
54 else if (size < sample_size) 56 else if (size < sample_size)
55 size = sample_size; 57 size = sample_size;
56 58
@@ -60,23 +62,18 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
60void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) 62void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s)
61{ 63{
62 struct labpc_private *devpriv = dev->private; 64 struct labpc_private *devpriv = dev->private;
65 struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
63 struct comedi_cmd *cmd = &s->async->cmd; 66 struct comedi_cmd *cmd = &s->async->cmd;
64 unsigned long irq_flags; 67 unsigned int sample_size = comedi_bytes_per_sample(s);
65 68
66 irq_flags = claim_dma_lock();
67 disable_dma(devpriv->dma_chan);
68 /* clear flip-flop to make sure 2-byte registers for
69 * count and address get set correctly */
70 clear_dma_ff(devpriv->dma_chan);
71 set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
72 /* set appropriate size of transfer */ 69 /* set appropriate size of transfer */
73 devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd); 70 desc->size = labpc_suggest_transfer_size(dev, s, desc->maxsize);
74 if (cmd->stop_src == TRIG_COUNT && 71 if (cmd->stop_src == TRIG_COUNT &&
75 devpriv->count * sample_size < devpriv->dma_transfer_size) 72 devpriv->count * sample_size < desc->size)
76 devpriv->dma_transfer_size = devpriv->count * sample_size; 73 desc->size = devpriv->count * sample_size;
77 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); 74
78 enable_dma(devpriv->dma_chan); 75 comedi_isadma_program(desc);
79 release_dma_lock(irq_flags); 76
80 /* set CMD3 bits for caller to enable DMA and interrupt */ 77 /* set CMD3 bits for caller to enable DMA and interrupt */
81 devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN); 78 devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN);
82} 79}
@@ -85,61 +82,55 @@ EXPORT_SYMBOL_GPL(labpc_setup_dma);
85void labpc_drain_dma(struct comedi_device *dev) 82void labpc_drain_dma(struct comedi_device *dev)
86{ 83{
87 struct labpc_private *devpriv = dev->private; 84 struct labpc_private *devpriv = dev->private;
85 struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
88 struct comedi_subdevice *s = dev->read_subdev; 86 struct comedi_subdevice *s = dev->read_subdev;
89 struct comedi_async *async = s->async; 87 struct comedi_async *async = s->async;
90 struct comedi_cmd *cmd = &async->cmd; 88 struct comedi_cmd *cmd = &async->cmd;
91 int status; 89 unsigned int max_samples = comedi_bytes_to_samples(s, desc->size);
92 unsigned long flags; 90 unsigned int residue;
93 unsigned int max_points, num_points, residue, leftover; 91 unsigned int nsamples;
92 unsigned int leftover;
94 93
95 status = devpriv->stat1; 94 /*
96 95 * residue is the number of bytes left to be done on the dma
97 flags = claim_dma_lock();
98 disable_dma(devpriv->dma_chan);
99 /* clear flip-flop to make sure 2-byte registers for
100 * count and address get set correctly */
101 clear_dma_ff(devpriv->dma_chan);
102
103 /* figure out how many points to read */
104 max_points = devpriv->dma_transfer_size / sample_size;
105 /* residue is the number of points left to be done on the dma
106 * transfer. It should always be zero at this point unless 96 * transfer. It should always be zero at this point unless
107 * the stop_src is set to external triggering. 97 * the stop_src is set to external triggering.
108 */ 98 */
109 residue = get_dma_residue(devpriv->dma_chan) / sample_size; 99 residue = comedi_isadma_disable(desc->chan);
110 num_points = max_points - residue;
111 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_points)
112 num_points = devpriv->count;
113
114 /* figure out how many points will be stored next time */
115 leftover = 0;
116 if (cmd->stop_src != TRIG_COUNT) {
117 leftover = devpriv->dma_transfer_size / sample_size;
118 } else if (devpriv->count > num_points) {
119 leftover = devpriv->count - num_points;
120 if (leftover > max_points)
121 leftover = max_points;
122 }
123
124 comedi_buf_write_samples(s, devpriv->dma_buffer, num_points);
125 100
126 if (cmd->stop_src == TRIG_COUNT) 101 /*
127 devpriv->count -= num_points; 102 * Figure out how many samples to read for this transfer and
103 * how many will be stored for next time.
104 */
105 nsamples = max_samples - comedi_bytes_to_samples(s, residue);
106 if (cmd->stop_src == TRIG_COUNT) {
107 if (devpriv->count <= nsamples) {
108 nsamples = devpriv->count;
109 leftover = 0;
110 } else {
111 leftover = devpriv->count - nsamples;
112 if (leftover > max_samples)
113 leftover = max_samples;
114 }
115 devpriv->count -= nsamples;
116 } else {
117 leftover = max_samples;
118 }
119 desc->size = comedi_samples_to_bytes(s, leftover);
128 120
129 /* set address and count for next transfer */ 121 comedi_buf_write_samples(s, desc->virt_addr, nsamples);
130 set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
131 set_dma_count(devpriv->dma_chan, leftover * sample_size);
132 release_dma_lock(flags);
133} 122}
134EXPORT_SYMBOL_GPL(labpc_drain_dma); 123EXPORT_SYMBOL_GPL(labpc_drain_dma);
135 124
136static void handle_isa_dma(struct comedi_device *dev) 125static void handle_isa_dma(struct comedi_device *dev)
137{ 126{
138 struct labpc_private *devpriv = dev->private; 127 struct labpc_private *devpriv = dev->private;
128 struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
139 129
140 labpc_drain_dma(dev); 130 labpc_drain_dma(dev);
141 131
142 enable_dma(devpriv->dma_chan); 132 if (desc->size)
133 comedi_isadma_program(desc);
143 134
144 /* clear dma tc interrupt */ 135 /* clear dma tc interrupt */
145 devpriv->write_byte(dev, 0x1, DMATC_CLEAR_REG); 136 devpriv->write_byte(dev, 0x1, DMATC_CLEAR_REG);
@@ -160,36 +151,18 @@ void labpc_handle_dma_status(struct comedi_device *dev)
160} 151}
161EXPORT_SYMBOL_GPL(labpc_handle_dma_status); 152EXPORT_SYMBOL_GPL(labpc_handle_dma_status);
162 153
163int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan) 154void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan)
164{ 155{
165 struct labpc_private *devpriv = dev->private; 156 struct labpc_private *devpriv = dev->private;
166 void *dma_buffer;
167 unsigned long dma_flags;
168 int ret;
169 157
158 /* only DMA channels 3 and 1 are valid */
170 if (dma_chan != 1 && dma_chan != 3) 159 if (dma_chan != 1 && dma_chan != 3)
171 return -EINVAL; 160 return;
172
173 dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
174 if (!dma_buffer)
175 return -ENOMEM;
176
177 ret = request_dma(dma_chan, dev->board_name);
178 if (ret) {
179 kfree(dma_buffer);
180 return ret;
181 }
182
183 devpriv->dma_buffer = dma_buffer;
184 devpriv->dma_chan = dma_chan;
185 devpriv->dma_addr = virt_to_bus(devpriv->dma_buffer);
186
187 dma_flags = claim_dma_lock();
188 disable_dma(devpriv->dma_chan);
189 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
190 release_dma_lock(dma_flags);
191 161
192 return 0; 162 /* DMA uses 1 buffer */
163 devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
164 LABPC_ISADMA_BUFFER_SIZE,
165 COMEDI_ISADMA_READ);
193} 166}
194EXPORT_SYMBOL_GPL(labpc_init_dma_chan); 167EXPORT_SYMBOL_GPL(labpc_init_dma_chan);
195 168
@@ -197,12 +170,8 @@ void labpc_free_dma_chan(struct comedi_device *dev)
197{ 170{
198 struct labpc_private *devpriv = dev->private; 171 struct labpc_private *devpriv = dev->private;
199 172
200 kfree(devpriv->dma_buffer); 173 if (devpriv)
201 devpriv->dma_buffer = NULL; 174 comedi_isadma_free(devpriv->dma);
202 if (devpriv->dma_chan) {
203 free_dma(devpriv->dma_chan);
204 devpriv->dma_chan = 0;
205 }
206} 175}
207EXPORT_SYMBOL_GPL(labpc_free_dma_chan); 176EXPORT_SYMBOL_GPL(labpc_free_dma_chan);
208 177
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.h b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
index 771af4bd5a76..b8a1b0ee6290 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.h
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
@@ -5,18 +5,9 @@
5#ifndef _NI_LABPC_ISADMA_H 5#ifndef _NI_LABPC_ISADMA_H
6#define _NI_LABPC_ISADMA_H 6#define _NI_LABPC_ISADMA_H
7 7
8#define NI_LABPC_HAVE_ISA_DMA IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISADMA) 8#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISADMA)
9 9
10#if NI_LABPC_HAVE_ISA_DMA 10void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan);
11
12static inline bool labpc_have_dma_chan(struct comedi_device *dev)
13{
14 struct labpc_private *devpriv = dev->private;
15
16 return (bool)devpriv->dma_chan;
17}
18
19int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan);
20void labpc_free_dma_chan(struct comedi_device *dev); 11void labpc_free_dma_chan(struct comedi_device *dev);
21void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s); 12void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s);
22void labpc_drain_dma(struct comedi_device *dev); 13void labpc_drain_dma(struct comedi_device *dev);
@@ -24,15 +15,9 @@ void labpc_handle_dma_status(struct comedi_device *dev);
24 15
25#else 16#else
26 17
27static inline bool labpc_have_dma_chan(struct comedi_device *dev) 18static inline void labpc_init_dma_chan(struct comedi_device *dev,
28{ 19 unsigned int dma_chan)
29 return false;
30}
31
32static inline int labpc_init_dma_chan(struct comedi_device *dev,
33 unsigned int dma_chan)
34{ 20{
35 return -ENOTSUPP;
36} 21}
37 22
38static inline void labpc_free_dma_chan(struct comedi_device *dev) 23static inline void labpc_free_dma_chan(struct comedi_device *dev)
diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c
index 3fc420406564..0407ff681dfd 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_pci.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c
@@ -17,7 +17,7 @@
17/* 17/*
18 * Driver: ni_labpc_pci 18 * Driver: ni_labpc_pci
19 * Description: National Instruments Lab-PC PCI-1200 19 * Description: National Instruments Lab-PC PCI-1200
20 * Devices: (National Instruments) PCI-1200 [ni_pci-1200] 20 * Devices: [National Instruments] PCI-1200 (ni_pci-1200)
21 * Author: Frank Mori Hess <fmhess@users.sourceforge.net> 21 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
22 * Status: works 22 * Status: works
23 * 23 *
@@ -79,7 +79,6 @@ static int labpc_pci_auto_attach(struct comedi_device *dev,
79{ 79{
80 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 80 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
81 const struct labpc_boardinfo *board = NULL; 81 const struct labpc_boardinfo *board = NULL;
82 struct labpc_private *devpriv;
83 int ret; 82 int ret;
84 83
85 if (context < ARRAY_SIZE(labpc_pci_boards)) 84 if (context < ARRAY_SIZE(labpc_pci_boards))
@@ -101,10 +100,6 @@ static int labpc_pci_auto_attach(struct comedi_device *dev,
101 if (!dev->mmio) 100 if (!dev->mmio)
102 return -ENOMEM; 101 return -ENOMEM;
103 102
104 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
105 if (!devpriv)
106 return -ENOMEM;
107
108 return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED); 103 return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED);
109} 104}
110 105
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 11e70173712d..b6ddc015dedf 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -1478,7 +1478,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
1478 dev_err(dev->class_dev, 1478 dev_err(dev->class_dev,
1479 "unknown mite interrupt (ai_mite_status=%08x)\n", 1479 "unknown mite interrupt (ai_mite_status=%08x)\n",
1480 ai_mite_status); 1480 ai_mite_status);
1481 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1481 s->async->events |= COMEDI_CB_ERROR;
1482 /* disable_irq(dev->irq); */ 1482 /* disable_irq(dev->irq); */
1483 } 1483 }
1484#endif 1484#endif
@@ -1491,8 +1491,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
1491 /* we probably aren't even running a command now, 1491 /* we probably aren't even running a command now,
1492 * so it's a good idea to be careful. */ 1492 * so it's a good idea to be careful. */
1493 if (comedi_is_subdevice_running(s)) { 1493 if (comedi_is_subdevice_running(s)) {
1494 s->async->events |= 1494 s->async->events |= COMEDI_CB_ERROR;
1495 COMEDI_CB_ERROR | COMEDI_CB_EOA;
1496 comedi_handle_events(dev, s); 1495 comedi_handle_events(dev, s);
1497 } 1496 }
1498 return; 1497 return;
@@ -1579,7 +1578,7 @@ static void handle_b_interrupt(struct comedi_device *dev,
1579 dev_err(dev->class_dev, 1578 dev_err(dev->class_dev,
1580 "unknown mite interrupt (ao_mite_status=%08x)\n", 1579 "unknown mite interrupt (ao_mite_status=%08x)\n",
1581 ao_mite_status); 1580 ao_mite_status);
1582 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 1581 s->async->events |= COMEDI_CB_ERROR;
1583 } 1582 }
1584#endif 1583#endif
1585 1584
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index 9b201e48233e..e3d821bf2d6a 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -37,16 +37,12 @@ See the notes in the ni_atmio.o driver.
37*/ 37*/
38 38
39#include <linux/module.h> 39#include <linux/module.h>
40#include "../comedidev.h"
41
42#include <linux/delay.h> 40#include <linux/delay.h>
43 41
42#include "../comedi_pcmcia.h"
44#include "ni_stc.h" 43#include "ni_stc.h"
45#include "8255.h" 44#include "8255.h"
46 45
47#include <pcmcia/cistpl.h>
48#include <pcmcia/ds.h>
49
50/* 46/*
51 * AT specific setup 47 * AT specific setup
52 */ 48 */
@@ -163,7 +159,6 @@ static int mio_cs_auto_attach(struct comedi_device *dev,
163{ 159{
164 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); 160 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
165 static const struct ni_board_struct *board; 161 static const struct ni_board_struct *board;
166 struct ni_private *devpriv;
167 int ret; 162 int ret;
168 163
169 board = ni_getboardtype(dev, link); 164 board = ni_getboardtype(dev, link);
@@ -188,8 +183,6 @@ static int mio_cs_auto_attach(struct comedi_device *dev,
188 if (ret) 183 if (ret)
189 return ret; 184 return ret;
190 185
191 devpriv = dev->private;
192
193 return ni_E_init(dev, 0, 1); 186 return ni_E_init(dev, 0, 1);
194} 187}
195 188
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index db7e8aac67b5..db399fe8c301 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -418,7 +418,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
418 CHSR_DRQ1 | CHSR_MRDY)) { 418 CHSR_DRQ1 | CHSR_MRDY)) {
419 dev_dbg(dev->class_dev, 419 dev_dbg(dev->class_dev,
420 "unknown mite interrupt, disabling IRQ\n"); 420 "unknown mite interrupt, disabling IRQ\n");
421 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 421 async->events |= COMEDI_CB_ERROR;
422 disable_irq(dev->irq); 422 disable_irq(dev->irq);
423 } 423 }
424 } 424 }
@@ -460,7 +460,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
460 break; 460 break;
461 } else if (flags & Waited) { 461 } else if (flags & Waited) {
462 writeb(ClearWaited, dev->mmio + Group_1_First_Clear); 462 writeb(ClearWaited, dev->mmio + Group_1_First_Clear);
463 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 463 async->events |= COMEDI_CB_ERROR;
464 break; 464 break;
465 } else if (flags & PrimaryTC) { 465 } else if (flags & PrimaryTC) {
466 writeb(ClearPrimaryTC, 466 writeb(ClearPrimaryTC,
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
index 0525292c1d8b..c20c51bef3e7 100644
--- a/drivers/staging/comedi/drivers/ni_tio.c
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -16,29 +16,28 @@
16*/ 16*/
17 17
18/* 18/*
19Driver: ni_tio 19 * Module: ni_tio
20Description: National Instruments general purpose counters 20 * Description: National Instruments general purpose counters
21Devices: 21 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
22Author: J.P. Mellor <jpmellor@rose-hulman.edu>, 22 * Herman.Bruyninckx@mech.kuleuven.ac.be,
23 Herman.Bruyninckx@mech.kuleuven.ac.be, 23 * Wim.Meeussen@mech.kuleuven.ac.be,
24 Wim.Meeussen@mech.kuleuven.ac.be, 24 * Klaas.Gadeyne@mech.kuleuven.ac.be,
25 Klaas.Gadeyne@mech.kuleuven.ac.be, 25 * Frank Mori Hess <fmhess@users.sourceforge.net>
26 Frank Mori Hess <fmhess@users.sourceforge.net> 26 * Updated: Thu Nov 16 09:50:32 EST 2006
27Updated: Thu Nov 16 09:50:32 EST 2006 27 * Status: works
28Status: works 28 *
29 29 * This module is not used directly by end-users. Rather, it
30This module is not used directly by end-users. Rather, it 30 * is used by other drivers (for example ni_660x and ni_pcimio)
31is used by other drivers (for example ni_660x and ni_pcimio) 31 * to provide support for NI's general purpose counters. It was
32to provide support for NI's general purpose counters. It was 32 * originally based on the counter code from ni_660x.c and
33originally based on the counter code from ni_660x.c and 33 * ni_mio_common.c.
34ni_mio_common.c. 34 *
35 35 * References:
36References: 36 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
37DAQ 660x Register-Level Programmer Manual (NI 370505A-01) 37 * DAQ 6601/6602 User Manual (NI 322137B-01)
38DAQ 6601/6602 User Manual (NI 322137B-01) 38 * 340934b.pdf DAQ-STC reference manual
39340934b.pdf DAQ-STC reference manual 39 */
40 40
41*/
42/* 41/*
43TODO: 42TODO:
44 Support use of both banks X and Y 43 Support use of both banks X and Y
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
index 6037bec77ef1..d36c3abd3120 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -16,29 +16,28 @@
16*/ 16*/
17 17
18/* 18/*
19Driver: ni_tiocmd 19 * Module: ni_tiocmd
20Description: National Instruments general purpose counters command support 20 * Description: National Instruments general purpose counters command support
21Devices: 21 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
22Author: J.P. Mellor <jpmellor@rose-hulman.edu>, 22 * Herman.Bruyninckx@mech.kuleuven.ac.be,
23 Herman.Bruyninckx@mech.kuleuven.ac.be, 23 * Wim.Meeussen@mech.kuleuven.ac.be,
24 Wim.Meeussen@mech.kuleuven.ac.be, 24 * Klaas.Gadeyne@mech.kuleuven.ac.be,
25 Klaas.Gadeyne@mech.kuleuven.ac.be, 25 * Frank Mori Hess <fmhess@users.sourceforge.net>
26 Frank Mori Hess <fmhess@users.sourceforge.net> 26 * Updated: Fri, 11 Apr 2008 12:32:35 +0100
27Updated: Fri, 11 Apr 2008 12:32:35 +0100 27 * Status: works
28Status: works 28 *
29 29 * This module is not used directly by end-users. Rather, it
30This module is not used directly by end-users. Rather, it 30 * is used by other drivers (for example ni_660x and ni_pcimio)
31is used by other drivers (for example ni_660x and ni_pcimio) 31 * to provide command support for NI's general purpose counters.
32to provide command support for NI's general purpose counters. 32 * It was originally split out of ni_tio.c to stop the 'ni_tio'
33It was originally split out of ni_tio.c to stop the 'ni_tio' 33 * module depending on the 'mite' module.
34module depending on the 'mite' module. 34 *
35 35 * References:
36References: 36 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
37DAQ 660x Register-Level Programmer Manual (NI 370505A-01) 37 * DAQ 6601/6602 User Manual (NI 322137B-01)
38DAQ 6601/6602 User Manual (NI 322137B-01) 38 * 340934b.pdf DAQ-STC reference manual
39340934b.pdf DAQ-STC reference manual 39 */
40 40
41*/
42/* 41/*
43TODO: 42TODO:
44 Support use of both banks X and Y 43 Support use of both banks X and Y
diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c
index 3b5a1b90366d..5f649f88d55c 100644
--- a/drivers/staging/comedi/drivers/ni_usb6501.c
+++ b/drivers/staging/comedi/drivers/ni_usb6501.c
@@ -96,9 +96,8 @@
96#include <linux/kernel.h> 96#include <linux/kernel.h>
97#include <linux/module.h> 97#include <linux/module.h>
98#include <linux/slab.h> 98#include <linux/slab.h>
99#include <linux/usb.h>
100 99
101#include "../comedidev.h" 100#include "../comedi_usb.h"
102 101
103#define NI6501_TIMEOUT 1000 102#define NI6501_TIMEOUT 1000
104 103
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 938aebc8e0ea..cb7e4c37b8b9 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -22,10 +22,8 @@
22/* 22/*
23 * Driver: pcl711 23 * Driver: pcl711
24 * Description: Advantech PCL-711 and 711b, ADLink ACL-8112 24 * Description: Advantech PCL-711 and 711b, ADLink ACL-8112
25 * Devices: (Advantech) PCL-711 [pcl711] 25 * Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
26 * (Advantech) PCL-711B [pcl711b] 26 * [ADLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
27 * (AdLink) ACL-8112HG [acl8112hg]
28 * (AdLink) ACL-8112DG [acl8112dg]
29 * Author: David A. Schleef <ds@schleef.org> 27 * Author: David A. Schleef <ds@schleef.org>
30 * Janne Jalkanen <jalkanen@cs.hut.fi> 28 * Janne Jalkanen <jalkanen@cs.hut.fi>
31 * Eric Bunn <ebu@cs.hut.fi> 29 * Eric Bunn <ebu@cs.hut.fi>
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index fcc440855e66..74b07e1744c7 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -8,14 +8,10 @@
8/* 8/*
9 * Driver: pcl724 9 * Driver: pcl724
10 * Description: Comedi driver for 8255 based ISA DIO boards 10 * Description: Comedi driver for 8255 based ISA DIO boards
11 * Devices: (Advantech) PCL-724 [pcl724] 11 * Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
12 * (Advantech) PCL-722 [pcl722] 12 * [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio),
13 * (Advantech) PCL-731 [pcl731] 13 * [WinSystems] PCM-IO48 (pcmio48),
14 * (ADLink) ACL-7122 [acl7122] 14 * [Diamond Systems] ONYX-MM-DIO (onyx-mm-dio)
15 * (ADLink) ACL-7124 [acl7124]
16 * (ADLink) PET-48DIO [pet48dio]
17 * (WinSystems) PCM-IO48 [pcmio48]
18 * (Diamond Systems) ONYX-MM-DIO [onyx-mm-dio]
19 * Author: Michal Dobes <dobes@tesnet.cz> 15 * Author: Michal Dobes <dobes@tesnet.cz>
20 * Status: untested 16 * Status: untested
21 * 17 *
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
index 86f713fdf1d0..40798150cfd8 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -21,11 +21,8 @@
21 * Description: Advantech PCL-726 & compatibles 21 * Description: Advantech PCL-726 & compatibles
22 * Author: David A. Schleef <ds@schleef.org> 22 * Author: David A. Schleef <ds@schleef.org>
23 * Status: untested 23 * Status: untested
24 * Devices: (Advantech) PCL-726 [pcl726] 24 * Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
25 * (Advantech) PCL-727 [pcl727] 25 * [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
26 * (Advantech) PCL-728 [pcl728]
27 * (ADLink) ACL-6126 [acl6126]
28 * (ADLink) ACL-6128 [acl6128]
29 * 26 *
30 * Configuration Options: 27 * Configuration Options:
31 * [0] - IO Base 28 * [0] - IO Base
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index a6c5770b2808..ce958eef2a61 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -7,19 +7,12 @@
7/* 7/*
8 * Driver: pcl730 8 * Driver: pcl730
9 * Description: Advantech PCL-730 (& compatibles) 9 * Description: Advantech PCL-730 (& compatibles)
10 * Devices: (Advantech) PCL-730 [pcl730] 10 * Devices: [Advantech] PCL-730 (pcl730), PCM-3730 (pcm3730), PCL-725 (pcl725),
11 * (ICP) ISO-730 [iso730] 11 * PCL-733 (pcl733), PCL-734 (pcl734),
12 * (Adlink) ACL-7130 [acl7130] 12 * [ADLink] ACL-7130 (acl7130), ACL-7225b (acl7225b),
13 * (Advantech) PCM-3730 [pcm3730] 13 * [ICP] ISO-730 (iso730), P8R8-DIO (p8r8dio), P16R16-DIO (p16r16dio),
14 * (Advantech) PCL-725 [pcl725] 14 * [Diamond Systems] OPMM-1616-XT (opmm-1616-xt), PEARL-MM-P (pearl-mm-p),
15 * (ICP) P8R8-DIO [p16r16dio] 15 * IR104-PBF (ir104-pbf),
16 * (Adlink) ACL-7225b [acl7225b]
17 * (ICP) P16R16-DIO [p16r16dio]
18 * (Advantech) PCL-733 [pcl733]
19 * (Advantech) PCL-734 [pcl734]
20 * (Diamond Systems) OPMM-1616-XT [opmm-1616-xt]
21 * (Diamond Systems) PEARL-MM-P [prearl-mm-p]
22 * (Diamond Systems) IR104-PBF [ir104-pbf]
23 * Author: José Luis Sánchez (jsanchezv@teleline.es) 16 * Author: José Luis Sánchez (jsanchezv@teleline.es)
24 * Status: untested 17 * Status: untested
25 * 18 *
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index ac243ca5e0f8..3ffb1ea2ecc8 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -111,12 +111,12 @@
111#include <linux/module.h> 111#include <linux/module.h>
112#include <linux/interrupt.h> 112#include <linux/interrupt.h>
113#include <linux/gfp.h> 113#include <linux/gfp.h>
114#include "../comedidev.h"
115
116#include <linux/delay.h> 114#include <linux/delay.h>
117#include <linux/io.h> 115#include <linux/io.h>
118#include <asm/dma.h>
119 116
117#include "../comedidev.h"
118
119#include "comedi_isadma.h"
120#include "comedi_fc.h" 120#include "comedi_fc.h"
121#include "8253.h" 121#include "8253.h"
122 122
@@ -507,19 +507,11 @@ static const struct pcl812_board boardtypes[] = {
507}; 507};
508 508
509struct pcl812_private { 509struct pcl812_private {
510 unsigned char dma; /* >0 use dma ( usedDMA channel) */ 510 struct comedi_isadma *dma;
511 unsigned char range_correction; /* =1 we must add 1 to range number */ 511 unsigned char range_correction; /* =1 we must add 1 to range number */
512 unsigned int last_ai_chanspec; 512 unsigned int last_ai_chanspec;
513 unsigned char mode_reg_int; /* there is stored INT number for some card */ 513 unsigned char mode_reg_int; /* there is stored INT number for some card */
514 unsigned int ai_poll_ptr; /* how many sampes transfer poll */ 514 unsigned int ai_poll_ptr; /* how many sampes transfer poll */
515 unsigned int dmapages;
516 unsigned int hwdmasize;
517 unsigned long dmabuf[2]; /* PTR to DMA buf */
518 unsigned int hwdmaptr[2]; /* HW PTR to DMA buf */
519 unsigned int dmabytestomove[2]; /* how many bytes DMA transfer */
520 int next_dma_buf; /* which buffer is next to use */
521 unsigned int dma_runs_to_end; /* how many times we must switch DMA buffers */
522 unsigned int last_dma_run; /* how many bytes to transfer on last DMA buffer */
523 unsigned int max_812_ai_mode0_rangewait; /* setling time for gain */ 515 unsigned int max_812_ai_mode0_rangewait; /* setling time for gain */
524 unsigned int divisor1; 516 unsigned int divisor1;
525 unsigned int divisor2; 517 unsigned int divisor2;
@@ -546,90 +538,32 @@ static void pcl812_start_pacer(struct comedi_device *dev, bool load_timers)
546} 538}
547 539
548static void pcl812_ai_setup_dma(struct comedi_device *dev, 540static void pcl812_ai_setup_dma(struct comedi_device *dev,
549 struct comedi_subdevice *s) 541 struct comedi_subdevice *s,
542 unsigned int unread_samples)
550{ 543{
551 struct pcl812_private *devpriv = dev->private; 544 struct pcl812_private *devpriv = dev->private;
552 struct comedi_cmd *cmd = &s->async->cmd; 545 struct comedi_isadma *dma = devpriv->dma;
553 unsigned int dma_flags; 546 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
554 unsigned int bytes; 547 unsigned int bytes;
548 unsigned int max_samples;
549 unsigned int nsamples;
555 550
556 /* we use EOS, so adapt DMA buffer to one scan */ 551 comedi_isadma_disable(dma->chan);
557 if (devpriv->ai_eos) {
558 devpriv->dmabytestomove[0] = comedi_bytes_per_scan(s);
559 devpriv->dmabytestomove[1] = comedi_bytes_per_scan(s);
560 devpriv->dma_runs_to_end = 1;
561 } else {
562 devpriv->dmabytestomove[0] = devpriv->hwdmasize;
563 devpriv->dmabytestomove[1] = devpriv->hwdmasize;
564 if (s->async->prealloc_bufsz < devpriv->hwdmasize) {
565 devpriv->dmabytestomove[0] =
566 s->async->prealloc_bufsz;
567 devpriv->dmabytestomove[1] =
568 s->async->prealloc_bufsz;
569 }
570 if (cmd->stop_src == TRIG_NONE) {
571 devpriv->dma_runs_to_end = 1;
572 } else {
573 /* how many samples we must transfer? */
574 bytes = cmd->stop_arg * comedi_bytes_per_scan(s);
575
576 /* how many DMA pages we must fill */
577 devpriv->dma_runs_to_end =
578 bytes / devpriv->dmabytestomove[0];
579
580 /* on last dma transfer must be moved */
581 devpriv->last_dma_run =
582 bytes % devpriv->dmabytestomove[0];
583 if (devpriv->dma_runs_to_end == 0)
584 devpriv->dmabytestomove[0] =
585 devpriv->last_dma_run;
586 devpriv->dma_runs_to_end--;
587 }
588 }
589 if (devpriv->dmabytestomove[0] > devpriv->hwdmasize) {
590 devpriv->dmabytestomove[0] = devpriv->hwdmasize;
591 devpriv->ai_eos = 0;
592 }
593 if (devpriv->dmabytestomove[1] > devpriv->hwdmasize) {
594 devpriv->dmabytestomove[1] = devpriv->hwdmasize;
595 devpriv->ai_eos = 0;
596 }
597 devpriv->next_dma_buf = 0;
598 set_dma_mode(devpriv->dma, DMA_MODE_READ);
599 dma_flags = claim_dma_lock();
600 clear_dma_ff(devpriv->dma);
601 set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
602 set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]);
603 release_dma_lock(dma_flags);
604 enable_dma(devpriv->dma);
605}
606 552
607static void pcl812_ai_setup_next_dma(struct comedi_device *dev, 553 /* if using EOS, adapt DMA buffer to one scan */
608 struct comedi_subdevice *s) 554 bytes = devpriv->ai_eos ? comedi_bytes_per_scan(s) : desc->maxsize;
609{ 555 max_samples = comedi_bytes_to_samples(s, bytes);
610 struct pcl812_private *devpriv = dev->private; 556
611 unsigned long dma_flags; 557 /*
612 558 * Determine dma size based on the buffer size plus the number of
613 devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; 559 * unread samples and the number of samples remaining in the command.
614 disable_dma(devpriv->dma); 560 */
615 set_dma_mode(devpriv->dma, DMA_MODE_READ); 561 nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
616 dma_flags = claim_dma_lock(); 562 if (nsamples > unread_samples) {
617 set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]); 563 nsamples -= unread_samples;
618 if (devpriv->ai_eos) { 564 desc->size = comedi_samples_to_bytes(s, nsamples);
619 set_dma_count(devpriv->dma, 565 comedi_isadma_program(desc);
620 devpriv->dmabytestomove[devpriv->next_dma_buf]);
621 } else {
622 if (devpriv->dma_runs_to_end) {
623 set_dma_count(devpriv->dma,
624 devpriv->dmabytestomove[devpriv->
625 next_dma_buf]);
626 } else {
627 set_dma_count(devpriv->dma, devpriv->last_dma_run);
628 }
629 devpriv->dma_runs_to_end--;
630 } 566 }
631 release_dma_lock(dma_flags);
632 enable_dma(devpriv->dma);
633} 567}
634 568
635static void pcl812_ai_set_chan_range(struct comedi_device *dev, 569static void pcl812_ai_set_chan_range(struct comedi_device *dev,
@@ -786,6 +720,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
786static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 720static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
787{ 721{
788 struct pcl812_private *devpriv = dev->private; 722 struct pcl812_private *devpriv = dev->private;
723 struct comedi_isadma *dma = devpriv->dma;
789 struct comedi_cmd *cmd = &s->async->cmd; 724 struct comedi_cmd *cmd = &s->async->cmd;
790 unsigned int ctrl = 0; 725 unsigned int ctrl = 0;
791 unsigned int i; 726 unsigned int i;
@@ -794,7 +729,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
794 729
795 pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1); 730 pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1);
796 731
797 if (devpriv->dma) { /* check if we can use DMA transfer */ 732 if (dma) { /* check if we can use DMA transfer */
798 devpriv->ai_dma = 1; 733 devpriv->ai_dma = 1;
799 for (i = 1; i < cmd->chanlist_len; i++) 734 for (i = 1; i < cmd->chanlist_len; i++)
800 if (cmd->chanlist[0] != cmd->chanlist[i]) { 735 if (cmd->chanlist[0] != cmd->chanlist[i]) {
@@ -817,8 +752,11 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
817 devpriv->ai_dma = 0; 752 devpriv->ai_dma = 0;
818 } 753 }
819 754
820 if (devpriv->ai_dma) 755 if (devpriv->ai_dma) {
821 pcl812_ai_setup_dma(dev, s); 756 /* setup and enable dma for the first buffer */
757 dma->cur_dma = 0;
758 pcl812_ai_setup_dma(dev, s, 0);
759 }
822 760
823 switch (cmd->convert_src) { 761 switch (cmd->convert_src) {
824 case TRIG_TIMER: 762 case TRIG_TIMER:
@@ -859,7 +797,7 @@ static void pcl812_handle_eoc(struct comedi_device *dev,
859 797
860 if (pcl812_ai_eoc(dev, s, NULL, 0)) { 798 if (pcl812_ai_eoc(dev, s, NULL, 0)) {
861 dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n"); 799 dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n");
862 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 800 s->async->events |= COMEDI_CB_ERROR;
863 return; 801 return;
864 } 802 }
865 803
@@ -895,19 +833,21 @@ static void pcl812_handle_dma(struct comedi_device *dev,
895 struct comedi_subdevice *s) 833 struct comedi_subdevice *s)
896{ 834{
897 struct pcl812_private *devpriv = dev->private; 835 struct pcl812_private *devpriv = dev->private;
898 int len, bufptr; 836 struct comedi_isadma *dma = devpriv->dma;
899 unsigned short *ptr; 837 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
900 838 unsigned int nsamples;
901 ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf]; 839 int bufptr;
902 len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
903 devpriv->ai_poll_ptr;
904
905 pcl812_ai_setup_next_dma(dev, s);
906 840
841 nsamples = comedi_bytes_to_samples(s, desc->size) -
842 devpriv->ai_poll_ptr;
907 bufptr = devpriv->ai_poll_ptr; 843 bufptr = devpriv->ai_poll_ptr;
908 devpriv->ai_poll_ptr = 0; 844 devpriv->ai_poll_ptr = 0;
909 845
910 transfer_from_dma_buf(dev, s, ptr, bufptr, len); 846 /* restart dma with the next buffer */
847 dma->cur_dma = 1 - dma->cur_dma;
848 pcl812_ai_setup_dma(dev, s, nsamples);
849
850 transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples);
911} 851}
912 852
913static irqreturn_t pcl812_interrupt(int irq, void *d) 853static irqreturn_t pcl812_interrupt(int irq, void *d)
@@ -935,45 +875,37 @@ static irqreturn_t pcl812_interrupt(int irq, void *d)
935static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) 875static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
936{ 876{
937 struct pcl812_private *devpriv = dev->private; 877 struct pcl812_private *devpriv = dev->private;
878 struct comedi_isadma *dma = devpriv->dma;
879 struct comedi_isadma_desc *desc;
938 unsigned long flags; 880 unsigned long flags;
939 unsigned int top1, top2, i; 881 unsigned int poll;
882 int ret;
940 883
884 /* poll is valid only for DMA transfer */
941 if (!devpriv->ai_dma) 885 if (!devpriv->ai_dma)
942 return 0; /* poll is valid only for DMA transfer */ 886 return 0;
943 887
944 spin_lock_irqsave(&dev->spinlock, flags); 888 spin_lock_irqsave(&dev->spinlock, flags);
945 889
946 for (i = 0; i < 10; i++) { 890 poll = comedi_isadma_poll(dma);
947 /* where is now DMA */ 891 poll = comedi_bytes_to_samples(s, poll);
948 top1 = get_dma_residue(devpriv->ai_dma); 892 if (poll > devpriv->ai_poll_ptr) {
949 top2 = get_dma_residue(devpriv->ai_dma); 893 desc = &dma->desc[dma->cur_dma];
950 if (top1 == top2) 894 transfer_from_dma_buf(dev, s, desc->virt_addr,
951 break; 895 devpriv->ai_poll_ptr,
952 } 896 poll - devpriv->ai_poll_ptr);
953 897 /* new buffer position */
954 if (top1 != top2) { 898 devpriv->ai_poll_ptr = poll;
955 spin_unlock_irqrestore(&dev->spinlock, flags); 899
956 return 0; 900 ret = comedi_buf_n_bytes_ready(s);
957 } 901 } else {
958 /* where is now DMA in buffer */ 902 /* no new samples */
959 top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1; 903 ret = 0;
960 top1 >>= 1; /* sample position */
961 top2 = top1 - devpriv->ai_poll_ptr;
962 if (top2 < 1) { /* no new samples */
963 spin_unlock_irqrestore(&dev->spinlock, flags);
964 return 0;
965 } 904 }
966 905
967 transfer_from_dma_buf(dev, s,
968 (void *)devpriv->dmabuf[1 -
969 devpriv->next_dma_buf],
970 devpriv->ai_poll_ptr, top2);
971
972 devpriv->ai_poll_ptr = top1; /* new buffer position */
973
974 spin_unlock_irqrestore(&dev->spinlock, flags); 906 spin_unlock_irqrestore(&dev->spinlock, flags);
975 907
976 return comedi_buf_n_bytes_ready(s); 908 return ret;
977} 909}
978 910
979static int pcl812_ai_cancel(struct comedi_device *dev, 911static int pcl812_ai_cancel(struct comedi_device *dev,
@@ -982,7 +914,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev,
982 struct pcl812_private *devpriv = dev->private; 914 struct pcl812_private *devpriv = dev->private;
983 915
984 if (devpriv->ai_dma) 916 if (devpriv->ai_dma)
985 disable_dma(devpriv->dma); 917 comedi_isadma_disable(devpriv->dma->chan);
986 918
987 outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG, 919 outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
988 dev->iobase + PCL812_CTRL_REG); 920 dev->iobase + PCL812_CTRL_REG);
@@ -1192,6 +1124,27 @@ static void pcl812_set_ai_range_table(struct comedi_device *dev,
1192 } 1124 }
1193} 1125}
1194 1126
1127static void pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
1128{
1129 struct pcl812_private *devpriv = dev->private;
1130
1131 /* only DMA channels 3 and 1 are valid */
1132 if (!(dma_chan == 3 || dma_chan == 1))
1133 return;
1134
1135 /* DMA uses two 8K buffers */
1136 devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
1137 PAGE_SIZE * 2, COMEDI_ISADMA_READ);
1138}
1139
1140static void pcl812_free_dma(struct comedi_device *dev)
1141{
1142 struct pcl812_private *devpriv = dev->private;
1143
1144 if (devpriv)
1145 comedi_isadma_free(devpriv->dma);
1146}
1147
1195static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1148static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1196{ 1149{
1197 const struct pcl812_board *board = dev->board_ptr; 1150 const struct pcl812_board *board = dev->board_ptr;
@@ -1200,7 +1153,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1200 int n_subdevices; 1153 int n_subdevices;
1201 int subdev; 1154 int subdev;
1202 int ret; 1155 int ret;
1203 int i;
1204 1156
1205 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1157 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1206 if (!devpriv) 1158 if (!devpriv)
@@ -1218,31 +1170,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1218 } 1170 }
1219 1171
1220 /* we need an IRQ to do DMA on channel 3 or 1 */ 1172 /* we need an IRQ to do DMA on channel 3 or 1 */
1221 if (dev->irq && board->has_dma && 1173 if (dev->irq && board->has_dma)
1222 (it->options[2] == 3 || it->options[2] == 1)) { 1174 pcl812_alloc_dma(dev, it->options[2]);
1223 ret = request_dma(it->options[2], dev->board_name);
1224 if (ret) {
1225 dev_err(dev->class_dev,
1226 "unable to request DMA channel %d\n",
1227 it->options[2]);
1228 return -EBUSY;
1229 }
1230 devpriv->dma = it->options[2];
1231
1232 devpriv->dmapages = 1; /* we want 8KB */
1233 devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
1234
1235 for (i = 0; i < 2; i++) {
1236 unsigned long dmabuf;
1237
1238 dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
1239 if (!dmabuf)
1240 return -ENOMEM;
1241
1242 devpriv->dmabuf[i] = dmabuf;
1243 devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
1244 }
1245 }
1246 1175
1247 /* differential analog inputs? */ 1176 /* differential analog inputs? */
1248 switch (board->board_type) { 1177 switch (board->board_type) {
@@ -1384,16 +1313,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1384 1313
1385static void pcl812_detach(struct comedi_device *dev) 1314static void pcl812_detach(struct comedi_device *dev)
1386{ 1315{
1387 struct pcl812_private *devpriv = dev->private; 1316 pcl812_free_dma(dev);
1388
1389 if (devpriv) {
1390 if (devpriv->dmabuf[0])
1391 free_pages(devpriv->dmabuf[0], devpriv->dmapages);
1392 if (devpriv->dmabuf[1])
1393 free_pages(devpriv->dmabuf[1], devpriv->dmapages);
1394 if (devpriv->dma)
1395 free_dma(devpriv->dma);
1396 }
1397 comedi_legacy_detach(dev); 1317 comedi_legacy_detach(dev);
1398} 1318}
1399 1319
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 73deb4bd5c93..da35edfccbc3 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -33,14 +33,14 @@ Configuration Options:
33*/ 33*/
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include "../comedidev.h"
37
38#include <linux/gfp.h> 36#include <linux/gfp.h>
39#include <linux/delay.h> 37#include <linux/delay.h>
40#include <linux/io.h> 38#include <linux/io.h>
41#include <linux/interrupt.h> 39#include <linux/interrupt.h>
42#include <asm/dma.h>
43 40
41#include "../comedidev.h"
42
43#include "comedi_isadma.h"
44#include "comedi_fc.h" 44#include "comedi_fc.h"
45#include "8253.h" 45#include "8253.h"
46 46
@@ -114,14 +114,7 @@ static const struct pcl816_board boardtypes[] = {
114}; 114};
115 115
116struct pcl816_private { 116struct pcl816_private {
117 unsigned int dma; /* used DMA, 0=don't use DMA */ 117 struct comedi_isadma *dma;
118 unsigned int dmapages;
119 unsigned int hwdmasize;
120 unsigned long dmabuf[2]; /* pointers to begin of DMA buffers */
121 unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */
122 int next_dma_buf; /* which DMA buffer will be used next round */
123 long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */
124 unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */
125 unsigned int ai_poll_ptr; /* how many sampes transfer poll */ 118 unsigned int ai_poll_ptr; /* how many sampes transfer poll */
126 unsigned int divisor1; 119 unsigned int divisor1;
127 unsigned int divisor2; 120 unsigned int divisor2;
@@ -149,63 +142,27 @@ static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters)
149} 142}
150 143
151static void pcl816_ai_setup_dma(struct comedi_device *dev, 144static void pcl816_ai_setup_dma(struct comedi_device *dev,
152 struct comedi_subdevice *s) 145 struct comedi_subdevice *s,
153{ 146 unsigned int unread_samples)
154 struct pcl816_private *devpriv = dev->private;
155 struct comedi_cmd *cmd = &s->async->cmd;
156 unsigned int dma_flags;
157 unsigned int bytes;
158
159 bytes = devpriv->hwdmasize;
160 if (cmd->stop_src == TRIG_COUNT) {
161 /* how many */
162 bytes = cmd->stop_arg * comedi_bytes_per_scan(s);
163
164 /* how many DMA pages we must fill */
165 devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize;
166
167 /* on last dma transfer must be moved */
168 devpriv->last_dma_run = bytes % devpriv->hwdmasize;
169 devpriv->dma_runs_to_end--;
170 if (devpriv->dma_runs_to_end >= 0)
171 bytes = devpriv->hwdmasize;
172 } else
173 devpriv->dma_runs_to_end = -1;
174
175 devpriv->next_dma_buf = 0;
176 set_dma_mode(devpriv->dma, DMA_MODE_READ);
177 dma_flags = claim_dma_lock();
178 clear_dma_ff(devpriv->dma);
179 set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
180 set_dma_count(devpriv->dma, bytes);
181 release_dma_lock(dma_flags);
182 enable_dma(devpriv->dma);
183}
184
185static void pcl816_ai_setup_next_dma(struct comedi_device *dev,
186 struct comedi_subdevice *s)
187{ 147{
188 struct pcl816_private *devpriv = dev->private; 148 struct pcl816_private *devpriv = dev->private;
189 struct comedi_cmd *cmd = &s->async->cmd; 149 struct comedi_isadma *dma = devpriv->dma;
190 unsigned long dma_flags; 150 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
191 151 unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
192 disable_dma(devpriv->dma); 152 unsigned int nsamples;
193 if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) { 153
194 /* switch dma bufs */ 154 comedi_isadma_disable(dma->chan);
195 devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; 155
196 set_dma_mode(devpriv->dma, DMA_MODE_READ); 156 /*
197 dma_flags = claim_dma_lock(); 157 * Determine dma size based on the buffer maxsize plus the number of
198 set_dma_addr(devpriv->dma, 158 * unread samples and the number of samples remaining in the command.
199 devpriv->hwdmaptr[devpriv->next_dma_buf]); 159 */
200 if (devpriv->dma_runs_to_end) 160 nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
201 set_dma_count(devpriv->dma, devpriv->hwdmasize); 161 if (nsamples > unread_samples) {
202 else 162 nsamples -= unread_samples;
203 set_dma_count(devpriv->dma, devpriv->last_dma_run); 163 desc->size = comedi_samples_to_bytes(s, nsamples);
204 release_dma_lock(dma_flags); 164 comedi_isadma_program(desc);
205 enable_dma(devpriv->dma);
206 } 165 }
207
208 devpriv->dma_runs_to_end--;
209} 166}
210 167
211static void pcl816_ai_set_chan_range(struct comedi_device *dev, 168static void pcl816_ai_set_chan_range(struct comedi_device *dev,
@@ -318,9 +275,10 @@ static irqreturn_t pcl816_interrupt(int irq, void *d)
318 struct comedi_device *dev = d; 275 struct comedi_device *dev = d;
319 struct comedi_subdevice *s = dev->read_subdev; 276 struct comedi_subdevice *s = dev->read_subdev;
320 struct pcl816_private *devpriv = dev->private; 277 struct pcl816_private *devpriv = dev->private;
321 unsigned short *ptr; 278 struct comedi_isadma *dma = devpriv->dma;
279 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
280 unsigned int nsamples;
322 unsigned int bufptr; 281 unsigned int bufptr;
323 unsigned int len;
324 282
325 if (!dev->attached || !devpriv->ai_cmd_running) { 283 if (!dev->attached || !devpriv->ai_cmd_running) {
326 pcl816_ai_clear_eoc(dev); 284 pcl816_ai_clear_eoc(dev);
@@ -333,15 +291,16 @@ static irqreturn_t pcl816_interrupt(int irq, void *d)
333 return IRQ_HANDLED; 291 return IRQ_HANDLED;
334 } 292 }
335 293
336 ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf]; 294 nsamples = comedi_bytes_to_samples(s, desc->size) -
337 295 devpriv->ai_poll_ptr;
338 pcl816_ai_setup_next_dma(dev, s);
339
340 len = (devpriv->hwdmasize >> 1) - devpriv->ai_poll_ptr;
341 bufptr = devpriv->ai_poll_ptr; 296 bufptr = devpriv->ai_poll_ptr;
342 devpriv->ai_poll_ptr = 0; 297 devpriv->ai_poll_ptr = 0;
343 298
344 transfer_from_dma_buf(dev, s, ptr, bufptr, len); 299 /* restart dma with the next buffer */
300 dma->cur_dma = 1 - dma->cur_dma;
301 pcl816_ai_setup_dma(dev, s, nsamples);
302
303 transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples);
345 304
346 pcl816_ai_clear_eoc(dev); 305 pcl816_ai_clear_eoc(dev);
347 306
@@ -483,6 +442,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
483static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 442static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
484{ 443{
485 struct pcl816_private *devpriv = dev->private; 444 struct pcl816_private *devpriv = dev->private;
445 struct comedi_isadma *dma = devpriv->dma;
486 struct comedi_cmd *cmd = &s->async->cmd; 446 struct comedi_cmd *cmd = &s->async->cmd;
487 unsigned int ctrl; 447 unsigned int ctrl;
488 unsigned int seglen; 448 unsigned int seglen;
@@ -502,7 +462,9 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
502 devpriv->ai_poll_ptr = 0; 462 devpriv->ai_poll_ptr = 0;
503 devpriv->ai_cmd_canceled = 0; 463 devpriv->ai_cmd_canceled = 0;
504 464
505 pcl816_ai_setup_dma(dev, s); 465 /* setup and enable dma for the first buffer */
466 dma->cur_dma = 0;
467 pcl816_ai_setup_dma(dev, s, 0);
506 468
507 pcl816_start_pacer(dev, true); 469 pcl816_start_pacer(dev, true);
508 470
@@ -513,7 +475,8 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
513 ctrl |= PCL816_CTRL_EXT_TRIG; 475 ctrl |= PCL816_CTRL_EXT_TRIG;
514 476
515 outb(ctrl, dev->iobase + PCL816_CTRL_REG); 477 outb(ctrl, dev->iobase + PCL816_CTRL_REG);
516 outb((devpriv->dma << 4) | dev->irq, dev->iobase + PCL816_STATUS_REG); 478 outb((dma->chan << 4) | dev->irq,
479 dev->iobase + PCL816_STATUS_REG);
517 480
518 return 0; 481 return 0;
519} 482}
@@ -521,42 +484,34 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
521static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) 484static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
522{ 485{
523 struct pcl816_private *devpriv = dev->private; 486 struct pcl816_private *devpriv = dev->private;
487 struct comedi_isadma *dma = devpriv->dma;
488 struct comedi_isadma_desc *desc;
524 unsigned long flags; 489 unsigned long flags;
525 unsigned int top1, top2, i; 490 unsigned int poll;
491 int ret;
526 492
527 spin_lock_irqsave(&dev->spinlock, flags); 493 spin_lock_irqsave(&dev->spinlock, flags);
528 494
529 for (i = 0; i < 20; i++) { 495 poll = comedi_isadma_poll(dma);
530 top1 = get_dma_residue(devpriv->dma); /* where is now DMA */ 496 poll = comedi_bytes_to_samples(s, poll);
531 top2 = get_dma_residue(devpriv->dma); 497 if (poll > devpriv->ai_poll_ptr) {
532 if (top1 == top2) 498 desc = &dma->desc[dma->cur_dma];
533 break; 499 transfer_from_dma_buf(dev, s, desc->virt_addr,
534 } 500 devpriv->ai_poll_ptr,
535 if (top1 != top2) { 501 poll - devpriv->ai_poll_ptr);
536 spin_unlock_irqrestore(&dev->spinlock, flags); 502 /* new buffer position */
537 return 0; 503 devpriv->ai_poll_ptr = poll;
538 }
539
540 /* where is now DMA in buffer */
541 top1 = devpriv->hwdmasize - top1;
542 top1 >>= 1; /* sample position */
543 top2 = top1 - devpriv->ai_poll_ptr;
544 if (top2 < 1) { /* no new samples */
545 spin_unlock_irqrestore(&dev->spinlock, flags);
546 return 0;
547 }
548 504
549 transfer_from_dma_buf(dev, s, 505 comedi_handle_events(dev, s);
550 (unsigned short *)devpriv->dmabuf[devpriv->
551 next_dma_buf],
552 devpriv->ai_poll_ptr, top2);
553 506
554 devpriv->ai_poll_ptr = top1; /* new buffer position */ 507 ret = comedi_buf_n_bytes_ready(s);
508 } else {
509 /* no new samples */
510 ret = 0;
511 }
555 spin_unlock_irqrestore(&dev->spinlock, flags); 512 spin_unlock_irqrestore(&dev->spinlock, flags);
556 513
557 comedi_handle_events(dev, s); 514 return ret;
558
559 return comedi_buf_n_bytes_ready(s);
560} 515}
561 516
562static int pcl816_ai_cancel(struct comedi_device *dev, 517static int pcl816_ai_cancel(struct comedi_device *dev,
@@ -657,13 +612,44 @@ static void pcl816_reset(struct comedi_device *dev)
657 outb(0, dev->iobase + PCL816_DO_DI_MSB_REG); 612 outb(0, dev->iobase + PCL816_DO_DI_MSB_REG);
658} 613}
659 614
615static void pcl816_alloc_irq_and_dma(struct comedi_device *dev,
616 struct comedi_devconfig *it)
617{
618 struct pcl816_private *devpriv = dev->private;
619 unsigned int irq_num = it->options[1];
620 unsigned int dma_chan = it->options[2];
621
622 /* only IRQs 2-7 and DMA channels 3 and 1 are valid */
623 if (!(irq_num >= 2 && irq_num <= 7) ||
624 !(dma_chan == 3 || dma_chan == 1))
625 return;
626
627 if (request_irq(irq_num, pcl816_interrupt, 0, dev->board_name, dev))
628 return;
629
630 /* DMA uses two 16K buffers */
631 devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
632 PAGE_SIZE * 4, COMEDI_ISADMA_READ);
633 if (!devpriv->dma)
634 free_irq(irq_num, dev);
635 else
636 dev->irq = irq_num;
637}
638
639static void pcl816_free_dma(struct comedi_device *dev)
640{
641 struct pcl816_private *devpriv = dev->private;
642
643 if (devpriv)
644 comedi_isadma_free(devpriv->dma);
645}
646
660static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) 647static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
661{ 648{
662 const struct pcl816_board *board = dev->board_ptr; 649 const struct pcl816_board *board = dev->board_ptr;
663 struct pcl816_private *devpriv; 650 struct pcl816_private *devpriv;
664 struct comedi_subdevice *s; 651 struct comedi_subdevice *s;
665 int ret; 652 int ret;
666 int i;
667 653
668 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 654 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
669 if (!devpriv) 655 if (!devpriv)
@@ -673,39 +659,8 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
673 if (ret) 659 if (ret)
674 return ret; 660 return ret;
675 661
676 /* we can use IRQ 2-7 for async command support */ 662 /* an IRQ and DMA are required to support async commands */
677 if (it->options[1] >= 2 && it->options[1] <= 7) { 663 pcl816_alloc_irq_and_dma(dev, it);
678 ret = request_irq(it->options[1], pcl816_interrupt, 0,
679 dev->board_name, dev);
680 if (ret == 0)
681 dev->irq = it->options[1];
682 }
683
684 /* we need an IRQ to do DMA on channel 3 or 1 */
685 if (dev->irq && (it->options[2] == 3 || it->options[2] == 1)) {
686 ret = request_dma(it->options[2], dev->board_name);
687 if (ret) {
688 dev_err(dev->class_dev,
689 "unable to request DMA channel %d\n",
690 it->options[2]);
691 return -EBUSY;
692 }
693 devpriv->dma = it->options[2];
694
695 devpriv->dmapages = 2; /* we need 16KB */
696 devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
697
698 for (i = 0; i < 2; i++) {
699 unsigned long dmabuf;
700
701 dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
702 if (!dmabuf)
703 return -ENOMEM;
704
705 devpriv->dmabuf[i] = dmabuf;
706 devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
707 }
708 }
709 664
710 ret = comedi_alloc_subdevices(dev, 4); 665 ret = comedi_alloc_subdevices(dev, 4);
711 if (ret) 666 if (ret)
@@ -718,7 +673,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
718 s->maxdata = board->ai_maxdata; 673 s->maxdata = board->ai_maxdata;
719 s->range_table = &range_pcl816; 674 s->range_table = &range_pcl816;
720 s->insn_read = pcl816_ai_insn_read; 675 s->insn_read = pcl816_ai_insn_read;
721 if (devpriv->dma) { 676 if (dev->irq) {
722 dev->read_subdev = s; 677 dev->read_subdev = s;
723 s->subdev_flags |= SDF_CMD_READ; 678 s->subdev_flags |= SDF_CMD_READ;
724 s->len_chanlist = board->ai_chanlist; 679 s->len_chanlist = board->ai_chanlist;
@@ -764,18 +719,11 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
764 719
765static void pcl816_detach(struct comedi_device *dev) 720static void pcl816_detach(struct comedi_device *dev)
766{ 721{
767 struct pcl816_private *devpriv = dev->private;
768
769 if (dev->private) { 722 if (dev->private) {
770 pcl816_ai_cancel(dev, dev->read_subdev); 723 pcl816_ai_cancel(dev, dev->read_subdev);
771 pcl816_reset(dev); 724 pcl816_reset(dev);
772 if (devpriv->dma)
773 free_dma(devpriv->dma);
774 if (devpriv->dmabuf[0])
775 free_pages(devpriv->dmabuf[0], devpriv->dmapages);
776 if (devpriv->dmabuf[1])
777 free_pages(devpriv->dmabuf[1], devpriv->dmapages);
778 } 725 }
726 pcl816_free_dma(dev);
779 comedi_legacy_detach(dev); 727 comedi_legacy_detach(dev);
780} 728}
781 729
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 8edea35532a9..7e4cdea5fe59 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -1,112 +1,105 @@
1/* 1/*
2 comedi/drivers/pcl818.c 2 * comedi/drivers/pcl818.c
3 3 *
4 Author: Michal Dobes <dobes@tesnet.cz> 4 * Driver: pcl818
5 5 * Description: Advantech PCL-818 cards, PCL-718
6 hardware driver for Advantech cards: 6 * Author: Michal Dobes <dobes@tesnet.cz>
7 card: PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718 7 * Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
8 driver: pcl818l, pcl818h, pcl818hd, pcl818hg, pcl818, pcl718 8 * PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
9*/ 9 * PCL-718 (pcl718)
10/* 10 * Status: works
11Driver: pcl818 11 *
12Description: Advantech PCL-818 cards, PCL-718 12 * All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
13Author: Michal Dobes <dobes@tesnet.cz> 13 * Differences are only at maximal sample speed, range list and FIFO
14Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h), 14 * support.
15 PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818), 15 * The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
16 PCL-718 (pcl718) 16 * only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
17Status: works 17 * PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
18 18 * but this code is untested.
19All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO. 19 * A word or two about DMA. Driver support DMA operations at two ways:
20Differences are only at maximal sample speed, range list and FIFO 20 * 1) DMA uses two buffers and after one is filled then is generated
21support. 21 * INT and DMA restart with second buffer. With this mode I'm unable run
22The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support 22 * more that 80Ksamples/secs without data dropouts on K6/233.
23only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0. 23 * 2) DMA uses one buffer and run in autoinit mode and the data are
24PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO 24 * from DMA buffer moved on the fly with 2kHz interrupts from RTC.
25but this code is untested. 25 * This mode is used if the interrupt 8 is available for allocation.
26A word or two about DMA. Driver support DMA operations at two ways: 26 * If not, then first DMA mode is used. With this I can run at
271) DMA uses two buffers and after one is filled then is generated 27 * full speed one card (100ksamples/secs) or two cards with
28 INT and DMA restart with second buffer. With this mode I'm unable run 28 * 60ksamples/secs each (more is problem on account of ISA limitations).
29 more that 80Ksamples/secs without data dropouts on K6/233. 29 * To use this mode you must have compiled kernel with disabled
302) DMA uses one buffer and run in autoinit mode and the data are 30 * "Enhanced Real Time Clock Support".
31 from DMA buffer moved on the fly with 2kHz interrupts from RTC. 31 * Maybe you can have problems if you use xntpd or similar.
32 This mode is used if the interrupt 8 is available for allocation. 32 * If you've data dropouts with DMA mode 2 then:
33 If not, then first DMA mode is used. With this I can run at 33 * a) disable IDE DMA
34 full speed one card (100ksamples/secs) or two cards with 34 * b) switch text mode console to fb.
35 60ksamples/secs each (more is problem on account of ISA limitations). 35 *
36 To use this mode you must have compiled kernel with disabled 36 * Options for PCL-818L:
37 "Enhanced Real Time Clock Support". 37 * [0] - IO Base
38 Maybe you can have problems if you use xntpd or similar. 38 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
39 If you've data dropouts with DMA mode 2 then: 39 * [2] - DMA (0=disable, 1, 3)
40 a) disable IDE DMA 40 * [3] - 0, 10=10MHz clock for 8254
41 b) switch text mode console to fb. 41 * 1= 1MHz clock for 8254
42 42 * [4] - 0, 5=A/D input -5V.. +5V
43 Options for PCL-818L: 43 * 1, 10=A/D input -10V..+10V
44 [0] - IO Base 44 * [5] - 0, 5=D/A output 0-5V (internal reference -5V)
45 [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7) 45 * 1, 10=D/A output 0-10V (internal reference -10V)
46 [2] - DMA (0=disable, 1, 3) 46 * 2 =D/A output unknown (external reference)
47 [3] - 0, 10=10MHz clock for 8254 47 *
48 1= 1MHz clock for 8254 48 * Options for PCL-818, PCL-818H:
49 [4] - 0, 5=A/D input -5V.. +5V 49 * [0] - IO Base
50 1, 10=A/D input -10V..+10V 50 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
51 [5] - 0, 5=D/A output 0-5V (internal reference -5V) 51 * [2] - DMA (0=disable, 1, 3)
52 1, 10=D/A output 0-10V (internal reference -10V) 52 * [3] - 0, 10=10MHz clock for 8254
53 2 =D/A output unknown (external reference) 53 * 1= 1MHz clock for 8254
54 54 * [4] - 0, 5=D/A output 0-5V (internal reference -5V)
55 Options for PCL-818, PCL-818H: 55 * 1, 10=D/A output 0-10V (internal reference -10V)
56 [0] - IO Base 56 * 2 =D/A output unknown (external reference)
57 [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7) 57 *
58 [2] - DMA (0=disable, 1, 3) 58 * Options for PCL-818HD, PCL-818HG:
59 [3] - 0, 10=10MHz clock for 8254 59 * [0] - IO Base
60 1= 1MHz clock for 8254 60 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
61 [4] - 0, 5=D/A output 0-5V (internal reference -5V) 61 * [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA,
62 1, 10=D/A output 0-10V (internal reference -10V) 62 * 1=use DMA ch 1, 3=use DMA ch 3)
63 2 =D/A output unknown (external reference) 63 * [3] - 0, 10=10MHz clock for 8254
64 64 * 1= 1MHz clock for 8254
65 Options for PCL-818HD, PCL-818HG: 65 * [4] - 0, 5=D/A output 0-5V (internal reference -5V)
66 [0] - IO Base 66 * 1, 10=D/A output 0-10V (internal reference -10V)
67 [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7) 67 * 2 =D/A output unknown (external reference)
68 [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA, 68 *
69 1=use DMA ch 1, 3=use DMA ch 3) 69 * Options for PCL-718:
70 [3] - 0, 10=10MHz clock for 8254 70 * [0] - IO Base
71 1= 1MHz clock for 8254 71 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
72 [4] - 0, 5=D/A output 0-5V (internal reference -5V) 72 * [2] - DMA (0=disable, 1, 3)
73 1, 10=D/A output 0-10V (internal reference -10V) 73 * [3] - 0, 10=10MHz clock for 8254
74 2 =D/A output unknown (external reference) 74 * 1= 1MHz clock for 8254
75 75 * [4] - 0=A/D Range is +/-10V
76 Options for PCL-718: 76 * 1= +/-5V
77 [0] - IO Base 77 * 2= +/-2.5V
78 [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7) 78 * 3= +/-1V
79 [2] - DMA (0=disable, 1, 3) 79 * 4= +/-0.5V
80 [3] - 0, 10=10MHz clock for 8254 80 * 5= user defined bipolar
81 1= 1MHz clock for 8254 81 * 6= 0-10V
82 [4] - 0=A/D Range is +/-10V 82 * 7= 0-5V
83 1= +/-5V 83 * 8= 0-2V
84 2= +/-2.5V 84 * 9= 0-1V
85 3= +/-1V 85 * 10= user defined unipolar
86 4= +/-0.5V 86 * [5] - 0, 5=D/A outputs 0-5V (internal reference -5V)
87 5= user defined bipolar 87 * 1, 10=D/A outputs 0-10V (internal reference -10V)
88 6= 0-10V 88 * 2=D/A outputs unknown (external reference)
89 7= 0-5V 89 * [6] - 0, 60=max 60kHz A/D sampling
90 8= 0-2V 90 * 1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
91 9= 0-1V 91 *
92 10= user defined unipolar 92 */
93 [5] - 0, 5=D/A outputs 0-5V (internal reference -5V)
94 1, 10=D/A outputs 0-10V (internal reference -10V)
95 2=D/A outputs unknown (external reference)
96 [6] - 0, 60=max 60kHz A/D sampling
97 1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
98
99*/
100 93
101#include <linux/module.h> 94#include <linux/module.h>
102#include <linux/gfp.h> 95#include <linux/gfp.h>
103#include <linux/delay.h> 96#include <linux/delay.h>
104#include <linux/io.h> 97#include <linux/io.h>
105#include <linux/interrupt.h> 98#include <linux/interrupt.h>
106#include <asm/dma.h>
107 99
108#include "../comedidev.h" 100#include "../comedidev.h"
109 101
102#include "comedi_isadma.h"
110#include "comedi_fc.h" 103#include "comedi_fc.h"
111#include "8253.h" 104#include "8253.h"
112 105
@@ -303,20 +296,14 @@ static const struct pcl818_board boardtypes[] = {
303}; 296};
304 297
305struct pcl818_private { 298struct pcl818_private {
306 unsigned int dma; /* used DMA, 0=don't use DMA */ 299 struct comedi_isadma *dma;
307 unsigned int dmapages; 300 /* manimal allowed delay between samples (in us) for actual card */
308 unsigned int hwdmasize; 301 unsigned int ns_min;
309 unsigned long dmabuf[2]; /* pointers to begin of DMA buffers */
310 unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */
311 int next_dma_buf; /* which DMA buffer will be used next round */
312 long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */
313 unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */
314 unsigned int ns_min; /* manimal allowed delay between samples (in us) for actual card */
315 int i8253_osc_base; /* 1/frequency of on board oscilator in ns */ 302 int i8253_osc_base; /* 1/frequency of on board oscilator in ns */
316 unsigned int act_chanlist[16]; /* MUX setting for actual AI operations */ 303 /* MUX setting for actual AI operations */
304 unsigned int act_chanlist[16];
317 unsigned int act_chanlist_len; /* how long is actual MUX list */ 305 unsigned int act_chanlist_len; /* how long is actual MUX list */
318 unsigned int act_chanlist_pos; /* actual position in MUX list */ 306 unsigned int act_chanlist_pos; /* actual position in MUX list */
319 unsigned int ai_data_len; /* len of data buffer */
320 unsigned int divisor1; 307 unsigned int divisor1;
321 unsigned int divisor2; 308 unsigned int divisor2;
322 unsigned int usefifo:1; 309 unsigned int usefifo:1;
@@ -340,58 +327,27 @@ static void pcl818_start_pacer(struct comedi_device *dev, bool load_counters)
340} 327}
341 328
342static void pcl818_ai_setup_dma(struct comedi_device *dev, 329static void pcl818_ai_setup_dma(struct comedi_device *dev,
343 struct comedi_subdevice *s) 330 struct comedi_subdevice *s,
344{ 331 unsigned int unread_samples)
345 struct pcl818_private *devpriv = dev->private;
346 struct comedi_cmd *cmd = &s->async->cmd;
347 unsigned int flags;
348 unsigned int bytes;
349
350 disable_dma(devpriv->dma); /* disable dma */
351 bytes = devpriv->hwdmasize;
352 if (cmd->stop_src == TRIG_COUNT) {
353 bytes = cmd->stop_arg * comedi_bytes_per_scan(s);
354 devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize;
355 devpriv->last_dma_run = bytes % devpriv->hwdmasize;
356 devpriv->dma_runs_to_end--;
357 if (devpriv->dma_runs_to_end >= 0)
358 bytes = devpriv->hwdmasize;
359 }
360
361 devpriv->next_dma_buf = 0;
362 set_dma_mode(devpriv->dma, DMA_MODE_READ);
363 flags = claim_dma_lock();
364 clear_dma_ff(devpriv->dma);
365 set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
366 set_dma_count(devpriv->dma, bytes);
367 release_dma_lock(flags);
368 enable_dma(devpriv->dma);
369}
370
371static void pcl818_ai_setup_next_dma(struct comedi_device *dev,
372 struct comedi_subdevice *s)
373{ 332{
374 struct pcl818_private *devpriv = dev->private; 333 struct pcl818_private *devpriv = dev->private;
375 struct comedi_cmd *cmd = &s->async->cmd; 334 struct comedi_isadma *dma = devpriv->dma;
376 unsigned long flags; 335 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
377 336 unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
378 disable_dma(devpriv->dma); 337 unsigned int nsamples;
379 devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; 338
380 if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) { 339 comedi_isadma_disable(dma->chan);
381 /* switch dma bufs */ 340
382 set_dma_mode(devpriv->dma, DMA_MODE_READ); 341 /*
383 flags = claim_dma_lock(); 342 * Determine dma size based on the buffer maxsize plus the number of
384 set_dma_addr(devpriv->dma, 343 * unread samples and the number of samples remaining in the command.
385 devpriv->hwdmaptr[devpriv->next_dma_buf]); 344 */
386 if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE) 345 nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
387 set_dma_count(devpriv->dma, devpriv->hwdmasize); 346 if (nsamples > unread_samples) {
388 else 347 nsamples -= unread_samples;
389 set_dma_count(devpriv->dma, devpriv->last_dma_run); 348 desc->size = comedi_samples_to_bytes(s, nsamples);
390 release_dma_lock(flags); 349 comedi_isadma_program(desc);
391 enable_dma(devpriv->dma);
392 } 350 }
393
394 devpriv->dma_runs_to_end--;
395} 351}
396 352
397static void pcl818_ai_set_chan_range(struct comedi_device *dev, 353static void pcl818_ai_set_chan_range(struct comedi_device *dev,
@@ -493,11 +449,12 @@ static int pcl818_ai_eoc(struct comedi_device *dev,
493 return -EBUSY; 449 return -EBUSY;
494} 450}
495 451
496static bool pcl818_ai_dropout(struct comedi_device *dev, 452static bool pcl818_ai_write_sample(struct comedi_device *dev,
497 struct comedi_subdevice *s, 453 struct comedi_subdevice *s,
498 unsigned int chan) 454 unsigned int chan, unsigned int val)
499{ 455{
500 struct pcl818_private *devpriv = dev->private; 456 struct pcl818_private *devpriv = dev->private;
457 struct comedi_cmd *cmd = &s->async->cmd;
501 unsigned int expected_chan; 458 unsigned int expected_chan;
502 459
503 expected_chan = devpriv->act_chanlist[devpriv->act_chanlist_pos]; 460 expected_chan = devpriv->act_chanlist[devpriv->act_chanlist_pos];
@@ -507,17 +464,11 @@ static bool pcl818_ai_dropout(struct comedi_device *dev,
507 (devpriv->dma) ? "DMA" : 464 (devpriv->dma) ? "DMA" :
508 (devpriv->usefifo) ? "FIFO" : "IRQ", 465 (devpriv->usefifo) ? "FIFO" : "IRQ",
509 chan, expected_chan); 466 chan, expected_chan);
510 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 467 s->async->events |= COMEDI_CB_ERROR;
511 return true; 468 return false;
512 } 469 }
513 return false;
514}
515 470
516static bool pcl818_ai_next_chan(struct comedi_device *dev, 471 comedi_buf_write_samples(s, &val, 1);
517 struct comedi_subdevice *s)
518{
519 struct pcl818_private *devpriv = dev->private;
520 struct comedi_cmd *cmd = &s->async->cmd;
521 472
522 devpriv->act_chanlist_pos++; 473 devpriv->act_chanlist_pos++;
523 if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) 474 if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
@@ -540,47 +491,35 @@ static void pcl818_handle_eoc(struct comedi_device *dev,
540 491
541 if (pcl818_ai_eoc(dev, s, NULL, 0)) { 492 if (pcl818_ai_eoc(dev, s, NULL, 0)) {
542 dev_err(dev->class_dev, "A/D mode1/3 IRQ without DRDY!\n"); 493 dev_err(dev->class_dev, "A/D mode1/3 IRQ without DRDY!\n");
543 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 494 s->async->events |= COMEDI_CB_ERROR;
544 return; 495 return;
545 } 496 }
546 497
547 val = pcl818_ai_get_sample(dev, s, &chan); 498 val = pcl818_ai_get_sample(dev, s, &chan);
548 499 pcl818_ai_write_sample(dev, s, chan, val);
549 if (pcl818_ai_dropout(dev, s, chan))
550 return;
551
552 comedi_buf_write_samples(s, &val, 1);
553
554 pcl818_ai_next_chan(dev, s);
555} 500}
556 501
557static void pcl818_handle_dma(struct comedi_device *dev, 502static void pcl818_handle_dma(struct comedi_device *dev,
558 struct comedi_subdevice *s) 503 struct comedi_subdevice *s)
559{ 504{
560 struct pcl818_private *devpriv = dev->private; 505 struct pcl818_private *devpriv = dev->private;
561 unsigned short *ptr; 506 struct comedi_isadma *dma = devpriv->dma;
507 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
508 unsigned short *ptr = desc->virt_addr;
509 unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
562 unsigned int chan; 510 unsigned int chan;
563 unsigned int val; 511 unsigned int val;
564 int i, len, bufptr; 512 int i;
565
566 pcl818_ai_setup_next_dma(dev, s);
567
568 ptr = (unsigned short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
569 513
570 len = devpriv->hwdmasize >> 1; 514 /* restart dma with the next buffer */
571 bufptr = 0; 515 dma->cur_dma = 1 - dma->cur_dma;
516 pcl818_ai_setup_dma(dev, s, nsamples);
572 517
573 for (i = 0; i < len; i++) { 518 for (i = 0; i < nsamples; i++) {
574 val = ptr[bufptr++]; 519 val = ptr[i];
575 chan = val & 0xf; 520 chan = val & 0xf;
576 val = (val >> 4) & s->maxdata; 521 val = (val >> 4) & s->maxdata;
577 522 if (!pcl818_ai_write_sample(dev, s, chan, val))
578 if (pcl818_ai_dropout(dev, s, chan))
579 break;
580
581 comedi_buf_write_samples(s, &val, 1);
582
583 if (!pcl818_ai_next_chan(dev, s))
584 break; 523 break;
585 } 524 }
586} 525}
@@ -597,14 +536,14 @@ static void pcl818_handle_fifo(struct comedi_device *dev,
597 536
598 if (status & 4) { 537 if (status & 4) {
599 dev_err(dev->class_dev, "A/D mode1/3 FIFO overflow!\n"); 538 dev_err(dev->class_dev, "A/D mode1/3 FIFO overflow!\n");
600 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 539 s->async->events |= COMEDI_CB_ERROR;
601 return; 540 return;
602 } 541 }
603 542
604 if (status & 1) { 543 if (status & 1) {
605 dev_err(dev->class_dev, 544 dev_err(dev->class_dev,
606 "A/D mode1/3 FIFO interrupt without data!\n"); 545 "A/D mode1/3 FIFO interrupt without data!\n");
607 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 546 s->async->events |= COMEDI_CB_ERROR;
608 return; 547 return;
609 } 548 }
610 549
@@ -615,13 +554,7 @@ static void pcl818_handle_fifo(struct comedi_device *dev,
615 554
616 for (i = 0; i < len; i++) { 555 for (i = 0; i < len; i++) {
617 val = pcl818_ai_get_fifo_sample(dev, s, &chan); 556 val = pcl818_ai_get_fifo_sample(dev, s, &chan);
618 557 if (!pcl818_ai_write_sample(dev, s, chan, val))
619 if (pcl818_ai_dropout(dev, s, chan))
620 break;
621
622 comedi_buf_write_samples(s, &val, 1);
623
624 if (!pcl818_ai_next_chan(dev, s))
625 break; 558 break;
626 } 559 }
627} 560}
@@ -687,7 +620,8 @@ static int check_channel_list(struct comedi_device *dev,
687 break; 620 break;
688 nowmustbechan = 621 nowmustbechan =
689 (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; 622 (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
690 if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ 623 if (nowmustbechan != CR_CHAN(chanlist[i])) {
624 /* channel list isn't continuous :-( */
691 dev_dbg(dev->class_dev, 625 dev_dbg(dev->class_dev,
692 "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", 626 "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
693 i, CR_CHAN(chanlist[i]), nowmustbechan, 627 i, CR_CHAN(chanlist[i]), nowmustbechan,
@@ -804,6 +738,7 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
804 struct comedi_subdevice *s) 738 struct comedi_subdevice *s)
805{ 739{
806 struct pcl818_private *devpriv = dev->private; 740 struct pcl818_private *devpriv = dev->private;
741 struct comedi_isadma *dma = devpriv->dma;
807 struct comedi_cmd *cmd = &s->async->cmd; 742 struct comedi_cmd *cmd = &s->async->cmd;
808 unsigned int ctrl = 0; 743 unsigned int ctrl = 0;
809 unsigned int seglen; 744 unsigned int seglen;
@@ -818,11 +753,9 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
818 return -EINVAL; 753 return -EINVAL;
819 pcl818_ai_setup_chanlist(dev, cmd->chanlist, seglen); 754 pcl818_ai_setup_chanlist(dev, cmd->chanlist, seglen);
820 755
821 devpriv->ai_data_len = s->async->prealloc_bufsz;
822 devpriv->ai_cmd_running = 1; 756 devpriv->ai_cmd_running = 1;
823 devpriv->ai_cmd_canceled = 0; 757 devpriv->ai_cmd_canceled = 0;
824 devpriv->act_chanlist_pos = 0; 758 devpriv->act_chanlist_pos = 0;
825 devpriv->dma_runs_to_end = 0;
826 759
827 if (cmd->convert_src == TRIG_TIMER) 760 if (cmd->convert_src == TRIG_TIMER)
828 ctrl |= PCL818_CTRL_PACER_TRIG; 761 ctrl |= PCL818_CTRL_PACER_TRIG;
@@ -831,8 +764,10 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
831 764
832 outb(PCL818_CNTENABLE_PACER_ENA, dev->iobase + PCL818_CNTENABLE_REG); 765 outb(PCL818_CNTENABLE_PACER_ENA, dev->iobase + PCL818_CNTENABLE_REG);
833 766
834 if (devpriv->dma) { 767 if (dma) {
835 pcl818_ai_setup_dma(dev, s); 768 /* setup and enable dma for the first buffer */
769 dma->cur_dma = 0;
770 pcl818_ai_setup_dma(dev, s, 0);
836 771
837 ctrl |= PCL818_CTRL_INTE | PCL818_CTRL_IRQ(dev->irq) | 772 ctrl |= PCL818_CTRL_INTE | PCL818_CTRL_IRQ(dev->irq) |
838 PCL818_CTRL_DMAE; 773 PCL818_CTRL_DMAE;
@@ -854,12 +789,13 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
854 struct comedi_subdevice *s) 789 struct comedi_subdevice *s)
855{ 790{
856 struct pcl818_private *devpriv = dev->private; 791 struct pcl818_private *devpriv = dev->private;
792 struct comedi_isadma *dma = devpriv->dma;
857 struct comedi_cmd *cmd = &s->async->cmd; 793 struct comedi_cmd *cmd = &s->async->cmd;
858 794
859 if (!devpriv->ai_cmd_running) 795 if (!devpriv->ai_cmd_running)
860 return 0; 796 return 0;
861 797
862 if (devpriv->dma) { 798 if (dma) {
863 if (cmd->stop_src == TRIG_NONE || 799 if (cmd->stop_src == TRIG_NONE ||
864 (cmd->stop_src == TRIG_COUNT && 800 (cmd->stop_src == TRIG_COUNT &&
865 s->async->scans_done < cmd->stop_arg)) { 801 s->async->scans_done < cmd->stop_arg)) {
@@ -872,7 +808,7 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
872 return 0; 808 return 0;
873 } 809 }
874 } 810 }
875 disable_dma(devpriv->dma); 811 comedi_isadma_disable(dma->chan);
876 } 812 }
877 813
878 outb(PCL818_CTRL_DISABLE_TRIG, dev->iobase + PCL818_CTRL_REG); 814 outb(PCL818_CTRL_DISABLE_TRIG, dev->iobase + PCL818_CTRL_REG);
@@ -1054,13 +990,33 @@ static void pcl818_set_ai_range_table(struct comedi_device *dev,
1054 } 990 }
1055} 991}
1056 992
993static void pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
994{
995 struct pcl818_private *devpriv = dev->private;
996
997 /* only DMA channels 3 and 1 are valid */
998 if (!(dma_chan == 3 || dma_chan == 1))
999 return;
1000
1001 /* DMA uses two 16K buffers */
1002 devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
1003 PAGE_SIZE * 4, COMEDI_ISADMA_READ);
1004}
1005
1006static void pcl818_free_dma(struct comedi_device *dev)
1007{
1008 struct pcl818_private *devpriv = dev->private;
1009
1010 if (devpriv)
1011 comedi_isadma_free(devpriv->dma);
1012}
1013
1057static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1014static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1058{ 1015{
1059 const struct pcl818_board *board = dev->board_ptr; 1016 const struct pcl818_board *board = dev->board_ptr;
1060 struct pcl818_private *devpriv; 1017 struct pcl818_private *devpriv;
1061 struct comedi_subdevice *s; 1018 struct comedi_subdevice *s;
1062 int ret; 1019 int ret;
1063 int i;
1064 1020
1065 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1021 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1066 if (!devpriv) 1022 if (!devpriv)
@@ -1084,31 +1040,8 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1084 devpriv->usefifo = 1; 1040 devpriv->usefifo = 1;
1085 1041
1086 /* we need an IRQ to do DMA on channel 3 or 1 */ 1042 /* we need an IRQ to do DMA on channel 3 or 1 */
1087 if (dev->irq && board->has_dma && 1043 if (dev->irq && board->has_dma)
1088 (it->options[2] == 3 || it->options[2] == 1)) { 1044 pcl818_alloc_dma(dev, it->options[2]);
1089 ret = request_dma(it->options[2], dev->board_name);
1090 if (ret) {
1091 dev_err(dev->class_dev,
1092 "unable to request DMA channel %d\n",
1093 it->options[2]);
1094 return -EBUSY;
1095 }
1096 devpriv->dma = it->options[2];
1097
1098 devpriv->dmapages = 2; /* we need 16KB */
1099 devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
1100
1101 for (i = 0; i < 2; i++) {
1102 unsigned long dmabuf;
1103
1104 dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
1105 if (!dmabuf)
1106 return -ENOMEM;
1107
1108 devpriv->dmabuf[i] = dmabuf;
1109 devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
1110 }
1111 }
1112 1045
1113 ret = comedi_alloc_subdevices(dev, 4); 1046 ret = comedi_alloc_subdevices(dev, 4);
1114 if (ret) 1047 if (ret)
@@ -1194,8 +1127,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1194 devpriv->ns_min = board->ns_min; 1127 devpriv->ns_min = board->ns_min;
1195 1128
1196 if (!board->is_818) { 1129 if (!board->is_818) {
1197 if ((it->options[6] == 1) || (it->options[6] == 100)) 1130 if ((it->options[6] == 1) || (it->options[6] == 100)) {
1198 devpriv->ns_min = 10000; /* extended PCL718 to 100kHz DAC */ 1131 /* extended PCL718 to 100kHz DAC */
1132 devpriv->ns_min = 10000;
1133 }
1199 } 1134 }
1200 1135
1201 pcl818_reset(dev); 1136 pcl818_reset(dev);
@@ -1210,13 +1145,8 @@ static void pcl818_detach(struct comedi_device *dev)
1210 if (devpriv) { 1145 if (devpriv) {
1211 pcl818_ai_cancel(dev, dev->read_subdev); 1146 pcl818_ai_cancel(dev, dev->read_subdev);
1212 pcl818_reset(dev); 1147 pcl818_reset(dev);
1213 if (devpriv->dma)
1214 free_dma(devpriv->dma);
1215 if (devpriv->dmabuf[0])
1216 free_pages(devpriv->dmabuf[0], devpriv->dmapages);
1217 if (devpriv->dmabuf[1])
1218 free_pages(devpriv->dmabuf[1], devpriv->dmapages);
1219 } 1148 }
1149 pcl818_free_dma(dev);
1220 comedi_legacy_detach(dev); 1150 comedi_legacy_detach(dev);
1221} 1151}
1222 1152
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index e3ac8ac6190e..12f94fe82f5b 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: pcmad 20 * Driver: pcmad
21 * Description: Winsystems PCM-A/D12, PCM-A/D16 21 * Description: Winsystems PCM-A/D12, PCM-A/D16
22 * Devices: (Winsystems) PCM-A/D12 [pcmad12] 22 * Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
23 * (Winsystems) PCM-A/D16 [pcmad16]
24 * Author: ds 23 * Author: ds
25 * Status: untested 24 * Status: untested
26 * 25 *
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
index 59108c06cedc..d86c5e2cd0c7 100644
--- a/drivers/staging/comedi/drivers/pcmda12.c
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -19,7 +19,7 @@
19/* 19/*
20 * Driver: pcmda12 20 * Driver: pcmda12
21 * Description: A driver for the Winsystems PCM-D/A-12 21 * Description: A driver for the Winsystems PCM-D/A-12
22 * Devices: (Winsystems) PCM-D/A-12 [pcmda12] 22 * Devices: [Winsystems] PCM-D/A-12 (pcmda12)
23 * Author: Calin Culianu <calin@ajvar.org> 23 * Author: Calin Culianu <calin@ajvar.org>
24 * Updated: Fri, 13 Jan 2006 12:01:01 -0500 24 * Updated: Fri, 13 Jan 2006 12:01:01 -0500
25 * Status: works 25 * Status: works
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index f0059e935da0..2c0e7ecbf494 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -19,7 +19,7 @@
19/* 19/*
20 * Driver: pcmmio 20 * Driver: pcmmio
21 * Description: A driver for the PCM-MIO multifunction board 21 * Description: A driver for the PCM-MIO multifunction board
22 * Devices: (Winsystems) PCM-MIO [pcmmio] 22 * Devices: [Winsystems] PCM-MIO (pcmmio)
23 * Author: Calin Culianu <calin@ajvar.org> 23 * Author: Calin Culianu <calin@ajvar.org>
24 * Updated: Wed, May 16 2007 16:21:10 -0500 24 * Updated: Wed, May 16 2007 16:21:10 -0500
25 * Status: works 25 * Status: works
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 0f5483b6147f..a1641d981812 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: pcmuio 20 * Driver: pcmuio
21 * Description: Winsystems PC-104 based 48/96-channel DIO boards. 21 * Description: Winsystems PC-104 based 48/96-channel DIO boards.
22 * Devices: (Winsystems) PCM-UIO48A [pcmuio48] 22 * Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
23 * (Winsystems) PCM-UIO96A [pcmuio96]
24 * Author: Calin Culianu <calin@ajvar.org> 23 * Author: Calin Culianu <calin@ajvar.org>
25 * Updated: Fri, 13 Jan 2006 12:01:01 -0500 24 * Updated: Fri, 13 Jan 2006 12:01:01 -0500
26 * Status: works 25 * Status: works
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 96098110b0b3..8387fd0e4b7e 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -48,15 +48,10 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
48*/ 48*/
49 49
50#include <linux/module.h> 50#include <linux/module.h>
51#include "../comedidev.h"
52#include <linux/semaphore.h> 51#include <linux/semaphore.h>
53
54#include <pcmcia/cistpl.h>
55#include <pcmcia/cisreg.h>
56#include <pcmcia/ds.h>
57
58#include <linux/completion.h> 52#include <linux/completion.h>
59 53
54#include "../comedi_pcmcia.h"
60#include "comedi_fc.h" 55#include "comedi_fc.h"
61 56
62struct daqp_private { 57struct daqp_private {
@@ -210,8 +205,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
210 unsigned short data; 205 unsigned short data;
211 206
212 if (status & DAQP_STATUS_DATA_LOST) { 207 if (status & DAQP_STATUS_DATA_LOST) {
213 s->async->events |= 208 s->async->events |= COMEDI_CB_OVERFLOW;
214 COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
215 dev_warn(dev->class_dev, "data lost\n"); 209 dev_warn(dev->class_dev, "data lost\n");
216 break; 210 break;
217 } 211 }
@@ -239,7 +233,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
239 if (loop_limit <= 0) { 233 if (loop_limit <= 0) {
240 dev_warn(dev->class_dev, 234 dev_warn(dev->class_dev,
241 "loop_limit reached in daqp_interrupt()\n"); 235 "loop_limit reached in daqp_interrupt()\n");
242 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 236 s->async->events |= COMEDI_CB_ERROR;
243 } 237 }
244 238
245 comedi_handle_events(dev, s); 239 comedi_handle_events(dev, s);
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 581aa58d9c0a..c94ad12ed446 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -19,10 +19,8 @@
19/* 19/*
20 * Driver: rtd520 20 * Driver: rtd520
21 * Description: Real Time Devices PCI4520/DM7520 21 * Description: Real Time Devices PCI4520/DM7520
22 * Devices: (Real Time Devices) DM7520HR-1 [DM7520] 22 * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8,
23 * (Real Time Devices) DM7520HR-8 [DM7520] 23 * PCI4520 (PCI4520), PCI4520-8
24 * (Real Time Devices) PCI4520 [PCI4520]
25 * (Real Time Devices) PCI4520-8 [PCI4520]
26 * Author: Dan Christian 24 * Author: Dan Christian
27 * Status: Works. Only tested on DM7520-8. Not SMP safe. 25 * Status: Works. Only tested on DM7520-8. Not SMP safe.
28 * 26 *
@@ -1014,10 +1012,8 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1014 readw(dev->mmio + LAS0_CLEAR); 1012 readw(dev->mmio + LAS0_CLEAR);
1015 1013
1016 /* TODO: allow multiple interrupt sources */ 1014 /* TODO: allow multiple interrupt sources */
1017 if (devpriv->xfer_count > 0) /* transfer every N samples */ 1015 /* transfer every N samples */
1018 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT); 1016 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
1019 else /* 1/2 FIFO transfers */
1020 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
1021 1017
1022 /* BUG: start_src is ASSUMED to be TRIG_NOW */ 1018 /* BUG: start_src is ASSUMED to be TRIG_NOW */
1023 /* BUG? it seems like things are running before the "start" */ 1019 /* BUG? it seems like things are running before the "start" */
@@ -1031,8 +1027,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1031static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 1027static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1032{ 1028{
1033 struct rtd_private *devpriv = dev->private; 1029 struct rtd_private *devpriv = dev->private;
1034 u32 overrun;
1035 u16 status;
1036 1030
1037 /* pacer stop source: SOFTWARE */ 1031 /* pacer stop source: SOFTWARE */
1038 writel(0, dev->mmio + LAS0_PACER_STOP); 1032 writel(0, dev->mmio + LAS0_PACER_STOP);
@@ -1040,8 +1034,6 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1040 writel(0, dev->mmio + LAS0_ADC_CONVERSION); 1034 writel(0, dev->mmio + LAS0_ADC_CONVERSION);
1041 writew(0, dev->mmio + LAS0_IT); 1035 writew(0, dev->mmio + LAS0_IT);
1042 devpriv->ai_count = 0; /* stop and don't transfer any more */ 1036 devpriv->ai_count = 0; /* stop and don't transfer any more */
1043 status = readw(dev->mmio + LAS0_IT);
1044 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
1045 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 1037 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1046 return 0; 1038 return 0;
1047} 1039}
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index 67b4b378bd01..340ac776e951 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -19,8 +19,7 @@
19/* 19/*
20 * Driver: rti800 20 * Driver: rti800
21 * Description: Analog Devices RTI-800/815 21 * Description: Analog Devices RTI-800/815
22 * Devices: (Analog Devices) RTI-800 [rti800] 22 * Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
23 * (Analog Devices) RTI-815 [rti815]
24 * Author: David A. Schleef <ds@schleef.org> 23 * Author: David A. Schleef <ds@schleef.org>
25 * Status: unknown 24 * Status: unknown
26 * Updated: Fri, 05 Sep 2008 14:50:44 +0100 25 * Updated: Fri, 05 Sep 2008 14:50:44 +0100
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index 96c3974207ae..6db58fcfd496 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -20,7 +20,7 @@
20 * Driver: rti802 20 * Driver: rti802
21 * Description: Analog Devices RTI-802 21 * Description: Analog Devices RTI-802
22 * Author: Anders Blomdell <anders.blomdell@control.lth.se> 22 * Author: Anders Blomdell <anders.blomdell@control.lth.se>
23 * Devices: (Analog Devices) RTI-802 [rti802] 23 * Devices: [Analog Devices] RTI-802 (rti802)
24 * Status: works 24 * Status: works
25 * 25 *
26 * Configuration Options: 26 * Configuration Options:
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 14932c5f3798..fc497dd92021 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -118,7 +118,7 @@ static void s626_mc_enable(struct comedi_device *dev,
118static void s626_mc_disable(struct comedi_device *dev, 118static void s626_mc_disable(struct comedi_device *dev,
119 unsigned int cmd, unsigned int reg) 119 unsigned int cmd, unsigned int reg)
120{ 120{
121 writel(cmd << 16 , dev->mmio + reg); 121 writel(cmd << 16, dev->mmio + reg);
122 mmiowb(); 122 mmiowb();
123} 123}
124 124
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 4737dbf8e01d..1cd7403a4e9c 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -16,10 +16,11 @@
16/* 16/*
17 * Driver: usbdux 17 * Driver: usbdux
18 * Description: University of Stirling USB DAQ & INCITE Technology Limited 18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
19 * Devices: (ITL) USB-DUX [usbdux] 19 * Devices: [ITL] USB-DUX (usbdux)
20 * Author: Bernd Porr <mail@berndporr.me.uk> 20 * Author: Bernd Porr <mail@berndporr.me.uk>
21 * Updated: 10 Oct 2014 21 * Updated: 10 Oct 2014
22 * Status: Stable 22 * Status: Stable
23 *
23 * Connection scheme for the counter at the digital port: 24 * Connection scheme for the counter at the digital port:
24 * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1. 25 * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
25 * The sampling rate of the counter is approximately 500Hz. 26 * The sampling rate of the counter is approximately 500Hz.
@@ -79,11 +80,10 @@
79#include <linux/module.h> 80#include <linux/module.h>
80#include <linux/slab.h> 81#include <linux/slab.h>
81#include <linux/input.h> 82#include <linux/input.h>
82#include <linux/usb.h>
83#include <linux/fcntl.h> 83#include <linux/fcntl.h>
84#include <linux/compiler.h> 84#include <linux/compiler.h>
85 85
86#include "../comedidev.h" 86#include "../comedi_usb.h"
87 87
88#include "comedi_fc.h" 88#include "comedi_fc.h"
89 89
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index ddc4cb9d5ed4..7ce27c16c2f9 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -15,7 +15,7 @@
15/* 15/*
16 * Driver: usbduxfast 16 * Driver: usbduxfast
17 * Description: University of Stirling USB DAQ & INCITE Technology Limited 17 * Description: University of Stirling USB DAQ & INCITE Technology Limited
18 * Devices: (ITL) USB-DUX [usbduxfast] 18 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
19 * Author: Bernd Porr <mail@berndporr.me.uk> 19 * Author: Bernd Porr <mail@berndporr.me.uk>
20 * Updated: 10 Oct 2014 20 * Updated: 10 Oct 2014
21 * Status: stable 21 * Status: stable
@@ -46,11 +46,10 @@
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/input.h> 48#include <linux/input.h>
49#include <linux/usb.h>
50#include <linux/fcntl.h> 49#include <linux/fcntl.h>
51#include <linux/compiler.h> 50#include <linux/compiler.h>
52#include "comedi_fc.h" 51#include "comedi_fc.h"
53#include "../comedidev.h" 52#include "../comedi_usb.h"
54 53
55/* 54/*
56 * timeout for the USB-transfer 55 * timeout for the USB-transfer
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index dc19435b6520..394969b7458c 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -16,7 +16,7 @@
16/* 16/*
17 * Driver: usbduxsigma 17 * Driver: usbduxsigma
18 * Description: University of Stirling USB DAQ & INCITE Technology Limited 18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
19 * Devices: (ITL) USB-DUX [usbduxsigma] 19 * Devices: [ITL] USB-DUX-SIGMA (usbduxsigma)
20 * Author: Bernd Porr <mail@berndporr.me.uk> 20 * Author: Bernd Porr <mail@berndporr.me.uk>
21 * Updated: 10 Oct 2014 21 * Updated: 10 Oct 2014
22 * Status: stable 22 * Status: stable
@@ -45,13 +45,12 @@
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/slab.h> 46#include <linux/slab.h>
47#include <linux/input.h> 47#include <linux/input.h>
48#include <linux/usb.h>
49#include <linux/fcntl.h> 48#include <linux/fcntl.h>
50#include <linux/compiler.h> 49#include <linux/compiler.h>
51#include <asm/unaligned.h> 50#include <asm/unaligned.h>
52 51
53#include "comedi_fc.h" 52#include "comedi_fc.h"
54#include "../comedidev.h" 53#include "../comedi_usb.h"
55 54
56/* timeout for the USB-transfer in ms*/ 55/* timeout for the USB-transfer in ms*/
57#define BULK_TIMEOUT 1000 56#define BULK_TIMEOUT 1000
@@ -215,7 +214,6 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
215 struct usbduxsigma_private *devpriv = dev->private; 214 struct usbduxsigma_private *devpriv = dev->private;
216 struct comedi_async *async = s->async; 215 struct comedi_async *async = s->async;
217 struct comedi_cmd *cmd = &async->cmd; 216 struct comedi_cmd *cmd = &async->cmd;
218 unsigned int dio_state;
219 uint32_t val; 217 uint32_t val;
220 int ret; 218 int ret;
221 int i; 219 int i;
@@ -224,9 +222,6 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
224 if (devpriv->ai_counter == 0) { 222 if (devpriv->ai_counter == 0) {
225 devpriv->ai_counter = devpriv->ai_timer; 223 devpriv->ai_counter = devpriv->ai_timer;
226 224
227 /* get the state of the dio pins to allow external trigger */
228 dio_state = be32_to_cpu(devpriv->in_buf[0]);
229
230 /* get the data from the USB bus and hand it over to comedi */ 225 /* get the data from the USB bus and hand it over to comedi */
231 for (i = 0; i < cmd->chanlist_len; i++) { 226 for (i = 0; i < cmd->chanlist_len; i++) {
232 /* transfer data, note first byte is the DIO state */ 227 /* transfer data, note first byte is the DIO state */
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index a19a56ee0eef..e37118321a27 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -18,21 +18,22 @@
18 GNU General Public License for more details. 18 GNU General Public License for more details.
19*/ 19*/
20/* 20/*
21Driver: vmk80xx 21 * Driver: vmk80xx
22Description: Velleman USB Board Low-Level Driver 22 * Description: Velleman USB Board Low-Level Driver
23Devices: K8055/K8061 aka VM110/VM140 23 * Devices: [Velleman] K8055 (K8055/VM110), K8061 (K8061/VM140),
24Author: Manuel Gebele <forensixs@gmx.de> 24 * VM110 (K8055/VM110), VM140 (K8061/VM140)
25Updated: Sun, 10 May 2009 11:14:59 +0200 25 * Author: Manuel Gebele <forensixs@gmx.de>
26Status: works 26 * Updated: Sun, 10 May 2009 11:14:59 +0200
27 27 * Status: works
28Supports: 28 *
29 - analog input 29 * Supports:
30 - analog output 30 * - analog input
31 - digital input 31 * - analog output
32 - digital output 32 * - digital input
33 - counter 33 * - digital output
34 - pwm 34 * - counter
35*/ 35 * - pwm
36 */
36 37
37#include <linux/kernel.h> 38#include <linux/kernel.h>
38#include <linux/module.h> 39#include <linux/module.h>
@@ -41,10 +42,9 @@ Supports:
41#include <linux/input.h> 42#include <linux/input.h>
42#include <linux/slab.h> 43#include <linux/slab.h>
43#include <linux/poll.h> 44#include <linux/poll.h>
44#include <linux/usb.h>
45#include <linux/uaccess.h> 45#include <linux/uaccess.h>
46 46
47#include "../comedidev.h" 47#include "../comedi_usb.h"
48 48
49enum { 49enum {
50 DEVICE_VMK8055, 50 DEVICE_VMK8055,
@@ -550,41 +550,35 @@ static int vmk80xx_cnt_insn_config(struct comedi_device *dev,
550 unsigned int *data) 550 unsigned int *data)
551{ 551{
552 struct vmk80xx_private *devpriv = dev->private; 552 struct vmk80xx_private *devpriv = dev->private;
553 unsigned int insn_cmd; 553 unsigned int chan = CR_CHAN(insn->chanspec);
554 int chan;
555 int cmd; 554 int cmd;
556 int reg; 555 int reg;
557 int n; 556 int ret;
558
559 insn_cmd = data[0];
560 if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET)
561 return -EINVAL;
562 557
563 down(&devpriv->limit_sem); 558 down(&devpriv->limit_sem);
564 559 switch (data[0]) {
565 chan = CR_CHAN(insn->chanspec); 560 case INSN_CONFIG_RESET:
566 561 if (devpriv->model == VMK8055_MODEL) {
567 if (devpriv->model == VMK8055_MODEL) { 562 if (!chan) {
568 if (!chan) { 563 cmd = VMK8055_CMD_RST_CNT1;
569 cmd = VMK8055_CMD_RST_CNT1; 564 reg = VMK8055_CNT1_REG;
570 reg = VMK8055_CNT1_REG; 565 } else {
566 cmd = VMK8055_CMD_RST_CNT2;
567 reg = VMK8055_CNT2_REG;
568 }
569 devpriv->usb_tx_buf[reg] = 0x00;
571 } else { 570 } else {
572 cmd = VMK8055_CMD_RST_CNT2; 571 cmd = VMK8061_CMD_RST_CNT;
573 reg = VMK8055_CNT2_REG;
574 } 572 }
575 573 ret = vmk80xx_write_packet(dev, cmd);
576 devpriv->usb_tx_buf[reg] = 0x00; 574 break;
577 } else { 575 default:
578 cmd = VMK8061_CMD_RST_CNT; 576 ret = -EINVAL;
577 break;
579 } 578 }
580
581 for (n = 0; n < insn->n; n++)
582 if (vmk80xx_write_packet(dev, cmd))
583 break;
584
585 up(&devpriv->limit_sem); 579 up(&devpriv->limit_sem);
586 580
587 return n; 581 return ret ? ret : insn->n;
588} 582}
589 583
590static int vmk80xx_cnt_insn_write(struct comedi_device *dev, 584static int vmk80xx_cnt_insn_write(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/z8536.h b/drivers/staging/comedi/drivers/z8536.h
new file mode 100644
index 000000000000..7be53109cc8d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/z8536.h
@@ -0,0 +1,202 @@
1/*
2 * Z8536 CIO Internal registers
3 */
4
5#ifndef _Z8536_H
6#define _Z8536_H
7
8/* Master Interrupt Control register */
9#define Z8536_INT_CTRL_REG 0x00
10#define Z8536_INT_CTRL_MIE BIT(7) /* Master Interrupt Enable */
11#define Z8536_INT_CTRL_DLC BIT(6) /* Disable Lower Chain */
12#define Z8536_INT_CTRL_NV BIT(5) /* No Vector */
13#define Z8536_INT_CTRL_PA_VIS BIT(4) /* Port A Vect Inc Status */
14#define Z8536_INT_CTRL_PB_VIS BIT(3) /* Port B Vect Inc Status */
15#define Z8536_INT_CTRL_VT_VIS BIT(2) /* C/T Vect Inc Status */
16#define Z8536_INT_CTRL_RJA BIT(1) /* Right Justified Addresses */
17#define Z8536_INT_CTRL_RESET BIT(0) /* Reset */
18
19/* Master Configuration Control register */
20#define Z8536_CFG_CTRL_REG 0x01
21#define Z8536_CFG_CTRL_PBE BIT(7) /* Port B Enable */
22#define Z8536_CFG_CTRL_CT1E BIT(6) /* C/T 1 Enable */
23#define Z8536_CFG_CTRL_CT2E BIT(5) /* C/T 2 Enable */
24#define Z8536_CFG_CTRL_PCE_CT3E BIT(4) /* Port C & C/T 3 Enable */
25#define Z8536_CFG_CTRL_PLC BIT(3) /* Port A/B Link Control */
26#define Z8536_CFG_CTRL_PAE BIT(2) /* Port A Enable */
27#define Z8536_CFG_CTRL_LC_INDEP (0 << 0)/* C/Ts Independent */
28#define Z8536_CFG_CTRL_LC_GATE (1 << 0)/* C/T 1 Out Gates C/T 2 */
29#define Z8536_CFG_CTRL_LC_TRIG (2 << 0)/* C/T 1 Out Triggers C/T 2 */
30#define Z8536_CFG_CTRL_LC_CLK (3 << 0)/* C/T 1 Out Clocks C/T 2 */
31#define Z8536_CFG_CTRL_LC_MASK (3 << 0)/* C/T Link Control mask */
32
33/* Interrupt Vector registers */
34#define Z8536_PA_INT_VECT_REG 0x02
35#define Z8536_PB_INT_VECT_REG 0x03
36#define Z8536_CT_INT_VECT_REG 0x04
37#define Z8536_CURR_INT_VECT_REG 0x1f
38
39/* Port A/B & Counter/Timer 1/2/3 Command and Status registers */
40#define Z8536_PA_CMDSTAT_REG 0x08
41#define Z8536_PB_CMDSTAT_REG 0x09
42#define Z8536_CT1_CMDSTAT_REG 0x0a
43#define Z8536_CT2_CMDSTAT_REG 0x0b
44#define Z8536_CT3_CMDSTAT_REG 0x0c
45#define Z8536_CT_CMDSTAT_REG(x) (0x0a + (x))
46#define Z8536_CMD_NULL (0 << 5)/* Null Code */
47#define Z8536_CMD_CLR_IP_IUS (1 << 5)/* Clear IP & IUS */
48#define Z8536_CMD_SET_IUS (2 << 5)/* Set IUS */
49#define Z8536_CMD_CLR_IUS (3 << 5)/* Clear IUS */
50#define Z8536_CMD_SET_IP (4 << 5)/* Set IP */
51#define Z8536_CMD_CLR_IP (5 << 5)/* Clear IP */
52#define Z8536_CMD_SET_IE (6 << 5)/* Set IE */
53#define Z8536_CMD_CLR_IE (7 << 5)/* Clear IE */
54#define Z8536_CMD_MASK (7 << 5)
55
56#define Z8536_STAT_IUS BIT(7) /* Interrupt Under Service */
57#define Z8536_STAT_IE BIT(6) /* Interrupt Enable */
58#define Z8536_STAT_IP BIT(5) /* Interrupt Pending */
59#define Z8536_STAT_ERR BIT(4) /* Interrupt Error */
60#define Z8536_STAT_IE_IP (Z8536_STAT_IE | Z8536_STAT_IP)
61
62#define Z8536_PAB_STAT_ORE BIT(3) /* Output Register Empty */
63#define Z8536_PAB_STAT_IRF BIT(2) /* Input Register Full */
64#define Z8536_PAB_STAT_PMF BIT(1) /* Pattern Match Flag */
65#define Z8536_PAB_CMDSTAT_IOE BIT(0) /* Interrupt On Error */
66
67#define Z8536_CT_CMD_RCC BIT(3) /* Read Counter Control */
68#define Z8536_CT_CMDSTAT_GCB BIT(2) /* Gate Command Bit */
69#define Z8536_CT_CMD_TCB BIT(1) /* Trigger Command Bit */
70#define Z8536_CT_STAT_CIP BIT(0) /* Count In Progress */
71
72/* Port Data registers */
73#define Z8536_PA_DATA_REG 0x0d
74#define Z8536_PB_DATA_REG 0x0e
75#define Z8536_PC_DATA_REG 0x0f
76
77/* Counter/Timer 1/2/3 Current Count registers */
78#define Z8536_CT1_VAL_MSB_REG 0x10
79#define Z8536_CT1_VAL_LSB_REG 0x11
80#define Z8536_CT2_VAL_MSB_REG 0x12
81#define Z8536_CT2_VAL_LSB_REG 0x13
82#define Z8536_CT3_VAL_MSB_REG 0x14
83#define Z8536_CT3_VAL_LSB_REG 0x15
84#define Z8536_CT_VAL_MSB_REG(x) (0x10 + ((x) * 2))
85#define Z8536_CT_VAL_LSB_REG(x) (0x11 + ((x) * 2))
86
87/* Counter/Timer 1/2/3 Time Constant registers */
88#define Z8536_CT1_RELOAD_MSB_REG 0x16
89#define Z8536_CT1_RELOAD_LSB_REG 0x17
90#define Z8536_CT2_RELOAD_MSB_REG 0x18
91#define Z8536_CT2_RELOAD_LSB_REG 0x19
92#define Z8536_CT3_RELOAD_MSB_REG 0x1a
93#define Z8536_CT3_RELOAD_LSB_REG 0x1b
94#define Z8536_CT_RELOAD_MSB_REG(x) (0x16 + ((x) * 2))
95#define Z8536_CT_RELOAD_LSB_REG(x) (0x17 + ((x) * 2))
96
97/* Counter/Timer 1/2/3 Mode Specification registers */
98#define Z8536_CT1_MODE_REG 0x1c
99#define Z8536_CT2_MODE_REG 0x1d
100#define Z8536_CT3_MODE_REG 0x1e
101#define Z8536_CT_MODE_REG(x) (0x1c + (x))
102#define Z8536_CT_MODE_CSC BIT(7) /* Continuous/Single Cycle */
103#define Z8536_CT_MODE_EOE BIT(6) /* External Output Enable */
104#define Z8536_CT_MODE_ECE BIT(5) /* External Count Enable */
105#define Z8536_CT_MODE_ETE BIT(4) /* External Trigger Enable */
106#define Z8536_CT_MODE_EGE BIT(3) /* External Gate Enable */
107#define Z8536_CT_MODE_REB BIT(2) /* Retrigger Enable Bit */
108#define Z8536_CT_MODE_DCS_PULSE (0 << 0)/* Duty Cycle - Pulse */
109#define Z8536_CT_MODE_DCS_ONESHOT (1 << 0)/* Duty Cycle - One-Shot */
110#define Z8536_CT_MODE_DCS_SQRWAVE (2 << 0)/* Duty Cycle - Square Wave */
111#define Z8536_CT_MODE_DCS_DO_NOT_USE (3 << 0)/* Duty Cycle - Do Not Use */
112#define Z8536_CT_MODE_DCS_MASK (3 << 0)/* Duty Cycle mask */
113
114/* Port A/B Mode Specification registers */
115#define Z8536_PA_MODE_REG 0x20
116#define Z8536_PB_MODE_REG 0x28
117#define Z8536_PAB_MODE_PTS_BIT (0 << 6)/* Bit Port */
118#define Z8536_PAB_MODE_PTS_INPUT (1 << 6)/* Input Port */
119#define Z8536_PAB_MODE_PTS_OUTPUT (2 << 6)/* Output Port */
120#define Z8536_PAB_MODE_PTS_BIDIR (3 << 6)/* Bidirectional Port */
121#define Z8536_PAB_MODE_PTS_MASK (3 << 6)/* Port Type Select mask */
122#define Z8536_PAB_MODE_ITB BIT(5) /* Interrupt on Two Bytes */
123#define Z8536_PAB_MODE_SB BIT(4) /* Single Buffered mode */
124#define Z8536_PAB_MODE_IMO BIT(3) /* Interrupt on Match Only */
125#define Z8536_PAB_MODE_PMS_DISABLE (0 << 1)/* Disable Pattern Match */
126#define Z8536_PAB_MODE_PMS_AND (1 << 1)/* "AND" mode */
127#define Z8536_PAB_MODE_PMS_OR (2 << 1)/* "OR" mode */
128#define Z8536_PAB_MODE_PMS_OR_PEV (3 << 1)/* "OR-Priority" mode */
129#define Z8536_PAB_MODE_PMS_MASK (3 << 1)/* Pattern Mode mask */
130#define Z8536_PAB_MODE_LPM BIT(0) /* Latch on Pattern Match */
131#define Z8536_PAB_MODE_DTE BIT(0) /* Deskew Timer Enabled */
132
133/* Port A/B Handshake Specification registers */
134#define Z8536_PA_HANDSHAKE_REG 0x21
135#define Z8536_PB_HANDSHAKE_REG 0x29
136#define Z8536_PAB_HANDSHAKE_HST_INTER (0 << 6)/* Interlocked Handshake */
137#define Z8536_PAB_HANDSHAKE_HST_STROBED (1 << 6)/* Strobed Handshake */
138#define Z8536_PAB_HANDSHAKE_HST_PULSED (2 << 6)/* Pulsed Handshake */
139#define Z8536_PAB_HANDSHAKE_HST_3WIRE (3 << 6)/* Three-Wire Handshake */
140#define Z8536_PAB_HANDSHAKE_HST_MASK (3 << 6)/* Handshake Type mask */
141#define Z8536_PAB_HANDSHAKE_RWS_DISABLE (0 << 3)/* Req/Wait Disabled */
142#define Z8536_PAB_HANDSHAKE_RWS_OUTWAIT (1 << 3)/* Output Wait */
143#define Z8536_PAB_HANDSHAKE_RWS_INWAIT (3 << 3)/* Input Wait */
144#define Z8536_PAB_HANDSHAKE_RWS_SPREQ (4 << 3)/* Special Request */
145#define Z8536_PAB_HANDSHAKE_RWS_OUTREQ (5 << 4)/* Output Request */
146#define Z8536_PAB_HANDSHAKE_RWS_INREQ (7 << 3)/* Input Request */
147#define Z8536_PAB_HANDSHAKE_RWS_MASK (7 << 3)/* Req/Wait mask */
148#define Z8536_PAB_HANDSHAKE_DESKEW(x) ((x) << 0)/* Deskew Time */
149#define Z8536_PAB_HANDSHAKE_DESKEW_MASK (3 << 0)/* Deskew Time mask */
150
151/*
152 * Port A/B/C Data Path Polarity registers
153 *
154 * 0 = Non-Inverting
155 * 1 = Inverting
156 */
157#define Z8536_PA_DPP_REG 0x22
158#define Z8536_PB_DPP_REG 0x2a
159#define Z8536_PC_DPP_REG 0x05
160
161/*
162 * Port A/B/C Data Direction registers
163 *
164 * 0 = Output bit
165 * 1 = Input bit
166 */
167#define Z8536_PA_DD_REG 0x23
168#define Z8536_PB_DD_REG 0x2b
169#define Z8536_PC_DD_REG 0x06
170
171/*
172 * Port A/B/C Special I/O Control registers
173 *
174 * 0 = Normal Input or Output
175 * 1 = Output with open drain or Input with 1's catcher
176 */
177#define Z8536_PA_SIO_REG 0x24
178#define Z8536_PB_SIO_REG 0x2c
179#define Z8536_PC_SIO_REG 0x07
180
181/*
182 * Port A/B Pattern Polarity/Transition/Mask registers
183 *
184 * PM PT PP Pattern Specification
185 * -- -- -- -------------------------------------
186 * 0 0 x Bit masked off
187 * 0 1 x Any transition
188 * 1 0 0 Zero (low-level)
189 * 1 0 1 One (high-level)
190 * 1 1 0 One-to-zero transition (falling-edge)
191 * 1 1 1 Zero-to-one transition (rising-edge)
192 */
193#define Z8536_PA_PP_REG 0x25
194#define Z8536_PB_PP_REG 0x2d
195
196#define Z8536_PA_PT_REG 0x26
197#define Z8536_PB_PT_REG 0x2e
198
199#define Z8536_PA_PM_REG 0x27
200#define Z8536_PB_PM_REG 0x2f
201
202#endif /* _Z8536_H */
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 8777f958c041..973f544e85e1 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -95,7 +95,7 @@ static int comedi_do_insn(struct comedi_device *dev,
95 95
96 if (s->type == COMEDI_SUBD_UNUSED) { 96 if (s->type == COMEDI_SUBD_UNUSED) {
97 dev_err(dev->class_dev, 97 dev_err(dev->class_dev,
98 "%d not useable subdevice\n", insn->subdev); 98 "%d not usable subdevice\n", insn->subdev);
99 ret = -EIO; 99 ret = -EIO;
100 goto error; 100 goto error;
101 } 101 }
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 9a1dc56f21d1..6a393b24bdd9 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -1,20 +1,20 @@
1/* 1/*
2 module/range.c 2 * comedi/range.c
3 comedi routines for voltage ranges 3 * comedi routines for voltage ranges
4 4 *
5 COMEDI - Linux Control and Measurement Device Interface 5 * COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> 6 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17*/ 17 */
18 18
19#include <linux/uaccess.h> 19#include <linux/uaccess.h>
20#include "comedidev.h" 20#include "comedidev.h"
@@ -42,18 +42,18 @@ const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } };
42EXPORT_SYMBOL_GPL(range_unknown); 42EXPORT_SYMBOL_GPL(range_unknown);
43 43
44/* 44/*
45 COMEDI_RANGEINFO 45 * COMEDI_RANGEINFO ioctl
46 range information ioctl 46 * range information
47 47 *
48 arg: 48 * arg:
49 pointer to rangeinfo structure 49 * pointer to comedi_rangeinfo structure
50 50 *
51 reads: 51 * reads:
52 range info structure 52 * comedi_rangeinfo structure
53 53 *
54 writes: 54 * writes:
55 n struct comedi_krange structures to rangeinfo->range_ptr 55 * array of comedi_krange structures to rangeinfo->range_ptr pointer
56*/ 56 */
57int do_rangeinfo_ioctl(struct comedi_device *dev, 57int do_rangeinfo_ioctl(struct comedi_device *dev,
58 struct comedi_rangeinfo __user *arg) 58 struct comedi_rangeinfo __user *arg)
59{ 59{
diff --git a/drivers/staging/cptm1217/Kconfig b/drivers/staging/cptm1217/Kconfig
deleted file mode 100644
index 43b1cc0a50a5..000000000000
--- a/drivers/staging/cptm1217/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
1config TOUCHSCREEN_CLEARPAD_TM1217
2 tristate "Synaptics Clearpad TM1217"
3 depends on I2C
4 depends on GPIOLIB
5 depends on INPUT
6 help
7 Say Y here if you have a Synaptics Clearpad TM1217 Controller
8
9 If unsure, say N.
10
11 To compile this driver as a module, choose M here: the
12 module will be called clearpad_tm1217.
diff --git a/drivers/staging/cptm1217/Makefile b/drivers/staging/cptm1217/Makefile
deleted file mode 100644
index 8961fafa80e7..000000000000
--- a/drivers/staging/cptm1217/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += clearpad_tm1217.o
2
diff --git a/drivers/staging/cptm1217/TODO b/drivers/staging/cptm1217/TODO
deleted file mode 100644
index 303922465e4d..000000000000
--- a/drivers/staging/cptm1217/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1- Wait for the official upstream general clearpad drivers as promised over
2 the past few months
3- Merge any device support needed from this driver into it
4- Delete this driver
5
diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c
deleted file mode 100644
index 7f265ce0dd13..000000000000
--- a/drivers/staging/cptm1217/clearpad_tm1217.c
+++ /dev/null
@@ -1,665 +0,0 @@
1/*
2 * clearpad_tm1217.c - Touch Screen driver for Synaptics Clearpad
3 * TM1217 controller
4 *
5 * Copyright (C) 2008 Intel Corp
6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; ifnot, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * Questions/Comments/Bug fixes to Ramesh Agarwal (ramesh.agarwal@intel.com)
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
25
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/input.h>
29#include <linux/interrupt.h>
30#include <linux/io.h>
31#include <linux/i2c.h>
32#include <linux/timer.h>
33#include <linux/gpio.h>
34#include <linux/hrtimer.h>
35#include <linux/kthread.h>
36#include <linux/delay.h>
37#include <linux/slab.h>
38#include "cp_tm1217.h"
39
40#define CPTM1217_DEVICE_NAME "cptm1217"
41#define CPTM1217_DRIVER_NAME CPTM1217_DEVICE_NAME
42
43#define MAX_TOUCH_SUPPORTED 2
44#define TOUCH_SUPPORTED 1
45#define SAMPLING_FREQ 80 /* Frequency in HZ */
46#define DELAY_BTWIN_SAMPLE (1000 / SAMPLING_FREQ)
47#define WAIT_FOR_RESPONSE 5 /* 5msec just works */
48#define MAX_RETRIES 5 /* As above */
49#define INCREMENTAL_DELAY 5 /* As above */
50
51/* Regster Definitions */
52#define TMA1217_DEV_STATUS 0x13 /* Device Status */
53#define TMA1217_INT_STATUS 0x14 /* Interrupt Status */
54
55/* Controller can detect up to 2 possible finger touches.
56 * Each finger touch provides 12 bit X Y co-ordinates, the values are split
57 * across 2 registers, and an 8 bit Z value */
58#define TMA1217_FINGER_STATE 0x18 /* Finger State */
59#define TMA1217_FINGER1_X_HIGHER8 0x19 /* Higher 8 bit of X coordinate */
60#define TMA1217_FINGER1_Y_HIGHER8 0x1A /* Higher 8 bit of Y coordinate */
61#define TMA1217_FINGER1_XY_LOWER4 0x1B /* Lower 4 bits of X and Y */
62#define TMA1217_FINGER1_Z_VALUE 0x1D /* 8 bit Z value for finger 1 */
63#define TMA1217_FINGER2_X_HIGHER8 0x1E /* Higher 8 bit of X coordinate */
64#define TMA1217_FINGER2_Y_HIGHER8 0x1F /* Higher 8 bit of Y coordinate */
65#define TMA1217_FINGER2_XY_LOWER4 0x20 /* Lower 4 bits of X and Y */
66#define TMA1217_FINGER2_Z_VALUE 0x22 /* 8 bit Z value for finger 2 */
67#define TMA1217_DEVICE_CTRL 0x23 /* Device Control */
68#define TMA1217_INTERRUPT_ENABLE 0x24 /* Interrupt Enable */
69#define TMA1217_REPORT_MODE 0x2B /* Reporting Mode */
70#define TMA1217_MAX_X_LOWER8 0x31 /* Bit 0-7 for Max X */
71#define TMA1217_MAX_X_HIGHER4 0x32 /* Bit 8-11 for Max X */
72#define TMA1217_MAX_Y_LOWER8 0x33 /* Bit 0-7 for Max Y */
73#define TMA1217_MAX_Y_HIGHER4 0x34 /* Bit 8-11 for Max Y */
74#define TMA1217_DEVICE_CMD_RESET 0x67 /* Device CMD reg for reset */
75#define TMA1217_DEVICE_CMD_REZERO 0x69 /* Device CMD reg for rezero */
76
77#define TMA1217_MANUFACTURER_ID 0x73 /* Manufacturer Id */
78#define TMA1217_PRODUCT_FAMILY 0x75 /* Product Family */
79#define TMA1217_FIRMWARE_REVISION 0x76 /* Firmware Revision */
80#define TMA1217_SERIAL_NO_HIGH 0x7C /* Bit 8-15 of device serial no. */
81#define TMA1217_SERIAL_NO_LOW 0x7D /* Bit 0-7 of device serial no. */
82#define TMA1217_PRODUCT_ID_START 0x7E /* Start address for 10 byte ID */
83#define TMA1217_DEVICE_CAPABILITY 0x8B /* Reporting capability */
84
85
86/*
87 * The touch position structure.
88 */
89struct touch_state {
90 int x;
91 int y;
92 bool button;
93};
94
95/* Device Specific info given by the controller */
96struct cp_dev_info {
97 u16 maxX;
98 u16 maxY;
99};
100
101/* Vendor related info given by the controller */
102struct cp_vendor_info {
103 u8 vendor_id;
104 u8 product_family;
105 u8 firmware_rev;
106 u16 serial_no;
107};
108
109/*
110 * Private structure to store the device details
111 */
112struct cp_tm1217_device {
113 struct i2c_client *client;
114 struct device *dev;
115 struct cp_vendor_info vinfo;
116 struct cp_dev_info dinfo;
117 struct input_dev_info {
118 char phys[32];
119 char name[128];
120 struct input_dev *input;
121 struct touch_state touch;
122 } cp_input_info[MAX_TOUCH_SUPPORTED];
123
124 int thread_running;
125 struct mutex thread_mutex;
126
127 int gpio;
128};
129
130
131/* The following functions are used to read/write registers on the device
132 * as per the RMI prorocol. Technically, a page select should be written
133 * before doing read/write but since the register offsets are below 0xFF
134 * we can use the default value of page which is 0x00
135 */
136static int cp_tm1217_read(struct cp_tm1217_device *ts,
137 u8 *req, int size)
138{
139 int i, retval;
140
141 /* Send the address */
142 retval = i2c_master_send(ts->client, &req[0], 1);
143 if (retval != 1) {
144 dev_err(ts->dev, "cp_tm1217: I2C send failed\n");
145 return retval;
146 }
147 msleep(WAIT_FOR_RESPONSE);
148 for (i = 0; i < MAX_RETRIES; i++) {
149 retval = i2c_master_recv(ts->client, &req[1], size);
150 if (retval == size)
151 break;
152
153 msleep(INCREMENTAL_DELAY);
154 dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i);
155 }
156 if (retval != size)
157 dev_err(ts->dev, "cp_tm1217: Read from device failed\n");
158
159 return retval;
160}
161
162static int cp_tm1217_write(struct cp_tm1217_device *ts,
163 u8 *req, int size)
164{
165 int retval;
166
167 /* Send the address and the data to be written */
168 retval = i2c_master_send(ts->client, &req[0], size + 1);
169 if (retval != size + 1) {
170 dev_err(ts->dev, "cp_tm1217: I2C write failed: %d\n", retval);
171 return retval;
172 }
173 /* Wait for the write to complete. TBD why this is required */
174 msleep(WAIT_FOR_RESPONSE);
175
176 return size;
177}
178
179static int cp_tm1217_mask_interrupt(struct cp_tm1217_device *ts)
180{
181 u8 req[2];
182 int retval;
183
184 req[0] = TMA1217_INTERRUPT_ENABLE;
185 req[1] = 0x0;
186 retval = cp_tm1217_write(ts, req, 1);
187 if (retval != 1)
188 return -EIO;
189
190 return 0;
191}
192
193static int cp_tm1217_unmask_interrupt(struct cp_tm1217_device *ts)
194{
195 u8 req[2];
196 int retval;
197
198 req[0] = TMA1217_INTERRUPT_ENABLE;
199 req[1] = 0xa;
200 retval = cp_tm1217_write(ts, req, 1);
201 if (retval != 1)
202 return -EIO;
203
204 return 0;
205}
206
207static void process_touch(struct cp_tm1217_device *ts, int index)
208{
209 int retval;
210 struct input_dev_info *input_info =
211 (struct input_dev_info *)&ts->cp_input_info[index];
212 u8 xy_data[6];
213
214 if (index == 0)
215 xy_data[0] = TMA1217_FINGER1_X_HIGHER8;
216 else
217 xy_data[0] = TMA1217_FINGER2_X_HIGHER8;
218
219 retval = cp_tm1217_read(ts, xy_data, 5);
220 if (retval < 5) {
221 dev_err(ts->dev, "cp_tm1217: XY read from device failed\n");
222 return;
223 }
224
225 /* Note: Currently not using the Z values but may be requried in
226 the future. */
227 input_info->touch.x = (xy_data[1] << 4)
228 | (xy_data[3] & 0x0F);
229 input_info->touch.y = (xy_data[2] << 4)
230 | ((xy_data[3] & 0xF0) >> 4);
231 input_report_abs(input_info->input, ABS_X, input_info->touch.x);
232 input_report_abs(input_info->input, ABS_Y, input_info->touch.y);
233 input_sync(input_info->input);
234}
235
236static void cp_tm1217_get_data(struct cp_tm1217_device *ts)
237{
238 u8 req[2];
239 int retval, i, finger_touched = 0;
240
241 do {
242 req[0] = TMA1217_FINGER_STATE;
243 retval = cp_tm1217_read(ts, req, 1);
244 if (retval != 1) {
245 dev_err(ts->dev,
246 "cp_tm1217: Read from device failed\n");
247 continue;
248 }
249 finger_touched = 0;
250 /* Start sampling until the pressure is below
251 threshold */
252 for (i = 0; i < TOUCH_SUPPORTED; i++) {
253 if (req[1] & 0x3) {
254 finger_touched++;
255 if (ts->cp_input_info[i].touch.button == 0) {
256 /* send the button touch event */
257 input_report_key(
258 ts->cp_input_info[i].input,
259 BTN_TOUCH, 1);
260 ts->cp_input_info[i].touch.button = 1;
261 }
262 process_touch(ts, i);
263 } else {
264 if (ts->cp_input_info[i].touch.button == 1) {
265 /* send the button release event */
266 input_report_key(
267 ts->cp_input_info[i].input,
268 BTN_TOUCH, 0);
269 input_sync(ts->cp_input_info[i].input);
270 ts->cp_input_info[i].touch.button = 0;
271 }
272 }
273 req[1] = req[1] >> 2;
274 }
275 msleep(DELAY_BTWIN_SAMPLE);
276 } while (finger_touched > 0);
277}
278
279static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle)
280{
281 struct cp_tm1217_device *ts = handle;
282 u8 req[2];
283 int retval;
284
285 /* Chedk if another thread is already running */
286 mutex_lock(&ts->thread_mutex);
287 if (ts->thread_running == 1) {
288 mutex_unlock(&ts->thread_mutex);
289 return IRQ_HANDLED;
290 }
291
292 ts->thread_running = 1;
293 mutex_unlock(&ts->thread_mutex);
294
295 /* Mask the interrupts */
296 retval = cp_tm1217_mask_interrupt(ts);
297
298 /* Read the Interrupt Status register to find the cause of the
299 Interrupt */
300 req[0] = TMA1217_INT_STATUS;
301 retval = cp_tm1217_read(ts, req, 1);
302 if (retval != 1)
303 goto exit_thread;
304
305 if (!(req[1] & 0x8))
306 goto exit_thread;
307
308 cp_tm1217_get_data(ts);
309
310exit_thread:
311 /* Unmask the interrupts before going to sleep */
312 retval = cp_tm1217_unmask_interrupt(ts);
313
314 mutex_lock(&ts->thread_mutex);
315 ts->thread_running = 0;
316 mutex_unlock(&ts->thread_mutex);
317
318 return IRQ_HANDLED;
319}
320
321static int cp_tm1217_init_data(struct cp_tm1217_device *ts)
322{
323 int retval;
324 u8 req[2];
325
326 /* Read the vendor id/ fw revision etc. Ignoring return check as this
327 is non critical info */
328 req[0] = TMA1217_MANUFACTURER_ID;
329 retval = cp_tm1217_read(ts, req, 1);
330 ts->vinfo.vendor_id = req[1];
331
332 req[0] = TMA1217_PRODUCT_FAMILY;
333 retval = cp_tm1217_read(ts, req, 1);
334 ts->vinfo.product_family = req[1];
335
336 req[0] = TMA1217_FIRMWARE_REVISION;
337 retval = cp_tm1217_read(ts, req, 1);
338 ts->vinfo.firmware_rev = req[1];
339
340 req[0] = TMA1217_SERIAL_NO_HIGH;
341 retval = cp_tm1217_read(ts, req, 1);
342 ts->vinfo.serial_no = (req[1] << 8);
343
344 req[0] = TMA1217_SERIAL_NO_LOW;
345 retval = cp_tm1217_read(ts, req, 1);
346 ts->vinfo.serial_no = ts->vinfo.serial_no | req[1];
347
348 req[0] = TMA1217_MAX_X_HIGHER4;
349 retval = cp_tm1217_read(ts, req, 1);
350 ts->dinfo.maxX = (req[1] & 0xF) << 8;
351
352 req[0] = TMA1217_MAX_X_LOWER8;
353 retval = cp_tm1217_read(ts, req, 1);
354 ts->dinfo.maxX = ts->dinfo.maxX | req[1];
355
356 req[0] = TMA1217_MAX_Y_HIGHER4;
357 retval = cp_tm1217_read(ts, req, 1);
358 ts->dinfo.maxY = (req[1] & 0xF) << 8;
359
360 req[0] = TMA1217_MAX_Y_LOWER8;
361 retval = cp_tm1217_read(ts, req, 1);
362 ts->dinfo.maxY = ts->dinfo.maxY | req[1];
363
364 return 0;
365
366}
367
368/*
369 * Set up a GPIO for use as the interrupt. We can't simply do this at
370 * boot time because the GPIO drivers themselves may not be around at
371 * boot/firmware set up time to do the work. Instead defer it to driver
372 * detection.
373 */
374
375static int cp_tm1217_setup_gpio_irq(struct cp_tm1217_device *ts)
376{
377 int retval;
378
379 /* Hook up the irq handler */
380 retval = gpio_request(ts->gpio, "cp_tm1217_touch");
381 if (retval < 0) {
382 dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n",
383 retval);
384 return retval;
385 }
386
387 retval = gpio_direction_input(ts->gpio);
388 if (retval < 0) {
389 dev_err(ts->dev,
390 "cp_tm1217: GPIO direction configuration failed, error %d\n",
391 retval);
392 gpio_free(ts->gpio);
393 return retval;
394 }
395
396 retval = gpio_to_irq(ts->gpio);
397 if (retval < 0) {
398 dev_err(ts->dev,
399 "cp_tm1217: GPIO to IRQ failed, error %d\n", retval);
400 gpio_free(ts->gpio);
401 }
402 dev_dbg(ts->dev,
403 "cp_tm1217: Got IRQ number is %d for GPIO %d\n",
404 retval, ts->gpio);
405 return retval;
406}
407
408static int cp_tm1217_probe(struct i2c_client *client,
409 const struct i2c_device_id *id)
410{
411 struct cp_tm1217_device *ts;
412 struct input_dev *input_dev;
413 struct input_dev_info *input_info;
414 struct cp_tm1217_platform_data *pdata;
415 u8 req[2];
416 int i, retval;
417
418 /* No pdata is fine - we then use "normal" IRQ mode */
419
420 pdata = client->dev.platform_data;
421
422 ts = kzalloc(sizeof(struct cp_tm1217_device), GFP_KERNEL);
423 if (!ts)
424 return -ENOMEM;
425
426 ts->client = client;
427 ts->dev = &client->dev;
428 i2c_set_clientdata(client, ts);
429
430 ts->thread_running = 0;
431 mutex_init(&ts->thread_mutex);
432
433 /* Reset the Controller */
434 req[0] = TMA1217_DEVICE_CMD_RESET;
435 req[1] = 0x1;
436 retval = cp_tm1217_write(ts, req, 1);
437 if (retval != 1) {
438 dev_err(ts->dev, "cp_tm1217: Controller reset failed\n");
439 kfree(ts);
440 return -EIO;
441 }
442
443 /* Clear up the interrupt status from reset. */
444 req[0] = TMA1217_INT_STATUS;
445 retval = cp_tm1217_read(ts, req, 1);
446
447 /* Mask all the interrupts */
448 retval = cp_tm1217_mask_interrupt(ts);
449
450 /* Read the controller information */
451 cp_tm1217_init_data(ts);
452
453 /* The following code will register multiple event devices when
454 multi-pointer is enabled, the code has not been tested
455 with MPX */
456 for (i = 0; i < TOUCH_SUPPORTED; i++) {
457 input_dev = input_allocate_device();
458 if (input_dev == NULL) {
459 retval = -ENOMEM;
460 goto fail;
461 }
462 input_info = &ts->cp_input_info[i];
463 snprintf(input_info->name, sizeof(input_info->name),
464 "cp_tm1217_touchscreen_%d", i);
465 input_dev->name = input_info->name;
466 snprintf(input_info->phys, sizeof(input_info->phys),
467 "%s/input%d", dev_name(&client->dev), i);
468
469 input_dev->phys = input_info->phys;
470 input_dev->id.bustype = BUS_I2C;
471
472 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
473 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
474
475 input_set_abs_params(input_dev, ABS_X, 0, ts->dinfo.maxX, 0, 0);
476 input_set_abs_params(input_dev, ABS_Y, 0, ts->dinfo.maxY, 0, 0);
477
478 retval = input_register_device(input_dev);
479 if (retval) {
480 dev_err(ts->dev,
481 "Input dev registration failed for %s\n",
482 input_dev->name);
483 input_free_device(input_dev);
484 goto fail;
485 }
486 input_info->input = input_dev;
487 }
488
489 /* Setup the reporting mode to send an interrupt only when
490 finger arrives or departs. */
491 req[0] = TMA1217_REPORT_MODE;
492 req[1] = 0x02;
493 retval = cp_tm1217_write(ts, req, 1);
494
495 /* Setup the device to no sleep mode for now and make it configured */
496 req[0] = TMA1217_DEVICE_CTRL;
497 req[1] = 0x84;
498 retval = cp_tm1217_write(ts, req, 1);
499
500 /* Check for the status of the device */
501 req[0] = TMA1217_DEV_STATUS;
502 retval = cp_tm1217_read(ts, req, 1);
503 if (req[1] != 0) {
504 dev_err(ts->dev,
505 "cp_tm1217: Device Status 0x%x != 0: config failed\n",
506 req[1]);
507
508 retval = -EIO;
509 goto fail;
510 }
511
512 if (pdata && pdata->gpio) {
513 ts->gpio = pdata->gpio;
514 retval = cp_tm1217_setup_gpio_irq(ts);
515 } else
516 retval = client->irq;
517
518 if (retval < 0) {
519 dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n",
520 retval);
521 goto fail;
522 }
523
524 client->irq = retval;
525
526
527 retval = request_threaded_irq(client->irq,
528 NULL, cp_tm1217_sample_thread,
529 IRQF_TRIGGER_FALLING, "cp_tm1217_touch", ts);
530 if (retval < 0) {
531 dev_err(ts->dev, "cp_tm1217: Request IRQ error %d\n", retval);
532 goto fail_gpio;
533 }
534
535 /* Unmask the interrupts */
536 retval = cp_tm1217_unmask_interrupt(ts);
537 if (retval == 0)
538 return 0;
539
540 free_irq(client->irq, ts);
541fail_gpio:
542 if (ts->gpio)
543 gpio_free(ts->gpio);
544fail:
545 /* Clean up before returning failure */
546 for (i = 0; i < TOUCH_SUPPORTED; i++) {
547 if (ts->cp_input_info[i].input)
548 input_unregister_device(ts->cp_input_info[i].input);
549 }
550 kfree(ts);
551 return retval;
552
553}
554
555#ifdef CONFIG_PM_SLEEP
556
557/*
558 * cp_tm1217 suspend
559 *
560 */
561static int cp_tm1217_suspend(struct device *dev)
562{
563 struct i2c_client *client = to_i2c_client(dev);
564 struct cp_tm1217_device *ts = i2c_get_clientdata(client);
565 u8 req[2];
566 int retval;
567
568 /* Put the controller to sleep */
569 req[0] = TMA1217_DEVICE_CTRL;
570 retval = cp_tm1217_read(ts, req, 1);
571 req[1] = (req[1] & 0xF8) | 0x1;
572 retval = cp_tm1217_write(ts, req, 1);
573
574 if (device_may_wakeup(&client->dev))
575 enable_irq_wake(client->irq);
576
577 return 0;
578}
579
580/*
581 * cp_tm1217_resume
582 *
583 */
584static int cp_tm1217_resume(struct device *dev)
585{
586 struct i2c_client *client = to_i2c_client(dev);
587 struct cp_tm1217_device *ts = i2c_get_clientdata(client);
588 u8 req[2];
589 int retval;
590
591 /* Take the controller out of sleep */
592 req[0] = TMA1217_DEVICE_CTRL;
593 retval = cp_tm1217_read(ts, req, 1);
594 req[1] = (req[1] & 0xF8) | 0x4;
595 retval = cp_tm1217_write(ts, req, 1);
596
597 /* Restore the register settings sinc the power to the
598 could have been cut off */
599
600 /* Setup the reporting mode to send an interrupt only when
601 finger arrives or departs. */
602 req[0] = TMA1217_REPORT_MODE;
603 req[1] = 0x02;
604 retval = cp_tm1217_write(ts, req, 1);
605
606 /* Setup the device to no sleep mode for now and make it configured */
607 req[0] = TMA1217_DEVICE_CTRL;
608 req[1] = 0x84;
609 retval = cp_tm1217_write(ts, req, 1);
610
611 /* Setup the interrupt mask */
612 retval = cp_tm1217_unmask_interrupt(ts);
613
614 if (device_may_wakeup(&client->dev))
615 disable_irq_wake(client->irq);
616
617 return 0;
618}
619
620#endif
621
622static SIMPLE_DEV_PM_OPS(cp_tm1217_pm_ops, cp_tm1217_suspend,
623 cp_tm1217_resume);
624
625/*
626 * cp_tm1217_remove
627 *
628 */
629static int cp_tm1217_remove(struct i2c_client *client)
630{
631 struct cp_tm1217_device *ts = i2c_get_clientdata(client);
632 int i;
633
634 free_irq(client->irq, ts);
635 if (ts->gpio)
636 gpio_free(ts->gpio);
637 for (i = 0; i < TOUCH_SUPPORTED; i++)
638 input_unregister_device(ts->cp_input_info[i].input);
639 kfree(ts);
640 return 0;
641}
642
643static struct i2c_device_id cp_tm1217_idtable[] = {
644 { CPTM1217_DEVICE_NAME, 0 },
645 { }
646};
647
648MODULE_DEVICE_TABLE(i2c, cp_tm1217_idtable);
649
650static struct i2c_driver cp_tm1217_driver = {
651 .driver = {
652 .owner = THIS_MODULE,
653 .name = CPTM1217_DRIVER_NAME,
654 .pm = &cp_tm1217_pm_ops,
655 },
656 .id_table = cp_tm1217_idtable,
657 .probe = cp_tm1217_probe,
658 .remove = cp_tm1217_remove,
659};
660
661module_i2c_driver(cp_tm1217_driver);
662
663MODULE_AUTHOR("Ramesh Agarwal <ramesh.agarwal@intel.com>");
664MODULE_DESCRIPTION("Synaptics TM1217 TouchScreen Driver");
665MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/cptm1217/cp_tm1217.h b/drivers/staging/cptm1217/cp_tm1217.h
deleted file mode 100644
index 30bad357a055..000000000000
--- a/drivers/staging/cptm1217/cp_tm1217.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef __LINUX_I2C_CP_TM1217_H
2#define __LINUX_I2C_CP_TM1217_H
3
4struct cp_tm1217_platform_data {
5 int gpio; /* If not set uses the IRQ resource 0 */
6};
7
8#endif
diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c
index bdb5317e3d9d..7184747e0652 100644
--- a/drivers/staging/dgap/dgap.c
+++ b/drivers/staging/dgap/dgap.c
@@ -978,8 +978,8 @@ static int dgap_parsefile(char **in)
978 brd->u.board.conc1++; 978 brd->u.board.conc1++;
979 979
980 conc_type = dgap_gettok(in); 980 conc_type = dgap_gettok(in);
981 if (conc_type == 0 || conc_type != CX || 981 if (conc_type == 0 || (conc_type != CX &&
982 conc_type != EPC) { 982 conc_type != EPC)) {
983 pr_err("failed to set a type of concentratros"); 983 pr_err("failed to set a type of concentratros");
984 return -1; 984 return -1;
985 } 985 }
@@ -1019,8 +1019,8 @@ static int dgap_parsefile(char **in)
1019 brd->u.board.module1++; 1019 brd->u.board.module1++;
1020 1020
1021 module_type = dgap_gettok(in); 1021 module_type = dgap_gettok(in);
1022 if (module_type == 0 || module_type != PORTS || 1022 if (module_type == 0 || (module_type != PORTS &&
1023 module_type != MODEM) { 1023 module_type != MODEM)) {
1024 pr_err("failed to set a type of module"); 1024 pr_err("failed to set a type of module");
1025 return -1; 1025 return -1;
1026 } 1026 }
@@ -1400,27 +1400,27 @@ static int dgap_remap(struct board_t *brd)
1400 return -ENOMEM; 1400 return -ENOMEM;
1401 1401
1402 if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000, 1402 if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000,
1403 "dgap")) { 1403 "dgap"))
1404 release_mem_region(brd->membase, 0x200000); 1404 goto err_req_mem;
1405 return -ENOMEM;
1406 }
1407 1405
1408 brd->re_map_membase = ioremap(brd->membase, 0x200000); 1406 brd->re_map_membase = ioremap(brd->membase, 0x200000);
1409 if (!brd->re_map_membase) { 1407 if (!brd->re_map_membase)
1410 release_mem_region(brd->membase, 0x200000); 1408 goto err_remap_mem;
1411 release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
1412 return -ENOMEM;
1413 }
1414 1409
1415 brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000); 1410 brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000);
1416 if (!brd->re_map_port) { 1411 if (!brd->re_map_port)
1417 release_mem_region(brd->membase, 0x200000); 1412 goto err_remap_port;
1418 release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
1419 iounmap(brd->re_map_membase);
1420 return -ENOMEM;
1421 }
1422 1413
1423 return 0; 1414 return 0;
1415
1416err_remap_port:
1417 iounmap(brd->re_map_membase);
1418err_remap_mem:
1419 release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
1420err_req_mem:
1421 release_mem_region(brd->membase, 0x200000);
1422
1423 return -ENOMEM;
1424} 1424}
1425 1425
1426static void dgap_unmap(struct board_t *brd) 1426static void dgap_unmap(struct board_t *brd)
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
index ba98ff348112..f177d3a258c2 100644
--- a/drivers/staging/dgnc/dgnc_driver.c
+++ b/drivers/staging/dgnc/dgnc_driver.c
@@ -97,12 +97,12 @@ static uint dgnc_poll_stop; /* Used to tell poller to stop */
97static struct timer_list dgnc_poll_timer; 97static struct timer_list dgnc_poll_timer;
98 98
99 99
100static struct pci_device_id dgnc_pci_tbl[] = { 100static const struct pci_device_id dgnc_pci_tbl[] = {
101 { DIGI_VID, PCI_DEVICE_CLASSIC_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 101 {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_DID), .driver_data = 0},
102 { DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, 102 {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID), .driver_data = 1},
103 { DIGI_VID, PCI_DEVICE_CLASSIC_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, 103 {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_8_DID), .driver_data = 2},
104 { DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, 104 {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID), .driver_data = 3},
105 {0,} /* 0 terminated list. */ 105 {0,}
106}; 106};
107MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl); 107MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl);
108 108
@@ -238,6 +238,7 @@ static int dgnc_start(void)
238{ 238{
239 int rc = 0; 239 int rc = 0;
240 unsigned long flags; 240 unsigned long flags;
241 struct device *dev;
241 242
242 /* make sure that the globals are init'd before we do anything else */ 243 /* make sure that the globals are init'd before we do anything else */
243 dgnc_init_globals(); 244 dgnc_init_globals();
@@ -257,9 +258,20 @@ static int dgnc_start(void)
257 dgnc_Major = rc; 258 dgnc_Major = rc;
258 259
259 dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); 260 dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt");
260 device_create(dgnc_class, NULL, 261 if (IS_ERR(dgnc_class)) {
261 MKDEV(dgnc_Major, 0), 262 rc = PTR_ERR(dgnc_class);
262 NULL, "dgnc_mgmt"); 263 pr_err(DRVSTR ": Can't create dgnc_mgmt class (%d)\n", rc);
264 goto failed_class;
265 }
266
267 dev = device_create(dgnc_class, NULL,
268 MKDEV(dgnc_Major, 0),
269 NULL, "dgnc_mgmt");
270 if (IS_ERR(dev)) {
271 rc = PTR_ERR(dev);
272 pr_err(DRVSTR ": Can't create device (%d)\n", rc);
273 goto failed_device;
274 }
263 275
264 /* 276 /*
265 * Init any global tty stuff. 277 * Init any global tty stuff.
@@ -268,7 +280,7 @@ static int dgnc_start(void)
268 280
269 if (rc < 0) { 281 if (rc < 0) {
270 pr_err(DRVSTR ": tty preinit - not enough memory (%d)\n", rc); 282 pr_err(DRVSTR ": tty preinit - not enough memory (%d)\n", rc);
271 return rc; 283 goto failed_tty;
272 } 284 }
273 285
274 /* Start the poller */ 286 /* Start the poller */
@@ -282,6 +294,14 @@ static int dgnc_start(void)
282 294
283 add_timer(&dgnc_poll_timer); 295 add_timer(&dgnc_poll_timer);
284 296
297 return 0;
298
299failed_tty:
300 device_destroy(dgnc_class, MKDEV(dgnc_Major, 0));
301failed_device:
302 class_destroy(dgnc_class);
303failed_class:
304 unregister_chrdev(dgnc_Major, "dgnc");
285 return rc; 305 return rc;
286} 306}
287 307
diff --git a/drivers/staging/dgnc/dgnc_utils.c b/drivers/staging/dgnc/dgnc_utils.c
index 61efc13ec160..80b51332292c 100644
--- a/drivers/staging/dgnc/dgnc_utils.c
+++ b/drivers/staging/dgnc/dgnc_utils.c
@@ -12,7 +12,7 @@
12 */ 12 */
13int dgnc_ms_sleep(ulong ms) 13int dgnc_ms_sleep(ulong ms)
14{ 14{
15 current->state = TASK_INTERRUPTIBLE; 15 __set_current_state(TASK_INTERRUPTIBLE);
16 schedule_timeout((ms * HZ) / 1000); 16 schedule_timeout((ms * HZ) / 1000);
17 return signal_pending(current); 17 return signal_pending(current);
18} 18}
diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h
index 3181a3590465..d6e0b9f6b24a 100644
--- a/drivers/staging/dgnc/digi.h
+++ b/drivers/staging/dgnc/digi.h
@@ -38,8 +38,8 @@
38 38
39#if !defined(TIOCMODG) 39#if !defined(TIOCMODG)
40 40
41#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */ 41#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
42#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */ 42#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
43 43
44#ifndef TIOCM_LE 44#ifndef TIOCM_LE
45#define TIOCM_LE 0x01 /* line enable */ 45#define TIOCM_LE 0x01 /* line enable */
@@ -58,44 +58,44 @@
58#endif 58#endif
59 59
60#if !defined(TIOCMSET) 60#if !defined(TIOCMSET)
61#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */ 61#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
62#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */ 62#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
63#endif 63#endif
64 64
65#if !defined(TIOCMBIC) 65#if !defined(TIOCMBIC)
66#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */ 66#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
67#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */ 67#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
68#endif 68#endif
69 69
70 70
71#if !defined(TIOCSDTR) 71#if !defined(TIOCSDTR)
72#define TIOCSDTR ('e'<<8) | 0 /* set DTR */ 72#define TIOCSDTR (('e'<<8) | 0) /* set DTR */
73#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */ 73#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */
74#endif 74#endif
75 75
76/************************************************************************ 76/************************************************************************
77 * Ioctl command arguments for DIGI parameters. 77 * Ioctl command arguments for DIGI parameters.
78 ************************************************************************/ 78 ************************************************************************/
79#define DIGI_GETA ('e'<<8) | 94 /* Read params */ 79#define DIGI_GETA (('e'<<8) | 94) /* Read params */
80 80
81#define DIGI_SETA ('e'<<8) | 95 /* Set params */ 81#define DIGI_SETA (('e'<<8) | 95) /* Set params */
82#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */ 82#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */
83#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */ 83#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */
84 84
85#define DIGI_KME ('e'<<8) | 98 /* Read/Write Host */ 85#define DIGI_KME (('e'<<8) | 98) /* Read/Write Host */
86 /* Adapter Memory */ 86 /* Adapter Memory */
87 87
88#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */ 88#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */
89 /* control characters */ 89 /* control characters */
90#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */ 90#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
91 /* control characters */ 91 /* control characters */
92#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */ 92#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
93 /* flow control chars */ 93 /* flow control chars */
94#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */ 94#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
95 /* flow control chars */ 95 /* flow control chars */
96 96
97#define DIGI_GEDELAY ('d'<<8) | 246 /* Get edelay */ 97#define DIGI_GEDELAY (('d'<<8) | 246) /* Get edelay */
98#define DIGI_SEDELAY ('d'<<8) | 247 /* Set edelay */ 98#define DIGI_SEDELAY (('d'<<8) | 247) /* Set edelay */
99 99
100struct digiflow_t { 100struct digiflow_t {
101 unsigned char startc; /* flow cntl start char */ 101 unsigned char startc; /* flow cntl start char */
@@ -104,8 +104,8 @@ struct digiflow_t {
104 104
105 105
106#ifdef FLOW_2200 106#ifdef FLOW_2200
107#define F2200_GETA ('e'<<8) | 104 /* Get 2x36 flow cntl flags */ 107#define F2200_GETA (('e'<<8) | 104) /* Get 2x36 flow cntl flags */
108#define F2200_SETAW ('e'<<8) | 105 /* Set 2x36 flow cntl flags */ 108#define F2200_SETAW (('e'<<8) | 105) /* Set 2x36 flow cntl flags */
109#define F2200_MASK 0x03 /* 2200 flow cntl bit mask */ 109#define F2200_MASK 0x03 /* 2200 flow cntl bit mask */
110#define FCNTL_2200 0x01 /* 2x36 terminal flow cntl */ 110#define FCNTL_2200 0x01 /* 2x36 terminal flow cntl */
111#define PCNTL_2200 0x02 /* 2x36 printer flow cntl */ 111#define PCNTL_2200 0x02 /* 2x36 printer flow cntl */
@@ -241,7 +241,7 @@ struct digi_dinfo {
241 char dinfo_version[16]; /* driver version */ 241 char dinfo_version[16]; /* driver version */
242}; 242};
243 243
244#define DIGI_GETDD ('d'<<8) | 248 /* get driver info */ 244#define DIGI_GETDD (('d'<<8) | 248) /* get driver info */
245 245
246/************************************************************************ 246/************************************************************************
247 * Structure used with ioctl commands for per-board information 247 * Structure used with ioctl commands for per-board information
@@ -261,7 +261,7 @@ struct digi_info {
261 char info_reserved[7]; /* for future expansion */ 261 char info_reserved[7]; /* for future expansion */
262}; 262};
263 263
264#define DIGI_GETBD ('d'<<8) | 249 /* get board info */ 264#define DIGI_GETBD (('d'<<8) | 249) /* get board info */
265 265
266struct digi_stat { 266struct digi_stat {
267 unsigned int info_chan; /* Channel number (0 based) */ 267 unsigned int info_chan; /* Channel number (0 based) */
@@ -276,7 +276,7 @@ struct digi_stat {
276 unsigned int info_reserved[8]; /* for future expansion */ 276 unsigned int info_reserved[8]; /* for future expansion */
277}; 277};
278 278
279#define DIGI_GETSTAT ('d'<<8) | 244 /* get board info */ 279#define DIGI_GETSTAT (('d'<<8) | 244) /* get board info */
280/************************************************************************ 280/************************************************************************
281 * 281 *
282 * Structure used with ioctl commands for per-channel information 282 * Structure used with ioctl commands for per-channel information
@@ -339,7 +339,7 @@ struct digi_getcounter {
339#define INFO_CH_WLOW 0x0020 339#define INFO_CH_WLOW 0x0020
340#define INFO_XXBUF_BUSY 0x0040 340#define INFO_XXBUF_BUSY 0x0040
341 341
342#define DIGI_GETCH ('d'<<8) | 245 /* get board info */ 342#define DIGI_GETCH (('d'<<8) | 245) /* get board info */
343 343
344/* Board type definitions */ 344/* Board type definitions */
345 345
@@ -384,15 +384,15 @@ struct digi_getcounter {
384#define BD_TRIBOOT 0x8 384#define BD_TRIBOOT 0x8
385#define BD_BADKME 0x80 385#define BD_BADKME 0x80
386 386
387#define DIGI_SPOLL ('d'<<8) | 254 /* change poller rate */ 387#define DIGI_SPOLL (('d'<<8) | 254) /* change poller rate */
388 388
389#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */ 389#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */
390#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */ 390#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */
391 391
392#define DIGI_REALPORT_GETBUFFERS ('e'<<8) | 108 392#define DIGI_REALPORT_GETBUFFERS (('e'<<8) | 108)
393#define DIGI_REALPORT_SENDIMMEDIATE ('e'<<8) | 109 393#define DIGI_REALPORT_SENDIMMEDIATE (('e'<<8) | 109)
394#define DIGI_REALPORT_GETCOUNTERS ('e'<<8) | 110 394#define DIGI_REALPORT_GETCOUNTERS (('e'<<8) | 110)
395#define DIGI_REALPORT_GETEVENTS ('e'<<8) | 111 395#define DIGI_REALPORT_GETEVENTS (('e'<<8) | 111)
396 396
397#define EV_OPU 0x0001 /* !<Output paused by client */ 397#define EV_OPU 0x0001 /* !<Output paused by client */
398#define EV_OPS 0x0002 /* !<Output paused by reqular sw flowctrl */ 398#define EV_OPS 0x0002 /* !<Output paused by reqular sw flowctrl */
diff --git a/drivers/staging/dgnc/dpacompat.h b/drivers/staging/dgnc/dpacompat.h
index b2d2dc08f869..33cb394524b8 100644
--- a/drivers/staging/dgnc/dpacompat.h
+++ b/drivers/staging/dgnc/dpacompat.h
@@ -51,7 +51,7 @@ struct ni_info {
51 51
52#define RW_READ 1 52#define RW_READ 1
53#define RW_WRITE 2 53#define RW_WRITE 2
54#define DIGI_KME ('e'<<8) | 98 /* Read/Write Host */ 54#define DIGI_KME (('e'<<8) | 98) /* Read/Write Host */
55 55
56#define SUBTYPE 0007 56#define SUBTYPE 0007
57#define T_PCXI 0000 57#define T_PCXI 0000
@@ -106,10 +106,10 @@ struct ni_info {
106 106
107/* Ioctls needed for dpa operation */ 107/* Ioctls needed for dpa operation */
108 108
109#define DIGI_GETDD ('d'<<8) | 248 /* get driver info */ 109#define DIGI_GETDD (('d'<<8) | 248) /* get driver info */
110#define DIGI_GETBD ('d'<<8) | 249 /* get board info */ 110#define DIGI_GETBD (('d'<<8) | 249) /* get board info */
111#define DIGI_GET_NI_INFO ('d'<<8) | 250 /* nonintelligent state snfo */ 111#define DIGI_GET_NI_INFO (('d'<<8) | 250) /* nonintelligent state snfo */
112 112
113/* Other special ioctls */ 113/* Other special ioctls */
114#define DIGI_TIMERIRQ ('d'<<8) | 251 /* Enable/disable RS_TIMER use */ 114#define DIGI_TIMERIRQ (('d'<<8) | 251) /* Enable/disable RS_TIMER use */
115#define DIGI_LOOPBACK ('d'<<8) | 252 /* Enable/disable UART internal loopback */ 115#define DIGI_LOOPBACK (('d'<<8) | 252) /* Enable/disable UART internal loopback */
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
index bd70ea05708b..4be646ce8a12 100644
--- a/drivers/staging/emxx_udc/emxx_udc.c
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -3249,42 +3249,6 @@ static const char *gp_ep_name[NUM_ENDPOINTS] = {
3249}; 3249};
3250 3250
3251/*-------------------------------------------------------------------------*/ 3251/*-------------------------------------------------------------------------*/
3252static void __init nbu2ss_drv_set_ep_info(
3253 struct nbu2ss_udc *udc,
3254 struct nbu2ss_ep *ep,
3255 const char *name)
3256{
3257 ep->udc = udc;
3258 ep->desc = NULL;
3259
3260 ep->ep.driver_data = NULL;
3261 ep->ep.name = name;
3262 ep->ep.ops = &nbu2ss_ep_ops;
3263
3264 if (isdigit(name[2])) {
3265
3266 long num;
3267 int res;
3268 char tempbuf[2];
3269
3270 tempbuf[0] = name[2];
3271 tempbuf[1] = '\0';
3272 res = kstrtol(tempbuf, 16, &num);
3273
3274 if (num == 0)
3275 ep->ep.maxpacket = EP0_PACKETSIZE;
3276 else
3277 ep->ep.maxpacket = EP_PACKETSIZE;
3278
3279 } else {
3280 ep->ep.maxpacket = EP_PACKETSIZE;
3281 }
3282
3283 list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
3284 INIT_LIST_HEAD(&ep->queue);
3285}
3286
3287/*-------------------------------------------------------------------------*/
3288static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) 3252static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
3289{ 3253{
3290 int i; 3254 int i;
@@ -3292,9 +3256,21 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
3292 INIT_LIST_HEAD(&udc->gadget.ep_list); 3256 INIT_LIST_HEAD(&udc->gadget.ep_list);
3293 udc->gadget.ep0 = &udc->ep[0].ep; 3257 udc->gadget.ep0 = &udc->ep[0].ep;
3294 3258
3259 for (i = 0; i < NUM_ENDPOINTS; i++) {
3260 struct nbu2ss_ep *ep = &udc->ep[i];
3295 3261
3296 for (i = 0; i < NUM_ENDPOINTS; i++) 3262 ep->udc = udc;
3297 nbu2ss_drv_set_ep_info(udc, &udc->ep[i], gp_ep_name[i]); 3263 ep->desc = NULL;
3264
3265 ep->ep.driver_data = NULL;
3266 ep->ep.name = gp_ep_name[i];
3267 ep->ep.ops = &nbu2ss_ep_ops;
3268
3269 ep->ep.maxpacket = (i == 0 ? EP0_PACKETSIZE : EP_PACKETSIZE);
3270
3271 list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
3272 INIT_LIST_HEAD(&ep->queue);
3273 }
3298 3274
3299 list_del_init(&udc->ep[0].ep.ep_list); 3275 list_del_init(&udc->ep[0].ep.ep_list);
3300} 3276}
diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig
new file mode 100644
index 000000000000..995a9101a080
--- /dev/null
+++ b/drivers/staging/fbtft/Kconfig
@@ -0,0 +1,169 @@
1menuconfig FB_TFT
2 tristate "Support for small TFT LCD display modules"
3 depends on FB && SPI && GPIOLIB
4 select FB_SYS_FILLRECT
5 select FB_SYS_COPYAREA
6 select FB_SYS_IMAGEBLIT
7 select FB_SYS_FOPS
8 select FB_DEFERRED_IO
9 select FB_BACKLIGHT
10
11config FB_TFT_AGM1264K_FL
12 tristate "FB driver for the AGM1264K-FL LCD display"
13 depends on FB_TFT
14 help
15 Framebuffer support for the AGM1264K-FL LCD display (two Samsung KS0108 compatable chips)
16
17config FB_TFT_BD663474
18 tristate "FB driver for the BD663474 LCD Controller"
19 depends on FB_TFT
20 help
21 Generic Framebuffer support for BD663474
22
23config FB_TFT_HX8340BN
24 tristate "FB driver for the HX8340BN LCD Controller"
25 depends on FB_TFT
26 help
27 Generic Framebuffer support for HX8340BN
28
29config FB_TFT_HX8347D
30 tristate "FB driver for the HX8347D LCD Controller"
31 depends on FB_TFT
32 help
33 Generic Framebuffer support for HX8347D
34
35config FB_TFT_HX8353D
36 tristate "FB driver for the HX8353D LCD Controller"
37 depends on FB_TFT
38 help
39 Generic Framebuffer support for HX8353D
40
41config FB_TFT_ILI9320
42 tristate "FB driver for the ILI9320 LCD Controller"
43 depends on FB_TFT
44 help
45 Generic Framebuffer support for ILI9320
46
47config FB_TFT_ILI9325
48 tristate "FB driver for the ILI9325 LCD Controller"
49 depends on FB_TFT
50 help
51 Generic Framebuffer support for ILI9325
52
53config FB_TFT_ILI9340
54 tristate "FB driver for the ILI9340 LCD Controller"
55 depends on FB_TFT
56 help
57 Generic Framebuffer support for ILI9340
58
59config FB_TFT_ILI9341
60 tristate "FB driver for the ILI9341 LCD Controller"
61 depends on FB_TFT
62 help
63 Generic Framebuffer support for ILI9341
64
65config FB_TFT_ILI9481
66 tristate "FB driver for the ILI9481 LCD Controller"
67 depends on FB_TFT
68 help
69 Generic Framebuffer support for ILI9481
70
71config FB_TFT_ILI9486
72 tristate "FB driver for the ILI9486 LCD Controller"
73 depends on FB_TFT
74 help
75 Generic Framebuffer support for ILI9486
76
77config FB_TFT_PCD8544
78 tristate "FB driver for the PCD8544 LCD Controller"
79 depends on FB_TFT
80 help
81 Generic Framebuffer support for PCD8544
82
83config FB_TFT_RA8875
84 tristate "FB driver for the RA8875 LCD Controller"
85 depends on FB_TFT
86 help
87 Generic Framebuffer support for RA8875
88
89config FB_TFT_S6D02A1
90 tristate "FB driver for the S6D02A1 LCD Controller"
91 depends on FB_TFT
92 help
93 Generic Framebuffer support for S6D02A1
94
95config FB_TFT_S6D1121
96 tristate "FB driver for the S6D1211 LCD Controller"
97 depends on FB_TFT
98 help
99 Generic Framebuffer support for S6D1121
100
101config FB_TFT_SSD1289
102 tristate "FB driver for the SSD1289 LCD Controller"
103 depends on FB_TFT
104 help
105 Framebuffer support for SSD1289
106
107config FB_TFT_SSD1306
108 tristate "FB driver for the SSD1306 OLED Controller"
109 depends on FB_TFT
110 help
111 Framebuffer support for SSD1306
112
113config FB_TFT_SSD1331
114 tristate "FB driver for the SSD1331 LCD Controller"
115 depends on FB_TFT
116 help
117 Framebuffer support for SSD1331
118
119config FB_TFT_SSD1351
120 tristate "FB driver for the SSD1351 LCD Controller"
121 depends on FB_TFT
122 help
123 Framebuffer support for SSD1351
124
125config FB_TFT_ST7735R
126 tristate "FB driver for the ST7735R LCD Controller"
127 depends on FB_TFT
128 help
129 Generic Framebuffer support for ST7735R
130
131config FB_TFT_TINYLCD
132 tristate "FB driver for tinylcd.com display"
133 depends on FB_TFT
134 help
135 Custom Framebuffer support for tinylcd.com display
136
137config FB_TFT_TLS8204
138 tristate "FB driver for the TLS8204 LCD Controller"
139 depends on FB_TFT
140 help
141 Generic Framebuffer support for TLS8204
142
143config FB_TFT_UC1701
144 tristate "FB driver for the UC1701 LCD Controller"
145 depends on FB_TFT
146 help
147 Generic Framebuffer support for UC1701
148
149config FB_TFT_UPD161704
150 tristate "FB driver for the uPD161704 LCD Controller"
151 depends on FB_TFT
152 help
153 Generic Framebuffer support for uPD161704
154
155config FB_TFT_WATTEROTT
156 tristate "FB driver for the WATTEROTT LCD Controller"
157 depends on FB_TFT
158 help
159 Generic Framebuffer support for WATTEROTT
160
161config FB_FLEX
162 tristate "Generic FB driver for TFT LCD displays"
163 depends on FB_TFT
164 help
165 Generic Framebuffer support for TFT LCD displays.
166
167config FB_TFT_FBTFT_DEVICE
168 tristate "Module to for adding FBTFT devices"
169 depends on FB_TFT
diff --git a/drivers/staging/fbtft/Makefile b/drivers/staging/fbtft/Makefile
new file mode 100644
index 000000000000..e773f0fdcfe8
--- /dev/null
+++ b/drivers/staging/fbtft/Makefile
@@ -0,0 +1,34 @@
1# Core module
2obj-$(CONFIG_FB_TFT) += fbtft.o
3fbtft-y += fbtft-core.o fbtft-sysfs.o fbtft-bus.o fbtft-io.o
4
5# drivers
6obj-$(CONFIG_FB_TFT_AGM1264K_FL) += fb_agm1264k-fl.o
7obj-$(CONFIG_FB_TFT_BD663474) += fb_bd663474.o
8obj-$(CONFIG_FB_TFT_HX8340BN) += fb_hx8340bn.o
9obj-$(CONFIG_FB_TFT_HX8347D) += fb_hx8347d.o
10obj-$(CONFIG_FB_TFT_HX8353D) += fb_hx8353d.o
11obj-$(CONFIG_FB_TFT_ILI9320) += fb_ili9320.o
12obj-$(CONFIG_FB_TFT_ILI9325) += fb_ili9325.o
13obj-$(CONFIG_FB_TFT_ILI9340) += fb_ili9340.o
14obj-$(CONFIG_FB_TFT_ILI9341) += fb_ili9341.o
15obj-$(CONFIG_FB_TFT_ILI9481) += fb_ili9481.o
16obj-$(CONFIG_FB_TFT_ILI9486) += fb_ili9486.o
17obj-$(CONFIG_FB_TFT_PCD8544) += fb_pcd8544.o
18obj-$(CONFIG_FB_TFT_RA8875) += fb_ra8875.o
19obj-$(CONFIG_FB_TFT_S6D02A1) += fb_s6d02a1.o
20obj-$(CONFIG_FB_TFT_S6D1121) += fb_s6d1121.o
21obj-$(CONFIG_FB_TFT_SSD1289) += fb_ssd1289.o
22obj-$(CONFIG_FB_TFT_SSD1306) += fb_ssd1306.o
23obj-$(CONFIG_FB_TFT_SSD1331) += fb_ssd1331.o
24obj-$(CONFIG_FB_TFT_SSD1351) += fb_ssd1351.o
25obj-$(CONFIG_FB_TFT_ST7735R) += fb_st7735r.o
26obj-$(CONFIG_FB_TFT_TINYLCD) += fb_tinylcd.o
27obj-$(CONFIG_FB_TFT_TLS8204) += fb_tls8204.o
28obj-$(CONFIG_FB_TFT_UC1701) += fb_uc1701.o
29obj-$(CONFIG_FB_TFT_UPD161704) += fb_upd161704.o
30obj-$(CONFIG_FB_TFT_WATTEROTT) += fb_watterott.o
31obj-$(CONFIG_FB_FLEX) += flexfb.o
32
33# Device modules
34obj-$(CONFIG_FB_TFT_FBTFT_DEVICE) += fbtft_device.o
diff --git a/drivers/staging/fbtft/README b/drivers/staging/fbtft/README
new file mode 100644
index 000000000000..bc89b5805f7b
--- /dev/null
+++ b/drivers/staging/fbtft/README
@@ -0,0 +1,32 @@
1 FBTFT
2=========
3
4Linux Framebuffer drivers for small TFT LCD display modules.
5The module 'fbtft' makes writing drivers for some of these displays very easy.
6
7Development is done on a Raspberry Pi running the Raspbian "wheezy" distribution.
8
9INSTALLATION
10 Download kernel sources
11
12 From Linux 3.15
13 cd drivers/video/fbdev/fbtft
14 git clone https://github.com/notro/fbtft.git
15
16 Add to drivers/video/fbdev/Kconfig: source "drivers/video/fbdev/fbtft/Kconfig"
17 Add to drivers/video/fbdev/Makefile: obj-y += fbtft/
18
19 Before Linux 3.15
20 cd drivers/video
21 git clone https://github.com/notro/fbtft.git
22
23 Add to drivers/video/Kconfig: source "drivers/video/fbtft/Kconfig"
24 Add to drivers/video/Makefile: obj-y += fbtft/
25
26 Enable driver(s) in menuconfig and build the kernel
27
28
29See wiki for more information: https://github.com/notro/fbtft/wiki
30
31
32Source: https://github.com/notro/fbtft/
diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c
new file mode 100644
index 000000000000..9cc7d25cf0e5
--- /dev/null
+++ b/drivers/staging/fbtft/fb_agm1264k-fl.c
@@ -0,0 +1,462 @@
1/*
2 * FB driver for Two KS0108 LCD controllers in AGM1264K-FL display
3 *
4 * Copyright (C) 2014 ololoshka2871
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/gpio.h>
21#include <linux/delay.h>
22#include <linux/slab.h>
23
24#include "fbtft.h"
25
26/* Uncomment text line to use negative image on display */
27/*#define NEGATIVE*/
28
29#define WHITE 0xff
30#define BLACK 0
31
32#define DRVNAME "fb_agm1264k-fl"
33#define WIDTH 64
34#define HEIGHT 64
35#define TOTALWIDTH (WIDTH * 2) /* because 2 x ks0108 in one display */
36#define FPS 20
37
38#define EPIN gpio.wr
39#define RS gpio.dc
40#define RW gpio.aux[2]
41#define CS0 gpio.aux[0]
42#define CS1 gpio.aux[1]
43
44
45/* diffusing error (“Floyd-Steinberg”) */
46#define DIFFUSING_MATRIX_WIDTH 2
47#define DIFFUSING_MATRIX_HEIGHT 2
48
49static const signed char
50diffusing_matrix[DIFFUSING_MATRIX_WIDTH][DIFFUSING_MATRIX_HEIGHT] = {
51 {-1, 3},
52 {3, 2},
53};
54
55static const unsigned char gamma_correction_table[] = {
560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
571, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
586, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13,
5913, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21,
6022, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32,
6133, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 43, 44, 45,
6246, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
6362, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 81,
6482, 83, 84, 85, 87, 88, 89, 90, 91, 93, 94, 95, 97, 98, 99, 100, 102,
65103, 105, 106, 107, 109, 110, 111, 113, 114, 116, 117, 119, 120, 121,
66123, 124, 126, 127, 129, 130, 132, 133, 135, 137, 138, 140, 141, 143,
67145, 146, 148, 149, 151, 153, 154, 156, 158, 159, 161, 163, 165, 166,
68168, 170, 172, 173, 175, 177, 179, 181, 182, 184, 186, 188, 190, 192,
69194, 196, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219,
70221, 223, 225, 227, 229, 231, 234, 236, 238, 240, 242, 244, 246, 248,
71251, 253, 255
72};
73
74static int init_display(struct fbtft_par *par)
75{
76 u8 i;
77
78 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
79
80 par->fbtftops.reset(par);
81
82 for (i = 0; i < 2; ++i) {
83 write_reg(par, i, 0x3f); /* display on */
84 write_reg(par, i, 0x40); /* set x to 0 */
85 write_reg(par, i, 0xb0); /* set page to 0 */
86 write_reg(par, i, 0xc0); /* set start line to 0 */
87 }
88
89 return 0;
90}
91
92static void reset(struct fbtft_par *par)
93{
94 if (par->gpio.reset == -1)
95 return;
96
97 fbtft_dev_dbg(DEBUG_RESET, par, par->info->device, "%s()\n", __func__);
98
99 gpio_set_value(par->gpio.reset, 0);
100 udelay(20);
101 gpio_set_value(par->gpio.reset, 1);
102 mdelay(120);
103}
104
105/* Check if all necessary GPIOS defined */
106static int verify_gpios(struct fbtft_par *par)
107{
108 int i;
109
110 fbtft_dev_dbg(DEBUG_VERIFY_GPIOS, par, par->info->device,
111 "%s()\n", __func__);
112
113 if (par->EPIN < 0) {
114 dev_err(par->info->device,
115 "Missing info about 'wr' (aka E) gpio. Aborting.\n");
116 return -EINVAL;
117 }
118 for (i = 0; i < 8; ++i) {
119 if (par->gpio.db[i] < 0) {
120 dev_err(par->info->device,
121 "Missing info about 'db[%i]' gpio. Aborting.\n",
122 i);
123 return -EINVAL;
124 }
125 }
126 if (par->CS0 < 0) {
127 dev_err(par->info->device,
128 "Missing info about 'cs0' gpio. Aborting.\n");
129 return -EINVAL;
130 }
131 if (par->CS1 < 0) {
132 dev_err(par->info->device,
133 "Missing info about 'cs1' gpio. Aborting.\n");
134 return -EINVAL;
135 }
136 if (par->RW < 0) {
137 dev_err(par->info->device,
138 "Missing info about 'rw' gpio. Aborting.\n");
139 return -EINVAL;
140 }
141
142 return 0;
143}
144
145static unsigned long
146request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio)
147{
148 fbtft_dev_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, par->info->device,
149 "%s('%s')\n", __func__, gpio->name);
150
151 if (strcasecmp(gpio->name, "wr") == 0) {
152 /* left ks0108 E pin */
153 par->EPIN = gpio->gpio;
154 return GPIOF_OUT_INIT_LOW;
155 } else if (strcasecmp(gpio->name, "cs0") == 0) {
156 /* left ks0108 controller pin */
157 par->CS0 = gpio->gpio;
158 return GPIOF_OUT_INIT_HIGH;
159 } else if (strcasecmp(gpio->name, "cs1") == 0) {
160 /* right ks0108 controller pin */
161 par->CS1 = gpio->gpio;
162 return GPIOF_OUT_INIT_HIGH;
163 }
164
165 /* if write (rw = 0) e(1->0) perform write */
166 /* if read (rw = 1) e(0->1) set data on D0-7*/
167 else if (strcasecmp(gpio->name, "rw") == 0) {
168 par->RW = gpio->gpio;
169 return GPIOF_OUT_INIT_LOW;
170 }
171
172 return FBTFT_GPIO_NO_MATCH;
173}
174
175/* This function oses to enter commands
176 * first byte - destination controller 0 or 1
177 * folowing - commands
178 */
179static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
180{
181 va_list args;
182 int i, ret;
183 u8 *buf = (u8 *)par->buf;
184
185 if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
186 va_start(args, len);
187 for (i = 0; i < len; i++)
188 buf[i] = (u8)va_arg(args, unsigned int);
189
190 va_end(args);
191 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par,
192 par->info->device, u8, buf, len, "%s: ", __func__);
193 }
194
195 va_start(args, len);
196
197 *buf = (u8)va_arg(args, unsigned int);
198
199 if (*buf > 1) {
200 va_end(args);
201 dev_err(par->info->device, "%s: Incorrect chip sellect request (%d)\n",
202 __func__, *buf);
203 return;
204 }
205
206 /* select chip */
207 if (*buf) {
208 /* cs1 */
209 gpio_set_value(par->CS0, 1);
210 gpio_set_value(par->CS1, 0);
211 } else {
212 /* cs0 */
213 gpio_set_value(par->CS0, 0);
214 gpio_set_value(par->CS1, 1);
215 }
216
217 gpio_set_value(par->RS, 0); /* RS->0 (command mode) */
218 len--;
219
220 if (len) {
221 i = len;
222 while (i--)
223 *buf++ = (u8)va_arg(args, unsigned int);
224 ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8)));
225 if (ret < 0) {
226 va_end(args);
227 dev_err(par->info->device, "%s: write() failed and returned %d\n",
228 __func__, ret);
229 return;
230 }
231 }
232
233 va_end(args);
234}
235
236static struct
237{
238 int xs, ys_page, xe, ye_page;
239} addr_win;
240
241/* save display writing zone */
242static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
243{
244 addr_win.xs = xs;
245 addr_win.ys_page = ys / 8;
246 addr_win.xe = xe;
247 addr_win.ye_page = ye / 8;
248
249 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
250 "%s(xs=%d, ys_page=%d, xe=%d, ye_page=%d)\n", __func__,
251 addr_win.xs, addr_win.ys_page, addr_win.xe, addr_win.ye_page);
252}
253
254static void
255construct_line_bitmap(struct fbtft_par *par, u8 *dest, signed short *src,
256 int xs, int xe, int y)
257{
258 int x, i;
259
260 for (x = xs; x < xe; ++x) {
261 u8 res = 0;
262
263 for (i = 0; i < 8; i++)
264 if (src[(y * 8 + i) * par->info->var.xres + x])
265 res |= 1 << i;
266#ifdef NEGATIVE
267 *dest++ = res;
268#else
269 *dest++ = ~res;
270#endif
271 }
272}
273
274static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
275{
276 u16 *vmem16 = (u16 *)par->info->screen_base;
277 u8 *buf = par->txbuf.buf;
278 int x, y;
279 int ret = 0;
280
281 /* buffer to convert RGB565 -> grayscale16 -> Ditherd image 1bpp */
282 signed short *convert_buf = kmalloc(par->info->var.xres *
283 par->info->var.yres * sizeof(signed short), GFP_NOIO);
284
285 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
286
287 /* converting to grayscale16 */
288 for (x = 0; x < par->info->var.xres; ++x)
289 for (y = 0; y < par->info->var.yres; ++y) {
290 u16 pixel = vmem16[y * par->info->var.xres + x];
291 u16 b = pixel & 0x1f;
292 u16 g = (pixel & (0x3f << 5)) >> 5;
293 u16 r = (pixel & (0x1f << (5 + 6))) >> (5 + 6);
294
295 pixel = (299 * r + 587 * g + 114 * b) / 200;
296 if (pixel > 255)
297 pixel = 255;
298
299 /* gamma-correction by table */
300 convert_buf[y * par->info->var.xres + x] =
301 (signed short)gamma_correction_table[pixel];
302 }
303
304 /* Image Dithering */
305 for (x = 0; x < par->info->var.xres; ++x)
306 for (y = 0; y < par->info->var.yres; ++y) {
307 signed short pixel =
308 convert_buf[y * par->info->var.xres + x];
309 signed short error_b = pixel - BLACK;
310 signed short error_w = pixel - WHITE;
311 signed short error;
312 u16 i, j;
313
314 /* what color close? */
315 if (abs(error_b) >= abs(error_w)) {
316 /* white */
317 error = error_w;
318 pixel = 0xff;
319 } else {
320 /* black */
321 error = error_b;
322 pixel = 0;
323 }
324
325 error /= 8;
326
327 /* diffusion matrix row */
328 for (i = 0; i < DIFFUSING_MATRIX_WIDTH; ++i)
329 /* diffusion matrix column */
330 for (j = 0; j < DIFFUSING_MATRIX_HEIGHT; ++j) {
331 signed short *write_pos;
332 signed char coeff;
333
334 /* skip pixels out of zone */
335 if (x + i < 0 ||
336 x + i >= par->info->var.xres
337 || y + j >= par->info->var.yres)
338 continue;
339 write_pos = &convert_buf[
340 (y + j) * par->info->var.xres +
341 x + i];
342 coeff = diffusing_matrix[i][j];
343 if (coeff == -1)
344 /* pixel itself */
345 *write_pos = pixel;
346 else {
347 signed short p = *write_pos +
348 error * coeff;
349
350 if (p > WHITE)
351 p = WHITE;
352 if (p < BLACK)
353 p = BLACK;
354 *write_pos = p;
355 }
356 }
357 }
358
359 /* 1 string = 2 pages */
360 for (y = addr_win.ys_page; y <= addr_win.ye_page; ++y) {
361 /* left half of display */
362 if (addr_win.xs < par->info->var.xres / 2) {
363 construct_line_bitmap(par, buf, convert_buf,
364 addr_win.xs, par->info->var.xres / 2, y);
365
366 len = par->info->var.xres / 2 - addr_win.xs;
367
368 /* select left side (sc0)
369 * set addr
370 */
371 write_reg(par, 0x00, (1 << 6) | (u8)addr_win.xs);
372 write_reg(par, 0x00, (0x17 << 3) | (u8)y);
373
374 /* write bitmap */
375 gpio_set_value(par->RS, 1); /* RS->1 (data mode) */
376 ret = par->fbtftops.write(par, buf, len);
377 if (ret < 0)
378 dev_err(par->info->device,
379 "%s: write failed and returned: %d\n",
380 __func__, ret);
381 }
382 /* right half of display */
383 if (addr_win.xe >= par->info->var.xres / 2) {
384 construct_line_bitmap(par, buf,
385 convert_buf, par->info->var.xres / 2,
386 addr_win.xe + 1, y);
387
388 len = addr_win.xe + 1 - par->info->var.xres / 2;
389
390 /* select right side (sc1)
391 * set addr
392 */
393 write_reg(par, 0x01, (1 << 6));
394 write_reg(par, 0x01, (0x17 << 3) | (u8)y);
395
396 /* write bitmap */
397 gpio_set_value(par->RS, 1); /* RS->1 (data mode) */
398 par->fbtftops.write(par, buf, len);
399 if (ret < 0)
400 dev_err(par->info->device,
401 "%s: write failed and returned: %d\n",
402 __func__, ret);
403 }
404 }
405 kfree(convert_buf);
406
407 gpio_set_value(par->CS0, 1);
408 gpio_set_value(par->CS1, 1);
409
410 return ret;
411}
412
413static int write(struct fbtft_par *par, void *buf, size_t len)
414{
415 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
416 "%s(len=%d): ", __func__, len);
417
418 gpio_set_value(par->RW, 0); /* set write mode */
419
420
421 while (len--) {
422 u8 i, data;
423
424 data = *(u8 *) buf++;
425
426 /* set data bus */
427 for (i = 0; i < 8; ++i)
428 gpio_set_value(par->gpio.db[i], data & (1 << i));
429 /* set E */
430 gpio_set_value(par->EPIN, 1);
431 udelay(5);
432 /* unset E - write */
433 gpio_set_value(par->EPIN, 0);
434 udelay(1);
435 }
436
437 return 0;
438}
439
440static struct fbtft_display display = {
441 .regwidth = 8,
442 .width = TOTALWIDTH,
443 .height = HEIGHT,
444 .fps = FPS,
445 .fbtftops = {
446 .init_display = init_display,
447 .set_addr_win = set_addr_win,
448 .verify_gpios = verify_gpios,
449 .request_gpios_match = request_gpios_match,
450 .reset = reset,
451 .write = write,
452 .write_register = write_reg8_bus8,
453 .write_vmem = write_vmem,
454 },
455};
456FBTFT_REGISTER_DRIVER(DRVNAME, "displaytronic,fb_agm1264k-fl", &display);
457
458MODULE_ALIAS("platform:" DRVNAME);
459
460MODULE_DESCRIPTION("Two KS0108 LCD controllers in AGM1264K-FL display");
461MODULE_AUTHOR("ololoshka2871");
462MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c
new file mode 100644
index 000000000000..7e00c609c7fe
--- /dev/null
+++ b/drivers/staging/fbtft/fb_bd663474.c
@@ -0,0 +1,193 @@
1/*
2 * FB driver for the uPD161704 LCD Controller
3 *
4 * Copyright (C) 2014 Seong-Woo Kim
5 *
6 * Based on fb_ili9325.c by Noralf Tronnes
7 * Based on ili9325.c by Jeroen Domburg
8 * Init code from UTFT library by Henning Karlsen
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/gpio.h>
29#include <linux/delay.h>
30
31#include "fbtft.h"
32
33#define DRVNAME "fb_bd663474"
34#define WIDTH 240
35#define HEIGHT 320
36#define BPP 16
37
38static int init_display(struct fbtft_par *par)
39{
40 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
41
42 if (par->gpio.cs != -1)
43 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
44
45 par->fbtftops.reset(par);
46
47 /* Initialization sequence from Lib_UTFT */
48
49 /* oscillator start */
50 write_reg(par, 0x000,0x0001); /*oscillator 0: stop, 1: operation */
51 mdelay(10);
52
53 /* Power settings */
54 write_reg(par, 0x100, 0x0000 ); /* power supply setup */
55 write_reg(par, 0x101, 0x0000 );
56 write_reg(par, 0x102, 0x3110 );
57 write_reg(par, 0x103, 0xe200 );
58 write_reg(par, 0x110, 0x009d );
59 write_reg(par, 0x111, 0x0022 );
60 write_reg(par, 0x100, 0x0120 );
61 mdelay( 20 );
62
63 write_reg(par, 0x100, 0x3120 );
64 mdelay( 80 );
65 /* Display control */
66 write_reg(par, 0x001, 0x0100 );
67 write_reg(par, 0x002, 0x0000 );
68 write_reg(par, 0x003, 0x1230 );
69 write_reg(par, 0x006, 0x0000 );
70 write_reg(par, 0x007, 0x0101 );
71 write_reg(par, 0x008, 0x0808 );
72 write_reg(par, 0x009, 0x0000 );
73 write_reg(par, 0x00b, 0x0000 );
74 write_reg(par, 0x00c, 0x0000 );
75 write_reg(par, 0x00d, 0x0018 );
76 /* LTPS control settings */
77 write_reg(par, 0x012, 0x0000 );
78 write_reg(par, 0x013, 0x0000 );
79 write_reg(par, 0x018, 0x0000 );
80 write_reg(par, 0x019, 0x0000 );
81
82 write_reg(par, 0x203, 0x0000 );
83 write_reg(par, 0x204, 0x0000 );
84
85 write_reg(par, 0x210, 0x0000 );
86 write_reg(par, 0x211, 0x00ef );
87 write_reg(par, 0x212, 0x0000 );
88 write_reg(par, 0x213, 0x013f );
89 write_reg(par, 0x214, 0x0000 );
90 write_reg(par, 0x215, 0x0000 );
91 write_reg(par, 0x216, 0x0000 );
92 write_reg(par, 0x217, 0x0000 );
93
94 /* Gray scale settings */
95 write_reg(par, 0x300, 0x5343);
96 write_reg(par, 0x301, 0x1021);
97 write_reg(par, 0x302, 0x0003);
98 write_reg(par, 0x303, 0x0011);
99 write_reg(par, 0x304, 0x050a);
100 write_reg(par, 0x305, 0x4342);
101 write_reg(par, 0x306, 0x1100);
102 write_reg(par, 0x307, 0x0003);
103 write_reg(par, 0x308, 0x1201);
104 write_reg(par, 0x309, 0x050a);
105
106 /* RAM access settings */
107 write_reg(par, 0x400, 0x4027 );
108 write_reg(par, 0x401, 0x0000 );
109 write_reg(par, 0x402, 0x0000 ); /* First screen drive position (1) */
110 write_reg(par, 0x403, 0x013f ); /* First screen drive position (2) */
111 write_reg(par, 0x404, 0x0000 );
112
113 write_reg(par, 0x200, 0x0000 );
114 write_reg(par, 0x201, 0x0000 );
115 write_reg(par, 0x100, 0x7120 );
116 write_reg(par, 0x007, 0x0103 );
117 mdelay( 10 );
118 write_reg(par, 0x007, 0x0113 );
119
120 return 0;
121}
122
123static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
124{
125 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
126 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
127 switch (par->info->var.rotate) {
128 /* R200h = Horizontal GRAM Start Address */
129 /* R201h = Vertical GRAM Start Address */
130 case 0:
131 write_reg(par, 0x0200, xs);
132 write_reg(par, 0x0201, ys);
133 break;
134 case 180:
135 write_reg(par, 0x0200, WIDTH - 1 - xs);
136 write_reg(par, 0x0201, HEIGHT - 1 - ys);
137 break;
138 case 270:
139 write_reg(par, 0x0200, WIDTH - 1 - ys);
140 write_reg(par, 0x0201, xs);
141 break;
142 case 90:
143 write_reg(par, 0x0200, ys);
144 write_reg(par, 0x0201, HEIGHT - 1 - xs);
145 break;
146 }
147 write_reg(par, 0x202); /* Write Data to GRAM */
148}
149
150static int set_var(struct fbtft_par *par)
151{
152 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
153
154 switch (par->info->var.rotate) {
155 /* AM: GRAM update direction */
156 case 0:
157 write_reg(par, 0x003, 0x1230);
158 break;
159 case 180:
160 write_reg(par, 0x003, 0x1200);
161 break;
162 case 270:
163 write_reg(par, 0x003, 0x1228);
164 break;
165 case 90:
166 write_reg(par, 0x003, 0x1218);
167 break;
168 }
169
170 return 0;
171}
172
173static struct fbtft_display display = {
174 .regwidth = 16,
175 .width = WIDTH,
176 .height = HEIGHT,
177 .bpp = BPP,
178 .fbtftops = {
179 .init_display = init_display,
180 .set_addr_win = set_addr_win,
181 .set_var = set_var,
182 },
183};
184FBTFT_REGISTER_DRIVER(DRVNAME, "hitachi,bd663474", &display);
185
186MODULE_ALIAS("spi:" DRVNAME);
187MODULE_ALIAS("platform:" DRVNAME);
188MODULE_ALIAS("spi:bd663474");
189MODULE_ALIAS("platform:bd663474");
190
191MODULE_DESCRIPTION("FB driver for the uPD161704 LCD Controller");
192MODULE_AUTHOR("Seong-Woo Kim");
193MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c
new file mode 100644
index 000000000000..3939502f2c81
--- /dev/null
+++ b/drivers/staging/fbtft/fb_hx8340bn.c
@@ -0,0 +1,229 @@
1/*
2 * FB driver for the HX8340BN LCD Controller
3 *
4 * This display uses 9-bit SPI: Data/Command bit + 8 data bits
5 * For platforms that doesn't support 9-bit, the driver is capable
6 * of emulating this using 8-bit transfer.
7 * This is done by transfering eight 9-bit words in 9 bytes.
8 *
9 * Copyright (C) 2013 Noralf Tronnes
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/vmalloc.h>
30#include <linux/spi/spi.h>
31#include <linux/delay.h>
32
33#include "fbtft.h"
34
35#define DRVNAME "fb_hx8340bn"
36#define WIDTH 176
37#define HEIGHT 220
38#define TXBUFLEN (4 * PAGE_SIZE)
39#define DEFAULT_GAMMA "1 3 0E 5 0 2 09 0 6 1 7 1 0 2 2\n" \
40 "3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "
41
42
43static bool emulate;
44module_param(emulate, bool, 0);
45MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");
46
47
48static int init_display(struct fbtft_par *par)
49{
50 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
51
52 par->fbtftops.reset(par);
53
54 /* BTL221722-276L startup sequence, from datasheet */
55
56 /* SETEXTCOM: Set extended command set (C1h)
57 This command is used to set extended command set access enable.
58 Enable: After command (C1h), must write: ffh,83h,40h */
59 write_reg(par, 0xC1, 0xFF, 0x83, 0x40);
60
61 /* Sleep out
62 This command turns off sleep mode.
63 In this mode the DC/DC converter is enabled, Internal oscillator
64 is started, and panel scanning is started. */
65 write_reg(par, 0x11);
66 mdelay(150);
67
68 /* Undoc'd register? */
69 write_reg(par, 0xCA, 0x70, 0x00, 0xD9);
70
71 /* SETOSC: Set Internal Oscillator (B0h)
72 This command is used to set internal oscillator related settings */
73 /* OSC_EN: Enable internal oscillator */
74 /* Internal oscillator frequency: 125% x 2.52MHz */
75 write_reg(par, 0xB0, 0x01, 0x11);
76
77 /* Drive ability setting */
78 write_reg(par, 0xC9, 0x90, 0x49, 0x10, 0x28, 0x28, 0x10, 0x00, 0x06);
79 mdelay(20);
80
81 /* SETPWCTR5: Set Power Control 5(B5h)
82 This command is used to set VCOM Low and VCOM High Voltage */
83 /* VCOMH 0110101 : 3.925 */
84 /* VCOML 0100000 : -1.700 */
85 /* 45h=69 VCOMH: "VMH" + 5d VCOML: "VMH" + 5d */
86 write_reg(par, 0xB5, 0x35, 0x20, 0x45);
87
88 /* SETPWCTR4: Set Power Control 4(B4h)
89 VRH[4:0]: Specify the VREG1 voltage adjusting.
90 VREG1 voltage is for gamma voltage setting.
91 BT[2:0]: Switch the output factor of step-up circuit 2
92 for VGH and VGL voltage generation. */
93 write_reg(par, 0xB4, 0x33, 0x25, 0x4C);
94 mdelay(10);
95
96 /* Interface Pixel Format (3Ah)
97 This command is used to define the format of RGB picture data,
98 which is to be transfer via the system and RGB interface. */
99 /* RGB interface: 16 Bit/Pixel */
100 write_reg(par, 0x3A, 0x05);
101
102 /* Display on (29h)
103 This command is used to recover from DISPLAY OFF mode.
104 Output from the Frame Memory is enabled. */
105 write_reg(par, 0x29);
106 mdelay(10);
107
108 return 0;
109}
110
111void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
112{
113 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
114 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
115
116 write_reg(par, FBTFT_CASET, 0x00, xs, 0x00, xe);
117 write_reg(par, FBTFT_RASET, 0x00, ys, 0x00, ye);
118 write_reg(par, FBTFT_RAMWR);
119}
120
121static int set_var(struct fbtft_par *par)
122{
123 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
124
125 /* MADCTL - Memory data access control */
126 /* RGB/BGR can be set with H/W pin SRGB and MADCTL BGR bit */
127#define MY (1 << 7)
128#define MX (1 << 6)
129#define MV (1 << 5)
130 switch (par->info->var.rotate) {
131 case 0:
132 write_reg(par, 0x36, (par->bgr << 3));
133 break;
134 case 270:
135 write_reg(par, 0x36, MX | MV | (par->bgr << 3));
136 break;
137 case 180:
138 write_reg(par, 0x36, MX | MY | (par->bgr << 3));
139 break;
140 case 90:
141 write_reg(par, 0x36, MY | MV | (par->bgr << 3));
142 break;
143 }
144
145 return 0;
146}
147
148/*
149 Gamma Curve selection, GC (only GC0 can be customized):
150 0 = 2.2, 1 = 1.8, 2 = 2.5, 3 = 1.0
151 Gamma string format:
152 OP0 OP1 CP0 CP1 CP2 CP3 CP4 MP0 MP1 MP2 MP3 MP4 MP5 CGM0 CGM1
153 ON0 ON1 CN0 CN1 CN2 CN3 CN4 MN0 MN1 MN2 MN3 MN4 MN5 XXXX GC
154*/
155#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
156static int set_gamma(struct fbtft_par *par, unsigned long *curves)
157{
158 unsigned long mask[] = {
159 0b1111, 0b1111, 0b11111, 0b1111, 0b1111, 0b1111, 0b11111,
160 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b11, 0b11,
161 0b1111, 0b1111, 0b11111, 0b1111, 0b1111, 0b1111, 0b11111,
162 0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b0, 0b0 };
163 int i, j;
164
165 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
166
167 /* apply mask */
168 for (i = 0; i < par->gamma.num_curves; i++)
169 for (j = 0; j < par->gamma.num_values; j++)
170 CURVE(i, j) &= mask[i * par->gamma.num_values + j];
171
172 write_reg(par, 0x26, 1 << CURVE(1, 14)); /* Gamma Set (26h) */
173
174 if (CURVE(1, 14))
175 return 0; /* only GC0 can be customized */
176
177 write_reg(par, 0xC2,
178 (CURVE(0, 8) << 4) | CURVE(0, 7),
179 (CURVE(0, 10) << 4) | CURVE(0, 9),
180 (CURVE(0, 12) << 4) | CURVE(0, 11),
181 CURVE(0, 2),
182 (CURVE(0, 4) << 4) | CURVE(0, 3),
183 CURVE(0, 5),
184 CURVE(0, 6),
185 (CURVE(0, 1) << 4) | CURVE(0, 0),
186 (CURVE(0, 14) << 2) | CURVE(0, 13));
187
188 write_reg(par, 0xC3,
189 (CURVE(1, 8) << 4) | CURVE(1, 7),
190 (CURVE(1, 10) << 4) | CURVE(1, 9),
191 (CURVE(1, 12) << 4) | CURVE(1, 11),
192 CURVE(1, 2),
193 (CURVE(1, 4) << 4) | CURVE(1, 3),
194 CURVE(1, 5),
195 CURVE(1, 6),
196 (CURVE(1, 1) << 4) | CURVE(1, 0));
197
198 mdelay(10);
199
200 return 0;
201}
202#undef CURVE
203
204
205static struct fbtft_display display = {
206 .regwidth = 8,
207 .width = WIDTH,
208 .height = HEIGHT,
209 .txbuflen = TXBUFLEN,
210 .gamma_num = 2,
211 .gamma_len = 15,
212 .gamma = DEFAULT_GAMMA,
213 .fbtftops = {
214 .init_display = init_display,
215 .set_addr_win = set_addr_win,
216 .set_var = set_var,
217 .set_gamma = set_gamma,
218 },
219};
220FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", &display);
221
222MODULE_ALIAS("spi:" DRVNAME);
223MODULE_ALIAS("platform:" DRVNAME);
224MODULE_ALIAS("spi:hx8340bn");
225MODULE_ALIAS("platform:hx8340bn");
226
227MODULE_DESCRIPTION("FB driver for the HX8340BN LCD Controller");
228MODULE_AUTHOR("Noralf Tronnes");
229MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_hx8347d.c b/drivers/staging/fbtft/fb_hx8347d.c
new file mode 100644
index 000000000000..8139a8f587b7
--- /dev/null
+++ b/drivers/staging/fbtft/fb_hx8347d.c
@@ -0,0 +1,181 @@
1/*
2 * FB driver for the HX8347D LCD Controller
3 *
4 * Copyright (C) 2013 Christian Vogelgsang
5 *
6 * Based on driver code found here: https://github.com/watterott/r61505u-Adapter
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27
28#include "fbtft.h"
29
30#define DRVNAME "fb_hx8347d"
31#define WIDTH 320
32#define HEIGHT 240
33#define DEFAULT_GAMMA "0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" \
34 "0 0 0 0 0 0 0 0 0 0 0 0 0 0"
35
36
37static int init_display(struct fbtft_par *par)
38{
39 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
40
41 par->fbtftops.reset(par);
42
43 /* driving ability */
44 write_reg(par, 0xEA, 0x00);
45 write_reg(par, 0xEB, 0x20);
46 write_reg(par, 0xEC, 0x0C);
47 write_reg(par, 0xED, 0xC4);
48 write_reg(par, 0xE8, 0x40);
49 write_reg(par, 0xE9, 0x38);
50 write_reg(par, 0xF1, 0x01);
51 write_reg(par, 0xF2, 0x10);
52 write_reg(par, 0x27, 0xA3);
53
54 /* power voltage */
55 write_reg(par, 0x1B, 0x1B);
56 write_reg(par, 0x1A, 0x01);
57 write_reg(par, 0x24, 0x2F);
58 write_reg(par, 0x25, 0x57);
59
60 /* VCOM offset */
61 write_reg(par, 0x23, 0x8D); /* for flicker adjust */
62
63 /* power on */
64 write_reg(par, 0x18, 0x36);
65 write_reg(par, 0x19, 0x01); /* start osc */
66 write_reg(par, 0x01, 0x00); /* wakeup */
67 write_reg(par, 0x1F, 0x88);
68 mdelay(5);
69 write_reg(par, 0x1F, 0x80);
70 mdelay(5);
71 write_reg(par, 0x1F, 0x90);
72 mdelay(5);
73 write_reg(par, 0x1F, 0xD0);
74 mdelay(5);
75
76 /* color selection */
77 write_reg(par, 0x17, 0x05); /* 65k */
78
79 /*panel characteristic */
80 write_reg(par, 0x36, 0x00);
81
82 /*display on */
83 write_reg(par, 0x28, 0x38);
84 mdelay(40);
85 write_reg(par, 0x28, 0x3C);
86
87 /* orientation */
88 write_reg(par, 0x16, 0x60 | (par->bgr << 3));
89
90 return 0;
91}
92
93static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
94{
95 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
96 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
97
98 write_reg(par, 0x02, (xs >> 8) & 0xFF);
99 write_reg(par, 0x03, xs & 0xFF);
100 write_reg(par, 0x04, (xe >> 8) & 0xFF);
101 write_reg(par, 0x05, xe & 0xFF);
102 write_reg(par, 0x06, (ys >> 8) & 0xFF);
103 write_reg(par, 0x07, ys & 0xFF);
104 write_reg(par, 0x08, (ye >> 8) & 0xFF);
105 write_reg(par, 0x09, ye & 0xFF);
106 write_reg(par, 0x22);
107}
108
109/*
110 Gamma string format:
111 VRP0 VRP1 VRP2 VRP3 VRP4 VRP5 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 CGM
112 VRN0 VRN1 VRN2 VRN3 VRN4 VRN5 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 CGM
113*/
114#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
115static int set_gamma(struct fbtft_par *par, unsigned long *curves)
116{
117 unsigned long mask[] = {
118 0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
119 0b1111111, 0b1111111,
120 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
121 0b1111};
122 int i, j;
123 int acc = 0;
124
125 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
126
127 /* apply mask */
128 for (i = 0; i < par->gamma.num_curves; i++)
129 for (j = 0; j < par->gamma.num_values; j++) {
130 acc += CURVE(i, j);
131 CURVE(i, j) &= mask[j];
132 }
133
134 if (acc == 0) /* skip if all values are zero */
135 return 0;
136
137 for (i = 0; i < par->gamma.num_curves; i++) {
138 write_reg(par, 0x40 + (i * 0x10), CURVE(i, 0));
139 write_reg(par, 0x41 + (i * 0x10), CURVE(i, 1));
140 write_reg(par, 0x42 + (i * 0x10), CURVE(i, 2));
141 write_reg(par, 0x43 + (i * 0x10), CURVE(i, 3));
142 write_reg(par, 0x44 + (i * 0x10), CURVE(i, 4));
143 write_reg(par, 0x45 + (i * 0x10), CURVE(i, 5));
144 write_reg(par, 0x46 + (i * 0x10), CURVE(i, 6));
145 write_reg(par, 0x47 + (i * 0x10), CURVE(i, 7));
146 write_reg(par, 0x48 + (i * 0x10), CURVE(i, 8));
147 write_reg(par, 0x49 + (i * 0x10), CURVE(i, 9));
148 write_reg(par, 0x4A + (i * 0x10), CURVE(i, 10));
149 write_reg(par, 0x4B + (i * 0x10), CURVE(i, 11));
150 write_reg(par, 0x4C + (i * 0x10), CURVE(i, 12));
151 }
152 write_reg(par, 0x5D, (CURVE(1, 0) << 4) | CURVE(0, 0));
153
154 return 0;
155}
156#undef CURVE
157
158
159static struct fbtft_display display = {
160 .regwidth = 8,
161 .width = WIDTH,
162 .height = HEIGHT,
163 .gamma_num = 2,
164 .gamma_len = 14,
165 .gamma = DEFAULT_GAMMA,
166 .fbtftops = {
167 .init_display = init_display,
168 .set_addr_win = set_addr_win,
169 .set_gamma = set_gamma,
170 },
171};
172FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8347d", &display);
173
174MODULE_ALIAS("spi:" DRVNAME);
175MODULE_ALIAS("platform:" DRVNAME);
176MODULE_ALIAS("spi:hx8347d");
177MODULE_ALIAS("platform:hx8347d");
178
179MODULE_DESCRIPTION("FB driver for the HX8347D LCD Controller");
180MODULE_AUTHOR("Christian Vogelgsang");
181MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_hx8353d.c b/drivers/staging/fbtft/fb_hx8353d.c
new file mode 100644
index 000000000000..c9512dc5f4d3
--- /dev/null
+++ b/drivers/staging/fbtft/fb_hx8353d.c
@@ -0,0 +1,166 @@
1/*
2 * FB driver for the HX8353D LCD Controller
3 *
4 * Copyright (c) 2014 Petr Olivka
5 * Copyright (c) 2013 Noralf Tronnes
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26
27#include "fbtft.h"
28
29#define DRVNAME "fb_hx8353d"
30#define DEFAULT_GAMMA "50 77 40 08 BF 00 03 0F 00 01 73 00 72 03 B0 0F 08 00 0F"
31
32static int init_display(struct fbtft_par *par)
33{
34
35 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
36
37 par->fbtftops.reset(par);
38 mdelay(150);
39
40 /* SETEXTC */
41 write_reg(par, 0xB9, 0xFF, 0x83, 0x53);
42
43 /* RADJ */
44 write_reg(par, 0xB0, 0x3C, 0x01);
45
46 /* VCOM */
47 write_reg(par, 0xB6, 0x94, 0x6C, 0x50);
48
49 /* PWR */
50 write_reg(par, 0xB1, 0x00, 0x01, 0x1B, 0x03, 0x01, 0x08, 0x77, 0x89);
51
52 /* COLMOD */
53 write_reg(par, 0x3A, 0x05);
54
55 /* MEM ACCESS */
56 write_reg(par, 0x36, 0xC0);
57
58 /* SLPOUT - Sleep out & booster on */
59 write_reg(par, 0x11);
60 mdelay(150);
61
62 /* DISPON - Display On */
63 write_reg(par, 0x29);
64
65 /* RGBSET */
66 write_reg(par, 0x2D,
67 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
68 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
69 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
70 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
71 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
72 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
73 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
74 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62);
75
76 return 0;
77};
78
79static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
80{
81 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
82 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
83
84 /* column address */
85 write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff);
86
87 /* row adress */
88 write_reg(par, 0x2b, ys >> 8, ys & 0xff, ye >> 8, ye & 0xff);
89
90 /* memory write */
91 write_reg(par, 0x2c);
92}
93
94#define my (1 << 7)
95#define mx (1 << 6)
96#define mv (1 << 5)
97static int set_var(struct fbtft_par *par)
98{
99 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
100
101 /* madctl - memory data access control
102 rgb/bgr:
103 1. mode selection pin srgb
104 rgb h/w pin for color filter setting: 0=rgb, 1=bgr
105 2. madctl rgb bit
106 rgb-bgr order color filter panel: 0=rgb, 1=bgr */
107 switch (par->info->var.rotate) {
108 case 0:
109 write_reg(par, 0x36, mx | my | (par->bgr << 3));
110 break;
111 case 270:
112 write_reg(par, 0x36, my | mv | (par->bgr << 3));
113 break;
114 case 180:
115 write_reg(par, 0x36, (par->bgr << 3));
116 break;
117 case 90:
118 write_reg(par, 0x36, mx | mv | (par->bgr << 3));
119 break;
120 }
121
122 return 0;
123}
124
125/*
126 gamma string format:
127*/
128static int set_gamma(struct fbtft_par *par, unsigned long *curves)
129{
130 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
131
132 write_reg(par, 0xE0,
133 curves[0], curves[1], curves[2], curves[3],
134 curves[4], curves[5], curves[6], curves[7],
135 curves[8], curves[9], curves[10], curves[11],
136 curves[12], curves[13], curves[14], curves[15],
137 curves[16], curves[17], curves[18]);
138
139 return 0;
140}
141
142
143static struct fbtft_display display = {
144 .regwidth = 8,
145 .width = 128,
146 .height = 160,
147 .gamma_num = 1,
148 .gamma_len = 19,
149 .gamma = DEFAULT_GAMMA,
150 .fbtftops = {
151 .init_display = init_display,
152 .set_addr_win = set_addr_win,
153 .set_var = set_var,
154 .set_gamma = set_gamma,
155 },
156};
157FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8353d", &display);
158
159MODULE_ALIAS("spi:" DRVNAME);
160MODULE_ALIAS("platform:" DRVNAME);
161MODULE_ALIAS("spi:hx8353d");
162MODULE_ALIAS("platform:hx8353d");
163
164MODULE_DESCRIPTION("FB driver for the HX8353D LCD Controller");
165MODULE_AUTHOR("Petr Olivka");
166MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c
new file mode 100644
index 000000000000..b26d89368da7
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9320.c
@@ -0,0 +1,234 @@
1/*
2 * FB driver for the ILI9320 LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/gpio.h>
25#include <linux/spi/spi.h>
26#include <linux/delay.h>
27
28#include "fbtft.h"
29
30#define DRVNAME "fb_ili9320"
31#define WIDTH 240
32#define HEIGHT 320
33#define DEFAULT_GAMMA "07 07 6 0 0 0 5 5 4 0\n" \
34 "07 08 4 7 5 1 2 0 7 7"
35
36
37static unsigned read_devicecode(struct fbtft_par *par)
38{
39 int ret;
40 u8 rxbuf[8] = {0, };
41
42 write_reg(par, 0x0000);
43 ret = par->fbtftops.read(par, rxbuf, 4);
44 return (rxbuf[2] << 8) | rxbuf[3];
45}
46
47static int init_display(struct fbtft_par *par)
48{
49 unsigned devcode;
50 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
51
52 par->fbtftops.reset(par);
53
54 devcode = read_devicecode(par);
55 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "Device code: 0x%04X\n",
56 devcode);
57 if ((devcode != 0x0000) && (devcode != 0x9320))
58 dev_warn(par->info->device,
59 "Unrecognized Device code: 0x%04X (expected 0x9320)\n",
60 devcode);
61
62 /* Initialization sequence from ILI9320 Application Notes */
63
64 /* *********** Start Initial Sequence ********* */
65 write_reg(par, 0x00E5, 0x8000); /* Set the Vcore voltage and this setting is must. */
66 write_reg(par, 0x0000, 0x0001); /* Start internal OSC. */
67 write_reg(par, 0x0001, 0x0100); /* set SS and SM bit */
68 write_reg(par, 0x0002, 0x0700); /* set 1 line inversion */
69 write_reg(par, 0x0004, 0x0000); /* Resize register */
70 write_reg(par, 0x0008, 0x0202); /* set the back and front porch */
71 write_reg(par, 0x0009, 0x0000); /* set non-display area refresh cycle */
72 write_reg(par, 0x000A, 0x0000); /* FMARK function */
73 write_reg(par, 0x000C, 0x0000); /* RGB interface setting */
74 write_reg(par, 0x000D, 0x0000); /* Frame marker Position */
75 write_reg(par, 0x000F, 0x0000); /* RGB interface polarity */
76
77 /* ***********Power On sequence *************** */
78 write_reg(par, 0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
79 write_reg(par, 0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */
80 write_reg(par, 0x0012, 0x0000); /* VREG1OUT voltage */
81 write_reg(par, 0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
82 mdelay(200); /* Dis-charge capacitor power voltage */
83 write_reg(par, 0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
84 write_reg(par, 0x0011, 0x0031); /* R11h=0x0031 at VCI=3.3V DC1[2:0], DC0[2:0], VC[2:0] */
85 mdelay(50);
86 write_reg(par, 0x0012, 0x0138); /* R12h=0x0138 at VCI=3.3V VREG1OUT voltage */
87 mdelay(50);
88 write_reg(par, 0x0013, 0x1800); /* R13h=0x1800 at VCI=3.3V VDV[4:0] for VCOM amplitude */
89 write_reg(par, 0x0029, 0x0008); /* R29h=0x0008 at VCI=3.3V VCM[4:0] for VCOMH */
90 mdelay(50);
91 write_reg(par, 0x0020, 0x0000); /* GRAM horizontal Address */
92 write_reg(par, 0x0021, 0x0000); /* GRAM Vertical Address */
93
94 /* ------------------ Set GRAM area --------------- */
95 write_reg(par, 0x0050, 0x0000); /* Horizontal GRAM Start Address */
96 write_reg(par, 0x0051, 0x00EF); /* Horizontal GRAM End Address */
97 write_reg(par, 0x0052, 0x0000); /* Vertical GRAM Start Address */
98 write_reg(par, 0x0053, 0x013F); /* Vertical GRAM Start Address */
99 write_reg(par, 0x0060, 0x2700); /* Gate Scan Line */
100 write_reg(par, 0x0061, 0x0001); /* NDL,VLE, REV */
101 write_reg(par, 0x006A, 0x0000); /* set scrolling line */
102
103 /* -------------- Partial Display Control --------- */
104 write_reg(par, 0x0080, 0x0000);
105 write_reg(par, 0x0081, 0x0000);
106 write_reg(par, 0x0082, 0x0000);
107 write_reg(par, 0x0083, 0x0000);
108 write_reg(par, 0x0084, 0x0000);
109 write_reg(par, 0x0085, 0x0000);
110
111 /* -------------- Panel Control ------------------- */
112 write_reg(par, 0x0090, 0x0010);
113 write_reg(par, 0x0092, 0x0000);
114 write_reg(par, 0x0093, 0x0003);
115 write_reg(par, 0x0095, 0x0110);
116 write_reg(par, 0x0097, 0x0000);
117 write_reg(par, 0x0098, 0x0000);
118 write_reg(par, 0x0007, 0x0173); /* 262K color and display ON */
119
120 return 0;
121}
122
123static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
124{
125 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
126 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
127
128 switch (par->info->var.rotate) {
129 /* R20h = Horizontal GRAM Start Address */
130 /* R21h = Vertical GRAM Start Address */
131 case 0:
132 write_reg(par, 0x0020, xs);
133 write_reg(par, 0x0021, ys);
134 break;
135 case 180:
136 write_reg(par, 0x0020, WIDTH - 1 - xs);
137 write_reg(par, 0x0021, HEIGHT - 1 - ys);
138 break;
139 case 270:
140 write_reg(par, 0x0020, WIDTH - 1 - ys);
141 write_reg(par, 0x0021, xs);
142 break;
143 case 90:
144 write_reg(par, 0x0020, ys);
145 write_reg(par, 0x0021, HEIGHT - 1 - xs);
146 break;
147 }
148 write_reg(par, 0x0022); /* Write Data to GRAM */
149}
150
151static int set_var(struct fbtft_par *par)
152{
153 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
154
155 switch (par->info->var.rotate) {
156 case 0:
157 write_reg(par, 0x3, (par->bgr << 12) | 0x30);
158 break;
159 case 270:
160 write_reg(par, 0x3, (par->bgr << 12) | 0x28);
161 break;
162 case 180:
163 write_reg(par, 0x3, (par->bgr << 12) | 0x00);
164 break;
165 case 90:
166 write_reg(par, 0x3, (par->bgr << 12) | 0x18);
167 break;
168 }
169 return 0;
170}
171
172/*
173 Gamma string format:
174 VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
175 VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
176*/
177#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
178static int set_gamma(struct fbtft_par *par, unsigned long *curves)
179{
180 unsigned long mask[] = {
181 0b11111, 0b11111, 0b111, 0b111, 0b111,
182 0b111, 0b111, 0b111, 0b111, 0b111,
183 0b11111, 0b11111, 0b111, 0b111, 0b111,
184 0b111, 0b111, 0b111, 0b111, 0b111 };
185 int i, j;
186
187 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
188
189 /* apply mask */
190 for (i = 0; i < 2; i++)
191 for (j = 0; j < 10; j++)
192 CURVE(i, j) &= mask[i*par->gamma.num_values + j];
193
194 write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
195 write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
196 write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
197 write_reg(par, 0x0035, CURVE(0, 3) << 8 | CURVE(0, 2));
198 write_reg(par, 0x0036, CURVE(0, 1) << 8 | CURVE(0, 0));
199
200 write_reg(par, 0x0037, CURVE(1, 5) << 8 | CURVE(1, 4));
201 write_reg(par, 0x0038, CURVE(1, 7) << 8 | CURVE(1, 6));
202 write_reg(par, 0x0039, CURVE(1, 9) << 8 | CURVE(1, 8));
203 write_reg(par, 0x003C, CURVE(1, 3) << 8 | CURVE(1, 2));
204 write_reg(par, 0x003D, CURVE(1, 1) << 8 | CURVE(1, 0));
205
206 return 0;
207}
208#undef CURVE
209
210
211static struct fbtft_display display = {
212 .regwidth = 16,
213 .width = WIDTH,
214 .height = HEIGHT,
215 .gamma_num = 2,
216 .gamma_len = 10,
217 .gamma = DEFAULT_GAMMA,
218 .fbtftops = {
219 .init_display = init_display,
220 .set_addr_win = set_addr_win,
221 .set_var = set_var,
222 .set_gamma = set_gamma,
223 },
224};
225FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9320", &display);
226
227MODULE_ALIAS("spi:" DRVNAME);
228MODULE_ALIAS("platform:" DRVNAME);
229MODULE_ALIAS("spi:ili9320");
230MODULE_ALIAS("platform:ili9320");
231
232MODULE_DESCRIPTION("FB driver for the ILI9320 LCD Controller");
233MODULE_AUTHOR("Noralf Tronnes");
234MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c
new file mode 100644
index 000000000000..5f88145fac9b
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9325.c
@@ -0,0 +1,291 @@
1/*
2 * FB driver for the ILI9325 LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * Based on ili9325.c by Jeroen Domburg
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/gpio.h>
27#include <linux/delay.h>
28
29#include "fbtft.h"
30
31#define DRVNAME "fb_ili9325"
32#define WIDTH 240
33#define HEIGHT 320
34#define BPP 16
35#define FPS 20
36#define DEFAULT_GAMMA "0F 00 7 2 0 0 6 5 4 1\n" \
37 "04 16 2 7 6 3 2 1 7 7"
38
39
40static unsigned bt = 6; /* VGL=Vci*4 , VGH=Vci*4 */
41module_param(bt, uint, 0);
42MODULE_PARM_DESC(bt, "Sets the factor used in the step-up circuits");
43
44static unsigned vc = 0b011; /* Vci1=Vci*0.80 */
45module_param(vc, uint, 0);
46MODULE_PARM_DESC(vc,
47"Sets the ratio factor of Vci to generate the reference voltages Vci1");
48
49static unsigned vrh = 0b1101; /* VREG1OUT=Vci*1.85 */
50module_param(vrh, uint, 0);
51MODULE_PARM_DESC(vrh,
52"Set the amplifying rate (1.6 ~ 1.9) of Vci applied to output the VREG1OUT");
53
54static unsigned vdv = 0b10010; /* VCOMH amplitude=VREG1OUT*0.98 */
55module_param(vdv, uint, 0);
56MODULE_PARM_DESC(vdv,
57"Select the factor of VREG1OUT to set the amplitude of Vcom");
58
59static unsigned vcm = 0b001010; /* VCOMH=VREG1OUT*0.735 */
60module_param(vcm, uint, 0);
61MODULE_PARM_DESC(vcm, "Set the internal VcomH voltage");
62
63
64/*
65Verify that this configuration is within the Voltage limits
66
67Display module configuration: Vcc = IOVcc = Vci = 3.3V
68
69 Voltages
70----------
71Vci = 3.3
72Vci1 = Vci * 0.80 = 2.64
73DDVDH = Vci1 * 2 = 5.28
74VCL = -Vci1 = -2.64
75VREG1OUT = Vci * 1.85 = 4.88
76VCOMH = VREG1OUT * 0.735 = 3.59
77VCOM amplitude = VREG1OUT * 0.98 = 4.79
78VGH = Vci * 4 = 13.2
79VGL = -Vci * 4 = -13.2
80
81 Limits
82--------
83Power supplies
841.65 < IOVcc < 3.30 => 1.65 < 3.3 < 3.30
852.40 < Vcc < 3.30 => 2.40 < 3.3 < 3.30
862.50 < Vci < 3.30 => 2.50 < 3.3 < 3.30
87
88Source/VCOM power supply voltage
89 4.50 < DDVDH < 6.0 => 4.50 < 5.28 < 6.0
90-3.0 < VCL < -2.0 => -3.0 < -2.64 < -2.0
91VCI - VCL < 6.0 => 5.94 < 6.0
92
93Gate driver output voltage
94 10 < VGH < 20 => 10 < 13.2 < 20
95-15 < VGL < -5 => -15 < -13.2 < -5
96VGH - VGL < 32 => 26.4 < 32
97
98VCOM driver output voltage
99VCOMH - VCOML < 6.0 => 4.79 < 6.0
100*/
101
102static int init_display(struct fbtft_par *par)
103{
104 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
105
106 par->fbtftops.reset(par);
107
108 if (par->gpio.cs != -1)
109 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
110
111 bt &= 0b111;
112 vc &= 0b111;
113 vrh &= 0b1111;
114 vdv &= 0b11111;
115 vcm &= 0b111111;
116
117 /* Initialization sequence from ILI9325 Application Notes */
118
119 /* ----------- Start Initial Sequence ----------- */
120 write_reg(par, 0x00E3, 0x3008); /* Set internal timing */
121 write_reg(par, 0x00E7, 0x0012); /* Set internal timing */
122 write_reg(par, 0x00EF, 0x1231); /* Set internal timing */
123 write_reg(par, 0x0001, 0x0100); /* set SS and SM bit */
124 write_reg(par, 0x0002, 0x0700); /* set 1 line inversion */
125 write_reg(par, 0x0004, 0x0000); /* Resize register */
126 write_reg(par, 0x0008, 0x0207); /* set the back porch and front porch */
127 write_reg(par, 0x0009, 0x0000); /* set non-display area refresh cycle */
128 write_reg(par, 0x000A, 0x0000); /* FMARK function */
129 write_reg(par, 0x000C, 0x0000); /* RGB interface setting */
130 write_reg(par, 0x000D, 0x0000); /* Frame marker Position */
131 write_reg(par, 0x000F, 0x0000); /* RGB interface polarity */
132
133 /* ----------- Power On sequence ----------- */
134 write_reg(par, 0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
135 write_reg(par, 0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */
136 write_reg(par, 0x0012, 0x0000); /* VREG1OUT voltage */
137 write_reg(par, 0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
138 mdelay(200); /* Dis-charge capacitor power voltage */
139 write_reg(par, 0x0010, /* SAP, BT[3:0], AP, DSTB, SLP, STB */
140 (1 << 12) | (bt << 8) | (1 << 7) | (0b001 << 4));
141 write_reg(par, 0x0011, 0x220 | vc); /* DC1[2:0], DC0[2:0], VC[2:0] */
142 mdelay(50); /* Delay 50ms */
143 write_reg(par, 0x0012, vrh); /* Internal reference voltage= Vci; */
144 mdelay(50); /* Delay 50ms */
145 write_reg(par, 0x0013, vdv << 8); /* Set VDV[4:0] for VCOM amplitude */
146 write_reg(par, 0x0029, vcm); /* Set VCM[5:0] for VCOMH */
147 write_reg(par, 0x002B, 0x000C); /* Set Frame Rate */
148 mdelay(50); /* Delay 50ms */
149 write_reg(par, 0x0020, 0x0000); /* GRAM horizontal Address */
150 write_reg(par, 0x0021, 0x0000); /* GRAM Vertical Address */
151
152 /*------------------ Set GRAM area --------------- */
153 write_reg(par, 0x0050, 0x0000); /* Horizontal GRAM Start Address */
154 write_reg(par, 0x0051, 0x00EF); /* Horizontal GRAM End Address */
155 write_reg(par, 0x0052, 0x0000); /* Vertical GRAM Start Address */
156 write_reg(par, 0x0053, 0x013F); /* Vertical GRAM Start Address */
157 write_reg(par, 0x0060, 0xA700); /* Gate Scan Line */
158 write_reg(par, 0x0061, 0x0001); /* NDL,VLE, REV */
159 write_reg(par, 0x006A, 0x0000); /* set scrolling line */
160
161 /*-------------- Partial Display Control --------- */
162 write_reg(par, 0x0080, 0x0000);
163 write_reg(par, 0x0081, 0x0000);
164 write_reg(par, 0x0082, 0x0000);
165 write_reg(par, 0x0083, 0x0000);
166 write_reg(par, 0x0084, 0x0000);
167 write_reg(par, 0x0085, 0x0000);
168
169 /*-------------- Panel Control ------------------- */
170 write_reg(par, 0x0090, 0x0010);
171 write_reg(par, 0x0092, 0x0600);
172 write_reg(par, 0x0007, 0x0133); /* 262K color and display ON */
173
174 return 0;
175}
176
177static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
178{
179 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
180 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
181 switch (par->info->var.rotate) {
182 /* R20h = Horizontal GRAM Start Address */
183 /* R21h = Vertical GRAM Start Address */
184 case 0:
185 write_reg(par, 0x0020, xs);
186 write_reg(par, 0x0021, ys);
187 break;
188 case 180:
189 write_reg(par, 0x0020, WIDTH - 1 - xs);
190 write_reg(par, 0x0021, HEIGHT - 1 - ys);
191 break;
192 case 270:
193 write_reg(par, 0x0020, WIDTH - 1 - ys);
194 write_reg(par, 0x0021, xs);
195 break;
196 case 90:
197 write_reg(par, 0x0020, ys);
198 write_reg(par, 0x0021, HEIGHT - 1 - xs);
199 break;
200 }
201 write_reg(par, 0x0022); /* Write Data to GRAM */
202}
203
204static int set_var(struct fbtft_par *par)
205{
206 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
207
208 switch (par->info->var.rotate) {
209 /* AM: GRAM update direction */
210 case 0:
211 write_reg(par, 0x03, 0x0030 | (par->bgr << 12));
212 break;
213 case 180:
214 write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
215 break;
216 case 270:
217 write_reg(par, 0x03, 0x0028 | (par->bgr << 12));
218 break;
219 case 90:
220 write_reg(par, 0x03, 0x0018 | (par->bgr << 12));
221 break;
222 }
223
224 return 0;
225}
226
227/*
228 Gamma string format:
229 VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
230 VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
231*/
232#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
233static int set_gamma(struct fbtft_par *par, unsigned long *curves)
234{
235 unsigned long mask[] = {
236 0b11111, 0b11111, 0b111, 0b111, 0b111,
237 0b111, 0b111, 0b111, 0b111, 0b111,
238 0b11111, 0b11111, 0b111, 0b111, 0b111,
239 0b111, 0b111, 0b111, 0b111, 0b111 };
240 int i, j;
241
242 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
243
244 /* apply mask */
245 for (i = 0; i < 2; i++)
246 for (j = 0; j < 10; j++)
247 CURVE(i, j) &= mask[i*par->gamma.num_values + j];
248
249 write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
250 write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
251 write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
252 write_reg(par, 0x0035, CURVE(0, 3) << 8 | CURVE(0, 2));
253 write_reg(par, 0x0036, CURVE(0, 1) << 8 | CURVE(0, 0));
254
255 write_reg(par, 0x0037, CURVE(1, 5) << 8 | CURVE(1, 4));
256 write_reg(par, 0x0038, CURVE(1, 7) << 8 | CURVE(1, 6));
257 write_reg(par, 0x0039, CURVE(1, 9) << 8 | CURVE(1, 8));
258 write_reg(par, 0x003C, CURVE(1, 3) << 8 | CURVE(1, 2));
259 write_reg(par, 0x003D, CURVE(1, 1) << 8 | CURVE(1, 0));
260
261 return 0;
262}
263#undef CURVE
264
265
266static struct fbtft_display display = {
267 .regwidth = 16,
268 .width = WIDTH,
269 .height = HEIGHT,
270 .bpp = BPP,
271 .fps = FPS,
272 .gamma_num = 2,
273 .gamma_len = 10,
274 .gamma = DEFAULT_GAMMA,
275 .fbtftops = {
276 .init_display = init_display,
277 .set_addr_win = set_addr_win,
278 .set_var = set_var,
279 .set_gamma = set_gamma,
280 },
281};
282FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9325", &display);
283
284MODULE_ALIAS("spi:" DRVNAME);
285MODULE_ALIAS("platform:" DRVNAME);
286MODULE_ALIAS("spi:ili9325");
287MODULE_ALIAS("platform:ili9325");
288
289MODULE_DESCRIPTION("FB driver for the ILI9325 LCD Controller");
290MODULE_AUTHOR("Noralf Tronnes");
291MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c
new file mode 100644
index 000000000000..985687d94ec2
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9340.c
@@ -0,0 +1,163 @@
1/*
2 * FB driver for the ILI9340 LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26
27#include "fbtft.h"
28
29#define DRVNAME "fb_ili9340"
30#define WIDTH 240
31#define HEIGHT 320
32
33
34/* Init sequence taken from: Arduino Library for the Adafruit 2.2" display */
35static int init_display(struct fbtft_par *par)
36{
37 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
38
39 par->fbtftops.reset(par);
40
41 write_reg(par, 0xEF, 0x03, 0x80, 0x02);
42 write_reg(par, 0xCF, 0x00 , 0XC1 , 0X30);
43 write_reg(par, 0xED, 0x64 , 0x03 , 0X12 , 0X81);
44 write_reg(par, 0xE8, 0x85 , 0x00 , 0x78);
45 write_reg(par, 0xCB, 0x39 , 0x2C , 0x00 , 0x34 , 0x02);
46 write_reg(par, 0xF7, 0x20);
47 write_reg(par, 0xEA, 0x00 , 0x00);
48
49 /* Power Control 1 */
50 write_reg(par, 0xC0, 0x23);
51
52 /* Power Control 2 */
53 write_reg(par, 0xC1, 0x10);
54
55 /* VCOM Control 1 */
56 write_reg(par, 0xC5, 0x3e, 0x28);
57
58 /* VCOM Control 2 */
59 write_reg(par, 0xC7, 0x86);
60
61 /* COLMOD: Pixel Format Set */
62 /* 16 bits/pixel */
63 write_reg(par, 0x3A, 0x55);
64
65 /* Frame Rate Control */
66 /* Division ratio = fosc, Frame Rate = 79Hz */
67 write_reg(par, 0xB1, 0x00, 0x18);
68
69 /* Display Function Control */
70 write_reg(par, 0xB6, 0x08, 0x82, 0x27);
71
72 /* Gamma Function Disable */
73 write_reg(par, 0xF2, 0x00);
74
75 /* Gamma curve selected */
76 write_reg(par, 0x26, 0x01);
77
78 /* Positive Gamma Correction */
79 write_reg(par, 0xE0,
80 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1,
81 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00);
82
83 /* Negative Gamma Correction */
84 write_reg(par, 0xE1,
85 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1,
86 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F);
87
88 /* Sleep OUT */
89 write_reg(par, 0x11);
90
91 mdelay(120);
92
93 /* Display ON */
94 write_reg(par, 0x29);
95
96 return 0;
97}
98
99static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
100{
101 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
102 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
103
104 /* Column address */
105 write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
106
107 /* Row adress */
108 write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
109
110 /* Memory write */
111 write_reg(par, 0x2C);
112}
113
114#define ILI9340_MADCTL_MV 0x20
115#define ILI9340_MADCTL_MX 0x40
116#define ILI9340_MADCTL_MY 0x80
117static int set_var(struct fbtft_par *par)
118{
119 u8 val;
120
121 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
122
123 switch (par->info->var.rotate) {
124 case 270:
125 val = ILI9340_MADCTL_MV;
126 break;
127 case 180:
128 val = ILI9340_MADCTL_MY;
129 break;
130 case 90:
131 val = ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX;
132 break;
133 default:
134 val = ILI9340_MADCTL_MX;
135 break;
136 }
137 /* Memory Access Control */
138 write_reg(par, 0x36, val | (par->bgr << 3));
139
140 return 0;
141}
142
143
144static struct fbtft_display display = {
145 .regwidth = 8,
146 .width = WIDTH,
147 .height = HEIGHT,
148 .fbtftops = {
149 .init_display = init_display,
150 .set_addr_win = set_addr_win,
151 .set_var = set_var,
152 },
153};
154FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9340", &display);
155
156MODULE_ALIAS("spi:" DRVNAME);
157MODULE_ALIAS("platform:" DRVNAME);
158MODULE_ALIAS("spi:ili9340");
159MODULE_ALIAS("platform:ili9340");
160
161MODULE_DESCRIPTION("FB driver for the ILI9340 LCD Controller");
162MODULE_AUTHOR("Noralf Tronnes");
163MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c
new file mode 100644
index 000000000000..225b2d84371f
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9341.c
@@ -0,0 +1,179 @@
1/*
2 * FB driver for the ILI9341 LCD display controller
3 *
4 * This display uses 9-bit SPI: Data/Command bit + 8 data bits
5 * For platforms that doesn't support 9-bit, the driver is capable
6 * of emulating this using 8-bit transfer.
7 * This is done by transfering eight 9-bit words in 9 bytes.
8 *
9 * Copyright (C) 2013 Christian Vogelgsang
10 * Based on adafruit22fb.c by Noralf Tronnes
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31
32#include "fbtft.h"
33
34#define DRVNAME "fb_ili9341"
35#define WIDTH 240
36#define HEIGHT 320
37#define TXBUFLEN (4 * PAGE_SIZE)
38#define DEFAULT_GAMMA "1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
39 "00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
40
41
42static int init_display(struct fbtft_par *par)
43{
44 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
45
46 par->fbtftops.reset(par);
47
48 /* startup sequence for MI0283QT-9A */
49 write_reg(par, 0x01); /* software reset */
50 mdelay(5);
51 write_reg(par, 0x28); /* display off */
52 /* --------------------------------------------------------- */
53 write_reg(par, 0xCF, 0x00, 0x83, 0x30);
54 write_reg(par, 0xED, 0x64, 0x03, 0x12, 0x81);
55 write_reg(par, 0xE8, 0x85, 0x01, 0x79);
56 write_reg(par, 0xCB, 0x39, 0X2C, 0x00, 0x34, 0x02);
57 write_reg(par, 0xF7, 0x20);
58 write_reg(par, 0xEA, 0x00, 0x00);
59 /* ------------power control-------------------------------- */
60 write_reg(par, 0xC0, 0x26);
61 write_reg(par, 0xC1, 0x11);
62 /* ------------VCOM --------- */
63 write_reg(par, 0xC5, 0x35, 0x3E);
64 write_reg(par, 0xC7, 0xBE);
65 /* ------------memory access control------------------------ */
66 write_reg(par, 0x3A, 0x55); /* 16bit pixel */
67 /* ------------frame rate----------------------------------- */
68 write_reg(par, 0xB1, 0x00, 0x1B);
69 /* ------------Gamma---------------------------------------- */
70 /* write_reg(par, 0xF2, 0x08); */ /* Gamma Function Disable */
71 write_reg(par, 0x26, 0x01);
72 /* ------------display-------------------------------------- */
73 write_reg(par, 0xB7, 0x07); /* entry mode set */
74 write_reg(par, 0xB6, 0x0A, 0x82, 0x27, 0x00);
75 write_reg(par, 0x11); /* sleep out */
76 mdelay(100);
77 write_reg(par, 0x29); /* display on */
78 mdelay(20);
79
80 return 0;
81}
82
83static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
84{
85 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
86 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
87
88 /* Column address set */
89 write_reg(par, 0x2A,
90 (xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
91
92 /* Row adress set */
93 write_reg(par, 0x2B,
94 (ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
95
96 /* Memory write */
97 write_reg(par, 0x2C);
98}
99
100#define MEM_Y (7) /* MY row address order */
101#define MEM_X (6) /* MX column address order */
102#define MEM_V (5) /* MV row / column exchange */
103#define MEM_L (4) /* ML vertical refresh order */
104#define MEM_H (2) /* MH horizontal refresh order */
105#define MEM_BGR (3) /* RGB-BGR Order */
106static int set_var(struct fbtft_par *par)
107{
108 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
109
110 switch (par->info->var.rotate) {
111 case 0:
112 write_reg(par, 0x36, (1 << MEM_X) | (par->bgr << MEM_BGR));
113 break;
114 case 270:
115 write_reg(par, 0x36,
116 (1<<MEM_V) | (1 << MEM_L) | (par->bgr << MEM_BGR));
117 break;
118 case 180:
119 write_reg(par, 0x36, (1 << MEM_Y) | (par->bgr << MEM_BGR));
120 break;
121 case 90:
122 write_reg(par, 0x36, (1 << MEM_Y) | (1 << MEM_X) |
123 (1 << MEM_V) | (par->bgr << MEM_BGR));
124 break;
125 }
126
127 return 0;
128}
129
130/*
131 Gamma string format:
132 Positive: Par1 Par2 [...] Par15
133 Negative: Par1 Par2 [...] Par15
134*/
135#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
136static int set_gamma(struct fbtft_par *par, unsigned long *curves)
137{
138 int i;
139
140 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
141
142 for (i = 0; i < par->gamma.num_curves; i++)
143 write_reg(par, 0xE0 + i,
144 CURVE(i, 0), CURVE(i, 1), CURVE(i, 2),
145 CURVE(i, 3), CURVE(i, 4), CURVE(i, 5),
146 CURVE(i, 6), CURVE(i, 7), CURVE(i, 8),
147 CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
148 CURVE(i, 12), CURVE(i, 13), CURVE(i, 14));
149
150 return 0;
151}
152#undef CURVE
153
154
155static struct fbtft_display display = {
156 .regwidth = 8,
157 .width = WIDTH,
158 .height = HEIGHT,
159 .txbuflen = TXBUFLEN,
160 .gamma_num = 2,
161 .gamma_len = 15,
162 .gamma = DEFAULT_GAMMA,
163 .fbtftops = {
164 .init_display = init_display,
165 .set_addr_win = set_addr_win,
166 .set_var = set_var,
167 .set_gamma = set_gamma,
168 },
169};
170FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display);
171
172MODULE_ALIAS("spi:" DRVNAME);
173MODULE_ALIAS("platform:" DRVNAME);
174MODULE_ALIAS("spi:ili9341");
175MODULE_ALIAS("platform:ili9341");
176
177MODULE_DESCRIPTION("FB driver for the ILI9341 LCD display controller");
178MODULE_AUTHOR("Christian Vogelgsang");
179MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9481.c b/drivers/staging/fbtft/fb_ili9481.c
new file mode 100644
index 000000000000..725157a1ac41
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9481.c
@@ -0,0 +1,117 @@
1/*
2 * FB driver for the ILI9481 LCD Controller
3 *
4 * Copyright (c) 2014 Petr Olivka
5 * Copyright (c) 2013 Noralf Tronnes
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26
27#include "fbtft.h"
28
29#define DRVNAME "fb_ili9481"
30#define WIDTH 320
31#define HEIGHT 480
32
33static int default_init_sequence[] = {
34
35 /* SLP_OUT - Sleep out */
36 -1, 0x11,
37 -2, 50,
38 /* Power setting */
39 -1, 0xD0, 0x07, 0x42, 0x18,
40 /* VCOM */
41 -1, 0xD1, 0x00, 0x07, 0x10,
42 /* Power setting for norm. mode */
43 -1, 0xD2, 0x01, 0x02,
44 /* Panel driving setting */
45 -1, 0xC0, 0x10, 0x3B, 0x00, 0x02, 0x11,
46 /* Frame rate & inv. */
47 -1, 0xC5, 0x03,
48 /* Pixel format */
49 -1, 0x3A, 0x55,
50 /* Gamma */
51 -1, 0xC8, 0x00, 0x32, 0x36, 0x45, 0x06, 0x16,
52 0x37, 0x75, 0x77, 0x54, 0x0C, 0x00,
53 /* DISP_ON */
54 -1, 0x29,
55 -3
56};
57
58static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
59{
60 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
61 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
62
63 /* column address */
64 write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff);
65
66 /* row adress */
67 write_reg(par, 0x2b, ys >> 8, ys & 0xff, ye >> 8, ye & 0xff);
68
69 /* memory write */
70 write_reg(par, 0x2c);
71}
72
73#define HFLIP 0x01
74#define VFLIP 0x02
75#define ROWxCOL 0x20
76static int set_var(struct fbtft_par *par)
77{
78 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
79
80 switch (par->info->var.rotate) {
81 case 270:
82 write_reg(par, 0x36, ROWxCOL | HFLIP | VFLIP | (par->bgr << 3));
83 break;
84 case 180:
85 write_reg(par, 0x36, VFLIP | (par->bgr << 3));
86 break;
87 case 90:
88 write_reg(par, 0x36, ROWxCOL | (par->bgr << 3));
89 break;
90 default:
91 write_reg(par, 0x36, HFLIP | (par->bgr << 3));
92 break;
93 }
94
95 return 0;
96}
97
98static struct fbtft_display display = {
99 .regwidth = 8,
100 .width = WIDTH,
101 .height = HEIGHT,
102 .init_sequence = default_init_sequence,
103 .fbtftops = {
104 .set_addr_win = set_addr_win,
105 .set_var = set_var,
106 },
107};
108FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9481", &display);
109
110MODULE_ALIAS("spi:" DRVNAME);
111MODULE_ALIAS("platform:" DRVNAME);
112MODULE_ALIAS("spi:ili9481");
113MODULE_ALIAS("platform:ili9481");
114
115MODULE_DESCRIPTION("FB driver for the ILI9481 LCD Controller");
116MODULE_AUTHOR("Petr Olivka");
117MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9486.c b/drivers/staging/fbtft/fb_ili9486.c
new file mode 100644
index 000000000000..95b89999d32a
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9486.c
@@ -0,0 +1,121 @@
1/*
2 * FB driver for the ILI9486 LCD Controller
3 *
4 * Copyright (C) 2014 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24
25#include "fbtft.h"
26
27#define DRVNAME "fb_ili9486"
28#define WIDTH 320
29#define HEIGHT 480
30
31
32/* this init sequence matches PiScreen */
33static int default_init_sequence[] = {
34 /* Interface Mode Control */
35 -1, 0xb0, 0x0,
36 /* Sleep OUT */
37 -1, 0x11,
38 -2, 250,
39 /* Interface Pixel Format */
40 -1, 0x3A, 0x55,
41 /* Power Control 3 */
42 -1, 0xC2, 0x44,
43 /* VCOM Control 1 */
44 -1, 0xC5, 0x00, 0x00, 0x00, 0x00,
45 /* PGAMCTRL(Positive Gamma Control) */
46 -1, 0xE0, 0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98,
47 0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00,
48 /* NGAMCTRL(Negative Gamma Control) */
49 -1, 0xE1, 0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75,
50 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00,
51 /* Digital Gamma Control 1 */
52 -1, 0xE2, 0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75,
53 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00,
54 /* Sleep OUT */
55 -1, 0x11,
56 /* Display ON */
57 -1, 0x29,
58 /* end marker */
59 -3
60};
61
62static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
63{
64 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
65 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
66
67 /* Column address */
68 write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
69
70 /* Row adress */
71 write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
72
73 /* Memory write */
74 write_reg(par, 0x2C);
75}
76
77static int set_var(struct fbtft_par *par)
78{
79 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
80
81 switch (par->info->var.rotate) {
82 case 0:
83 write_reg(par, 0x36, 0x80 | (par->bgr << 3));
84 break;
85 case 90:
86 write_reg(par, 0x36, 0x20 | (par->bgr << 3));
87 break;
88 case 180:
89 write_reg(par, 0x36, 0x40 | (par->bgr << 3));
90 break;
91 case 270:
92 write_reg(par, 0x36, 0xE0 | (par->bgr << 3));
93 break;
94 default:
95 break;
96 }
97
98 return 0;
99}
100
101
102static struct fbtft_display display = {
103 .regwidth = 8,
104 .width = WIDTH,
105 .height = HEIGHT,
106 .init_sequence = default_init_sequence,
107 .fbtftops = {
108 .set_addr_win = set_addr_win,
109 .set_var = set_var,
110 },
111};
112FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9486", &display);
113
114MODULE_ALIAS("spi:" DRVNAME);
115MODULE_ALIAS("platform:" DRVNAME);
116MODULE_ALIAS("spi:ili9486");
117MODULE_ALIAS("platform:ili9486");
118
119MODULE_DESCRIPTION("FB driver for the ILI9486 LCD Controller");
120MODULE_AUTHOR("Noralf Tronnes");
121MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c
new file mode 100644
index 000000000000..8b9ebfb49ef8
--- /dev/null
+++ b/drivers/staging/fbtft/fb_pcd8544.c
@@ -0,0 +1,177 @@
1/*
2 * FB driver for the PCD8544 LCD Controller
3 *
4 * The display is monochrome and the video memory is RGB565.
5 * Any pixel value except 0 turns the pixel on.
6 *
7 * Copyright (C) 2013 Noralf Tronnes
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/gpio.h>
28#include <linux/spi/spi.h>
29#include <linux/delay.h>
30
31#include "fbtft.h"
32
33#define DRVNAME "fb_pcd8544"
34#define WIDTH 84
35#define HEIGHT 48
36#define TXBUFLEN (84*6)
37#define DEFAULT_GAMMA "40" /* gamma is used to control contrast in this driver */
38
39static unsigned tc;
40module_param(tc, uint, 0);
41MODULE_PARM_DESC(tc, "TC[1:0] Temperature coefficient: 0-3 (default: 0)");
42
43static unsigned bs = 4;
44module_param(bs, uint, 0);
45MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
46
47
48static int init_display(struct fbtft_par *par)
49{
50 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
51
52 par->fbtftops.reset(par);
53
54 /* Function set */
55 write_reg(par, 0x21); /* 5:1 1
56 2:0 PD - Powerdown control: chip is active
57 1:0 V - Entry mode: horizontal addressing
58 0:1 H - Extended instruction set control: extended
59 */
60
61 /* H=1 Temperature control */
62 write_reg(par, 0x04 | (tc & 0x3)); /*
63 2:1 1
64 1:x TC1 - Temperature Coefficient: 0x10
65 0:x TC0
66 */
67
68 /* H=1 Bias system */
69 write_reg(par, 0x10 | (bs & 0x7)); /*
70 4:1 1
71 3:0 0
72 2:x BS2 - Bias System
73 1:x BS1
74 0:x BS0
75 */
76
77 /* Function set */
78 write_reg(par, 0x22); /* 5:1 1
79 2:0 PD - Powerdown control: chip is active
80 1:1 V - Entry mode: vertical addressing
81 0:0 H - Extended instruction set control: basic
82 */
83
84 /* H=0 Display control */
85 write_reg(par, 0x08 | 4); /*
86 3:1 1
87 2:1 D - DE: 10=normal mode
88 1:0 0
89 0:0 E
90 */
91
92 return 0;
93}
94
95static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
96{
97 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
98
99 /* H=0 Set X address of RAM */
100 write_reg(par, 0x80); /* 7:1 1
101 6-0: X[6:0] - 0x00
102 */
103
104 /* H=0 Set Y address of RAM */
105 write_reg(par, 0x40); /* 7:0 0
106 6:1 1
107 2-0: Y[2:0] - 0x0
108 */
109}
110
111static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
112{
113 u16 *vmem16 = (u16 *)par->info->screen_base;
114 u8 *buf = par->txbuf.buf;
115 int x, y, i;
116 int ret = 0;
117
118 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
119
120 for (x = 0; x < 84; x++) {
121 for (y = 0; y < 6; y++) {
122 *buf = 0x00;
123 for (i = 0; i < 8; i++) {
124 *buf |= (vmem16[(y*8+i)*84+x] ? 1 : 0) << i;
125 }
126 buf++;
127 }
128 }
129
130 /* Write data */
131 gpio_set_value(par->gpio.dc, 1);
132 ret = par->fbtftops.write(par, par->txbuf.buf, 6*84);
133 if (ret < 0)
134 dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret);
135
136 return ret;
137}
138
139static int set_gamma(struct fbtft_par *par, unsigned long *curves)
140{
141 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
142
143 /* apply mask */
144 curves[0] &= 0x7F;
145
146 write_reg(par, 0x23); /* turn on extended instruction set */
147 write_reg(par, 0x80 | curves[0]);
148 write_reg(par, 0x22); /* turn off extended instruction set */
149
150 return 0;
151}
152
153
154static struct fbtft_display display = {
155 .regwidth = 8,
156 .width = WIDTH,
157 .height = HEIGHT,
158 .txbuflen = TXBUFLEN,
159 .gamma_num = 1,
160 .gamma_len = 1,
161 .gamma = DEFAULT_GAMMA,
162 .fbtftops = {
163 .init_display = init_display,
164 .set_addr_win = set_addr_win,
165 .write_vmem = write_vmem,
166 .set_gamma = set_gamma,
167 },
168 .backlight = 1,
169};
170FBTFT_REGISTER_DRIVER(DRVNAME, "philips,pdc8544", &display);
171
172MODULE_ALIAS("spi:" DRVNAME);
173MODULE_ALIAS("spi:pdc8544");
174
175MODULE_DESCRIPTION("FB driver for the PCD8544 LCD Controller");
176MODULE_AUTHOR("Noralf Tronnes");
177MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c
new file mode 100644
index 000000000000..c323c06344fd
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ra8875.c
@@ -0,0 +1,331 @@
1/******************************************************************************
2
3 ProjectName: FBTFT driver ***** *****
4 for the RA8875 LCD Controller * * ************
5 * ** ** * *
6 Copyright © by Pf@nne & NOTRO * * * * * **** *
7 * * * * * * *
8 Last modification by: * * * * **** *
9 - Pf@nne (pf@nne-mail.de) * * ***** *
10 * * * *******
11 ***** * *
12 Date : 10.06.2014 * *
13 Version : V1.13 *****
14 Revison : 5
15
16*******************************************************************************
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/init.h>
35#include <linux/delay.h>
36
37#include <linux/gpio.h>
38#include "fbtft.h"
39
40#define DRVNAME "fb_ra8875"
41
42static int write_spi(struct fbtft_par *par, void *buf, size_t len)
43{
44 struct spi_transfer t = {
45 .tx_buf = buf,
46 .len = len,
47 .speed_hz = 1000000,
48 };
49 struct spi_message m;
50
51 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
52 "%s(len=%d): ", __func__, len);
53
54 if (!par->spi) {
55 dev_err(par->info->device,
56 "%s: par->spi is unexpectedly NULL\n", __func__);
57 return -1;
58 }
59
60 spi_message_init(&m);
61 if (par->txbuf.dma && buf == par->txbuf.buf) {
62 t.tx_dma = par->txbuf.dma;
63 m.is_dma_mapped = 1;
64 }
65 spi_message_add_tail(&t, &m);
66 return spi_sync(par->spi, &m);
67}
68
69static int init_display(struct fbtft_par *par)
70{
71 gpio_set_value(par->gpio.dc, 1);
72
73 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
74 "%s()\n", __func__);
75 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
76 "display size %dx%d\n", par->info->var.xres, par->info->var.yres);
77
78 par->fbtftops.reset(par);
79
80 if ((par->info->var.xres == 320) && (par->info->var.yres == 240)) {
81 /* PLL clock frequency */
82 write_reg(par, 0x88 , 0x0A);
83 write_reg(par, 0x89 , 0x02);
84 mdelay(10);
85 /* color deep / MCU Interface */
86 write_reg(par, 0x10 , 0x0C);
87 /* pixel clock period */
88 write_reg(par, 0x04 , 0x03);
89 mdelay(1);
90 /* horizontal settings */
91 write_reg(par, 0x14 , 0x27);
92 write_reg(par, 0x15 , 0x00);
93 write_reg(par, 0x16 , 0x05);
94 write_reg(par, 0x17 , 0x04);
95 write_reg(par, 0x18 , 0x03);
96 /* vertical settings */
97 write_reg(par, 0x19 , 0xEF);
98 write_reg(par, 0x1A , 0x00);
99 write_reg(par, 0x1B , 0x05);
100 write_reg(par, 0x1C , 0x00);
101 write_reg(par, 0x1D , 0x0E);
102 write_reg(par, 0x1E , 0x00);
103 write_reg(par, 0x1F , 0x02);
104 } else if ((par->info->var.xres == 480) && (par->info->var.yres == 272)) {
105 /* PLL clock frequency */
106 write_reg(par, 0x88 , 0x0A);
107 write_reg(par, 0x89 , 0x02);
108 mdelay(10);
109 /* color deep / MCU Interface */
110 write_reg(par, 0x10 , 0x0C);
111 /* pixel clock period */
112 write_reg(par, 0x04 , 0x82);
113 mdelay(1);
114 /* horizontal settings */
115 write_reg(par, 0x14 , 0x3B);
116 write_reg(par, 0x15 , 0x00);
117 write_reg(par, 0x16 , 0x01);
118 write_reg(par, 0x17 , 0x00);
119 write_reg(par, 0x18 , 0x05);
120 /* vertical settings */
121 write_reg(par, 0x19 , 0x0F);
122 write_reg(par, 0x1A , 0x01);
123 write_reg(par, 0x1B , 0x02);
124 write_reg(par, 0x1C , 0x00);
125 write_reg(par, 0x1D , 0x07);
126 write_reg(par, 0x1E , 0x00);
127 write_reg(par, 0x1F , 0x09);
128 } else if ((par->info->var.xres == 640) && (par->info->var.yres == 480)) {
129 /* PLL clock frequency */
130 write_reg(par, 0x88 , 0x0B);
131 write_reg(par, 0x89 , 0x02);
132 mdelay(10);
133 /* color deep / MCU Interface */
134 write_reg(par, 0x10 , 0x0C);
135 /* pixel clock period */
136 write_reg(par, 0x04 , 0x01);
137 mdelay(1);
138 /* horizontal settings */
139 write_reg(par, 0x14 , 0x4F);
140 write_reg(par, 0x15 , 0x05);
141 write_reg(par, 0x16 , 0x0F);
142 write_reg(par, 0x17 , 0x01);
143 write_reg(par, 0x18 , 0x00);
144 /* vertical settings */
145 write_reg(par, 0x19 , 0xDF);
146 write_reg(par, 0x1A , 0x01);
147 write_reg(par, 0x1B , 0x0A);
148 write_reg(par, 0x1C , 0x00);
149 write_reg(par, 0x1D , 0x0E);
150 write_reg(par, 0x1E , 0x00);
151 write_reg(par, 0x1F , 0x01);
152 } else if ((par->info->var.xres == 800) && (par->info->var.yres == 480)) {
153 /* PLL clock frequency */
154 write_reg(par, 0x88 , 0x0B);
155 write_reg(par, 0x89 , 0x02);
156 mdelay(10);
157 /* color deep / MCU Interface */
158 write_reg(par, 0x10 , 0x0C);
159 /* pixel clock period */
160 write_reg(par, 0x04 , 0x81);
161 mdelay(1);
162 /* horizontal settings */
163 write_reg(par, 0x14 , 0x63);
164 write_reg(par, 0x15 , 0x03);
165 write_reg(par, 0x16 , 0x03);
166 write_reg(par, 0x17 , 0x02);
167 write_reg(par, 0x18 , 0x00);
168 /* vertical settings */
169 write_reg(par, 0x19 , 0xDF);
170 write_reg(par, 0x1A , 0x01);
171 write_reg(par, 0x1B , 0x14);
172 write_reg(par, 0x1C , 0x00);
173 write_reg(par, 0x1D , 0x06);
174 write_reg(par, 0x1E , 0x00);
175 write_reg(par, 0x1F , 0x01);
176 } else {
177 dev_err(par->info->device, "display size is not supported!!");
178 return -1;
179 }
180
181 /* PWM clock */
182 write_reg(par, 0x8a , 0x81);
183 write_reg(par, 0x8b , 0xFF);
184 mdelay(10);
185
186 /* Display ON */
187 write_reg(par, 0x01 , 0x80);
188 mdelay(10);
189
190 return 0;
191}
192
193static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
194{
195 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
196 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
197
198 /* Set_Active_Window */
199 write_reg(par, 0x30 , xs & 0x00FF);
200 write_reg(par, 0x31 , (xs & 0xFF00) >> 8);
201 write_reg(par, 0x32 , ys & 0x00FF);
202 write_reg(par, 0x33 , (ys & 0xFF00) >> 8);
203 write_reg(par, 0x34 , (xs+xe) & 0x00FF);
204 write_reg(par, 0x35 , ((xs+xe) & 0xFF00) >> 8);
205 write_reg(par, 0x36 , (ys+ye) & 0x00FF);
206 write_reg(par, 0x37 , ((ys+ye) & 0xFF00) >> 8);
207
208 /* Set_Memory_Write_Cursor */
209 write_reg(par, 0x46, xs & 0xff);
210 write_reg(par, 0x47, (xs >> 8) & 0x03);
211 write_reg(par, 0x48, ys & 0xff);
212 write_reg(par, 0x49, (ys >> 8) & 0x01);
213
214 write_reg(par, 0x02);
215}
216
217static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
218{
219 va_list args;
220 int i, ret;
221 u8 *buf = (u8 *)par->buf;
222
223 /* slow down spi-speed for writing registers */
224 par->fbtftops.write = write_spi;
225
226 if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
227 va_start(args, len);
228 for (i = 0; i < len; i++)
229 buf[i] = (u8)va_arg(args, unsigned int);
230 va_end(args);
231 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device,
232 u8, buf, len, "%s: ", __func__);
233 }
234
235 va_start(args, len);
236 *buf++ = 0x80;
237 *buf = (u8)va_arg(args, unsigned int);
238 ret = par->fbtftops.write(par, par->buf, 2);
239 if (ret < 0) {
240 va_end(args);
241 dev_err(par->info->device, "%s: write() failed and returned %dn",
242 __func__, ret);
243 return;
244 }
245 len--;
246
247 udelay(100);
248
249 if (len) {
250 buf = (u8 *)par->buf;
251 *buf++ = 0x00;
252 i = len;
253 while (i--)
254 *buf++ = (u8)va_arg(args, unsigned int);
255
256 ret = par->fbtftops.write(par, par->buf, len + 1);
257 if (ret < 0) {
258 va_end(args);
259 dev_err(par->info->device, "%s: write() failed and returned %dn",
260 __func__, ret);
261 return;
262 }
263 }
264 va_end(args);
265
266 /* restore user spi-speed */
267 par->fbtftops.write = fbtft_write_spi;
268 udelay(100);
269}
270
271static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
272{
273 u16 *vmem16;
274 u16 *txbuf16 = (u16 *)par->txbuf.buf;
275 size_t remain;
276 size_t to_copy;
277 size_t tx_array_size;
278 int i;
279 int ret = 0;
280 size_t startbyte_size = 0;
281
282 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
283 __func__, offset, len);
284
285 remain = len / 2;
286 vmem16 = (u16 *)(par->info->screen_base + offset);
287 tx_array_size = par->txbuf.len / 2;
288 txbuf16 = (u16 *)(par->txbuf.buf + 1);
289 tx_array_size -= 2;
290 *(u8 *)(par->txbuf.buf) = 0x00;
291 startbyte_size = 1;
292
293 while (remain) {
294 to_copy = remain > tx_array_size ? tx_array_size : remain;
295 dev_dbg(par->info->device, " to_copy=%zu, remain=%zu\n",
296 to_copy, remain - to_copy);
297
298 for (i = 0; i < to_copy; i++)
299 txbuf16[i] = cpu_to_be16(vmem16[i]);
300
301 vmem16 = vmem16 + to_copy;
302 ret = par->fbtftops.write(par, par->txbuf.buf,
303 startbyte_size + to_copy * 2);
304 if (ret < 0)
305 return ret;
306 remain -= to_copy;
307 }
308
309 return ret;
310}
311
312static struct fbtft_display display = {
313 .regwidth = 8,
314 .fbtftops = {
315 .init_display = init_display,
316 .set_addr_win = set_addr_win,
317 .write_register = write_reg8_bus8,
318 .write_vmem = write_vmem16_bus8,
319 .write = write_spi,
320 },
321};
322FBTFT_REGISTER_DRIVER(DRVNAME, "raio,ra8875", &display);
323
324MODULE_ALIAS("spi:" DRVNAME);
325MODULE_ALIAS("platform:" DRVNAME);
326MODULE_ALIAS("spi:ra8875");
327MODULE_ALIAS("platform:ra8875");
328
329MODULE_DESCRIPTION("FB driver for the RA8875 LCD Controller");
330MODULE_AUTHOR("Pf@nne");
331MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_s6d02a1.c b/drivers/staging/fbtft/fb_s6d02a1.c
new file mode 100644
index 000000000000..e412a42443e5
--- /dev/null
+++ b/drivers/staging/fbtft/fb_s6d02a1.c
@@ -0,0 +1,168 @@
1/*
2 * FB driver for the S6D02A1 LCD Controller
3 *
4 * Based on fb_st7735r.c by Noralf Tronnes
5 * Init code from UTFT library by Henning Karlsen
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25
26#include "fbtft.h"
27
28#define DRVNAME "fb_s6d02a1"
29
30static int default_init_sequence[] = {
31
32 -1, 0xf0, 0x5a, 0x5a,
33
34 -1, 0xfc, 0x5a, 0x5a,
35
36 -1, 0xfa, 0x02, 0x1f, 0x00, 0x10, 0x22, 0x30, 0x38, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3d, 0x02, 0x01,
37
38 -1, 0xfb, 0x21, 0x00, 0x02, 0x04, 0x07, 0x0a, 0x0b, 0x0c, 0x0c, 0x16, 0x1e, 0x30, 0x3f, 0x01, 0x02,
39
40 /* power setting sequence */
41 -1, 0xfd, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x01, 0x01, 0x00, 0x1f, 0x1f,
42
43 -1, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,
44
45 -1, 0xf5, 0x00, 0x70, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x66, 0x06,
46
47 -1, 0xf6, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x01, 0x00,
48
49 -1, 0xf2, 0x00, 0x01, 0x03, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x08, 0x08,
50
51 -1, 0xf8, 0x11,
52
53 -1, 0xf7, 0xc8, 0x20, 0x00, 0x00,
54
55 -1, 0xf3, 0x00, 0x00,
56
57 -1, 0x11,
58 -2, 50,
59
60 -1, 0xf3, 0x00, 0x01,
61 -2, 50,
62 -1, 0xf3, 0x00, 0x03,
63 -2, 50,
64 -1, 0xf3, 0x00, 0x07,
65 -2, 50,
66 -1, 0xf3, 0x00, 0x0f,
67 -2, 50,
68
69 -1, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,
70 -2, 50,
71
72 -1, 0xf3, 0x00, 0x1f,
73 -2, 50,
74 -1, 0xf3, 0x00, 0x7f,
75 -2, 50,
76
77 -1, 0xf3, 0x00, 0xff,
78 -2, 50,
79
80 -1, 0xfd, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x01, 0x00, 0x16, 0x16,
81
82 -1, 0xf4, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,
83
84 /* initializing sequence */
85
86 -1, 0x36, 0x08,
87
88 -1, 0x35, 0x00,
89
90 -1, 0x3a, 0x05,
91
92 /* gamma setting sequence */
93 -1, 0x26, 0x01, /* preset gamma curves, possible values 0x01, 0x02, 0x04, 0x08 */
94
95 -2, 150,
96 -1, 0x29,
97 -1, 0x2c,
98 /* end marker */
99 -3
100
101};
102
103static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
104{
105 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
106 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
107
108 /* Column address */
109 write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
110
111 /* Row adress */
112 write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
113
114 /* Memory write */
115 write_reg(par, 0x2C);
116}
117
118#define MY (1 << 7)
119#define MX (1 << 6)
120#define MV (1 << 5)
121static int set_var(struct fbtft_par *par)
122{
123 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
124
125 /* MADCTL - Memory data access control
126 RGB/BGR:
127 1. Mode selection pin SRGB
128 RGB H/W pin for color filter setting: 0=RGB, 1=BGR
129 2. MADCTL RGB bit
130 RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR */
131 switch (par->info->var.rotate) {
132 case 0:
133 write_reg(par, 0x36, MX | MY | (par->bgr << 3));
134 break;
135 case 270:
136 write_reg(par, 0x36, MY | MV | (par->bgr << 3));
137 break;
138 case 180:
139 write_reg(par, 0x36, (par->bgr << 3));
140 break;
141 case 90:
142 write_reg(par, 0x36, MX | MV | (par->bgr << 3));
143 break;
144 }
145
146 return 0;
147}
148
149static struct fbtft_display display = {
150 .regwidth = 8,
151 .width = 128,
152 .height = 160,
153 .init_sequence = default_init_sequence,
154 .fbtftops = {
155 .set_addr_win = set_addr_win,
156 .set_var = set_var,
157 },
158};
159FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d02a1", &display);
160
161MODULE_ALIAS("spi:" DRVNAME);
162MODULE_ALIAS("platform:" DRVNAME);
163MODULE_ALIAS("spi:s6d02a1");
164MODULE_ALIAS("platform:s6d02a1");
165
166MODULE_DESCRIPTION("FB driver for the S6D02A1 LCD Controller");
167MODULE_AUTHOR("WOLFGANG BUENING");
168MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c
new file mode 100644
index 000000000000..1ef8c1ad827e
--- /dev/null
+++ b/drivers/staging/fbtft/fb_s6d1121.c
@@ -0,0 +1,208 @@
1/*
2 * FB driver for the S6D1121 LCD Controller
3 *
4 * Copyright (C) 2013 Roman Rolinsky
5 *
6 * Based on fb_ili9325.c by Noralf Tronnes
7 * Based on ili9325.c by Jeroen Domburg
8 * Init code from UTFT library by Henning Karlsen
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/gpio.h>
29#include <linux/delay.h>
30
31#include "fbtft.h"
32
33#define DRVNAME "fb_s6d1121"
34#define WIDTH 240
35#define HEIGHT 320
36#define BPP 16
37#define FPS 20
38#define DEFAULT_GAMMA "26 09 24 2C 1F 23 24 25 22 26 25 23 0D 00\n" \
39 "1C 1A 13 1D 0B 11 12 10 13 15 36 19 00 0D"
40
41static int init_display(struct fbtft_par *par)
42{
43 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
44
45 par->fbtftops.reset(par);
46
47 if (par->gpio.cs != -1)
48 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
49
50 /* Initialization sequence from Lib_UTFT */
51
52 write_reg(par, 0x0011, 0x2004);
53 write_reg(par, 0x0013, 0xCC00);
54 write_reg(par, 0x0015, 0x2600);
55 write_reg(par, 0x0014, 0x252A);
56 write_reg(par, 0x0012, 0x0033);
57 write_reg(par, 0x0013, 0xCC04);
58 write_reg(par, 0x0013, 0xCC06);
59 write_reg(par, 0x0013, 0xCC4F);
60 write_reg(par, 0x0013, 0x674F);
61 write_reg(par, 0x0011, 0x2003);
62 write_reg(par, 0x0016, 0x0007);
63 write_reg(par, 0x0002, 0x0013);
64 write_reg(par, 0x0003, 0x0003);
65 write_reg(par, 0x0001, 0x0127);
66 write_reg(par, 0x0008, 0x0303);
67 write_reg(par, 0x000A, 0x000B);
68 write_reg(par, 0x000B, 0x0003);
69 write_reg(par, 0x000C, 0x0000);
70 write_reg(par, 0x0041, 0x0000);
71 write_reg(par, 0x0050, 0x0000);
72 write_reg(par, 0x0060, 0x0005);
73 write_reg(par, 0x0070, 0x000B);
74 write_reg(par, 0x0071, 0x0000);
75 write_reg(par, 0x0078, 0x0000);
76 write_reg(par, 0x007A, 0x0000);
77 write_reg(par, 0x0079, 0x0007);
78 write_reg(par, 0x0007, 0x0051);
79 write_reg(par, 0x0007, 0x0053);
80 write_reg(par, 0x0079, 0x0000);
81
82 write_reg(par, 0x0022); /* Write Data to GRAM */
83
84 return 0;
85}
86
87static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
88{
89 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
90 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
91 switch (par->info->var.rotate) {
92 /* R20h = Horizontal GRAM Start Address */
93 /* R21h = Vertical GRAM Start Address */
94 case 0:
95 write_reg(par, 0x0020, xs);
96 write_reg(par, 0x0021, ys);
97 break;
98 case 180:
99 write_reg(par, 0x0020, WIDTH - 1 - xs);
100 write_reg(par, 0x0021, HEIGHT - 1 - ys);
101 break;
102 case 270:
103 write_reg(par, 0x0020, WIDTH - 1 - ys);
104 write_reg(par, 0x0021, xs);
105 break;
106 case 90:
107 write_reg(par, 0x0020, ys);
108 write_reg(par, 0x0021, HEIGHT - 1 - xs);
109 break;
110 }
111 write_reg(par, 0x0022); /* Write Data to GRAM */
112}
113
114static int set_var(struct fbtft_par *par)
115{
116 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
117
118 switch (par->info->var.rotate) {
119 /* AM: GRAM update direction */
120 case 0:
121 write_reg(par, 0x03, 0x0003 | (par->bgr << 12));
122 break;
123 case 180:
124 write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
125 break;
126 case 270:
127 write_reg(par, 0x03, 0x000A | (par->bgr << 12));
128 break;
129 case 90:
130 write_reg(par, 0x03, 0x0009 | (par->bgr << 12));
131 break;
132 }
133
134 return 0;
135}
136
137/*
138 Gamma string format:
139 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5 PKP6 PKP7 PKP8 PKP9 PKP10 PKP11 VRP0 VRP1
140 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1
141*/
142#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
143static int set_gamma(struct fbtft_par *par, unsigned long *curves)
144{
145 unsigned long mask[] = {
146 0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
147 0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
148 0b11111, 0b11111,
149 0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
150 0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
151 0b11111, 0b11111 };
152 int i, j;
153
154 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
155
156 /* apply mask */
157 for (i = 0; i < 2; i++)
158 for (j = 0; j < 14; j++)
159 CURVE(i, j) &= mask[i*par->gamma.num_values + j];
160
161 write_reg(par, 0x0030, CURVE(0, 1) << 8 | CURVE(0, 0));
162 write_reg(par, 0x0031, CURVE(0, 3) << 8 | CURVE(0, 2));
163 write_reg(par, 0x0032, CURVE(0, 5) << 8 | CURVE(0, 3));
164 write_reg(par, 0x0033, CURVE(0, 7) << 8 | CURVE(0, 6));
165 write_reg(par, 0x0034, CURVE(0, 9) << 8 | CURVE(0, 8));
166 write_reg(par, 0x0035, CURVE(0, 11) << 8 | CURVE(0, 10));
167
168 write_reg(par, 0x0036, CURVE(1, 1) << 8 | CURVE(1, 0));
169 write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
170 write_reg(par, 0x0038, CURVE(1, 5) << 8 | CURVE(1, 4));
171 write_reg(par, 0x0039, CURVE(1, 7) << 8 | CURVE(1, 6));
172 write_reg(par, 0x003A, CURVE(1, 9) << 8 | CURVE(1, 8));
173 write_reg(par, 0x003B, CURVE(1, 11) << 8 | CURVE(1, 10));
174
175 write_reg(par, 0x003C, CURVE(0, 13) << 8 | CURVE(0, 12));
176 write_reg(par, 0x003D, CURVE(1, 13) << 8 | CURVE(1, 12));
177
178 return 0;
179}
180#undef CURVE
181
182
183static struct fbtft_display display = {
184 .regwidth = 16,
185 .width = WIDTH,
186 .height = HEIGHT,
187 .bpp = BPP,
188 .fps = FPS,
189 .gamma_num = 2,
190 .gamma_len = 14,
191 .gamma = DEFAULT_GAMMA,
192 .fbtftops = {
193 .init_display = init_display,
194 .set_addr_win = set_addr_win,
195 .set_var = set_var,
196 .set_gamma = set_gamma,
197 },
198};
199FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d1121", &display);
200
201MODULE_ALIAS("spi:" DRVNAME);
202MODULE_ALIAS("platform:" DRVNAME);
203MODULE_ALIAS("spi:s6d1121");
204MODULE_ALIAS("platform:s6d1121");
205
206MODULE_DESCRIPTION("FB driver for the S6D1121 LCD Controller");
207MODULE_AUTHOR("Roman Rolinsky");
208MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c
new file mode 100644
index 000000000000..ef46fbca2700
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1289.c
@@ -0,0 +1,206 @@
1/*
2 * FB driver for the SSD1289 LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * Init sequence taken from ITDB02_Graph16.cpp - (C)2010-2011 Henning Karlsen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/gpio.h>
27
28#include "fbtft.h"
29
30#define DRVNAME "fb_ssd1289"
31#define WIDTH 240
32#define HEIGHT 320
33#define DEFAULT_GAMMA "02 03 2 5 7 7 4 2 4 2\n" \
34 "02 03 2 5 7 5 4 2 4 2"
35
36static unsigned reg11 = 0x6040;
37module_param(reg11, uint, 0);
38MODULE_PARM_DESC(reg11, "Register 11h value");
39
40
41static int init_display(struct fbtft_par *par)
42{
43 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
44
45 par->fbtftops.reset(par);
46
47 if (par->gpio.cs != -1)
48 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
49
50 write_reg(par, 0x00, 0x0001);
51 write_reg(par, 0x03, 0xA8A4);
52 write_reg(par, 0x0C, 0x0000);
53 write_reg(par, 0x0D, 0x080C);
54 write_reg(par, 0x0E, 0x2B00);
55 write_reg(par, 0x1E, 0x00B7);
56 write_reg(par, 0x01,
57 (1 << 13) | (par->bgr << 11) | (1 << 9) | (HEIGHT - 1));
58 write_reg(par, 0x02, 0x0600);
59 write_reg(par, 0x10, 0x0000);
60 write_reg(par, 0x05, 0x0000);
61 write_reg(par, 0x06, 0x0000);
62 write_reg(par, 0x16, 0xEF1C);
63 write_reg(par, 0x17, 0x0003);
64 write_reg(par, 0x07, 0x0233);
65 write_reg(par, 0x0B, 0x0000);
66 write_reg(par, 0x0F, 0x0000);
67 write_reg(par, 0x41, 0x0000);
68 write_reg(par, 0x42, 0x0000);
69 write_reg(par, 0x48, 0x0000);
70 write_reg(par, 0x49, 0x013F);
71 write_reg(par, 0x4A, 0x0000);
72 write_reg(par, 0x4B, 0x0000);
73 write_reg(par, 0x44, 0xEF00);
74 write_reg(par, 0x45, 0x0000);
75 write_reg(par, 0x46, 0x013F);
76 write_reg(par, 0x23, 0x0000);
77 write_reg(par, 0x24, 0x0000);
78 write_reg(par, 0x25, 0x8000);
79 write_reg(par, 0x4f, 0x0000);
80 write_reg(par, 0x4e, 0x0000);
81 write_reg(par, 0x22);
82 return 0;
83}
84
85static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
86{
87 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
88 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
89
90 switch (par->info->var.rotate) {
91 /* R4Eh - Set GDDRAM X address counter */
92 /* R4Fh - Set GDDRAM Y address counter */
93 case 0:
94 write_reg(par, 0x4e, xs);
95 write_reg(par, 0x4f, ys);
96 break;
97 case 180:
98 write_reg(par, 0x4e, par->info->var.xres - 1 - xs);
99 write_reg(par, 0x4f, par->info->var.yres - 1 - ys);
100 break;
101 case 270:
102 write_reg(par, 0x4e, par->info->var.yres - 1 - ys);
103 write_reg(par, 0x4f, xs);
104 break;
105 case 90:
106 write_reg(par, 0x4e, ys);
107 write_reg(par, 0x4f, par->info->var.xres - 1 - xs);
108 break;
109 }
110
111 /* R22h - RAM data write */
112 write_reg(par, 0x22);
113}
114
115static int set_var(struct fbtft_par *par)
116{
117 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
118
119 if (par->fbtftops.init_display != init_display) {
120 /* don't risk messing up register 11h */
121 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
122 "%s: skipping since custom init_display() is used\n",
123 __func__);
124 return 0;
125 }
126
127 switch (par->info->var.rotate) {
128 case 0:
129 write_reg(par, 0x11, reg11 | 0b110000);
130 break;
131 case 270:
132 write_reg(par, 0x11, reg11 | 0b101000);
133 break;
134 case 180:
135 write_reg(par, 0x11, reg11 | 0b000000);
136 break;
137 case 90:
138 write_reg(par, 0x11, reg11 | 0b011000);
139 break;
140 }
141
142 return 0;
143}
144
145/*
146 Gamma string format:
147 VRP0 VRP1 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5
148 VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5
149*/
150#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
151static int set_gamma(struct fbtft_par *par, unsigned long *curves)
152{
153 unsigned long mask[] = {
154 0b11111, 0b11111, 0b111, 0b111, 0b111,
155 0b111, 0b111, 0b111, 0b111, 0b111,
156 0b11111, 0b11111, 0b111, 0b111, 0b111,
157 0b111, 0b111, 0b111, 0b111, 0b111 };
158 int i, j;
159
160 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
161
162 /* apply mask */
163 for (i = 0; i < 2; i++)
164 for (j = 0; j < 10; j++)
165 CURVE(i, j) &= mask[i*par->gamma.num_values + j];
166
167 write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
168 write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
169 write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
170 write_reg(par, 0x0033, CURVE(0, 3) << 8 | CURVE(0, 2));
171 write_reg(par, 0x0034, CURVE(1, 5) << 8 | CURVE(1, 4));
172 write_reg(par, 0x0035, CURVE(1, 7) << 8 | CURVE(1, 6));
173 write_reg(par, 0x0036, CURVE(1, 9) << 8 | CURVE(1, 8));
174 write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
175 write_reg(par, 0x003A, CURVE(0, 1) << 8 | CURVE(0, 0));
176 write_reg(par, 0x003B, CURVE(1, 1) << 8 | CURVE(1, 0));
177
178 return 0;
179}
180#undef CURVE
181
182
183static struct fbtft_display display = {
184 .regwidth = 16,
185 .width = WIDTH,
186 .height = HEIGHT,
187 .gamma_num = 2,
188 .gamma_len = 10,
189 .gamma = DEFAULT_GAMMA,
190 .fbtftops = {
191 .init_display = init_display,
192 .set_addr_win = set_addr_win,
193 .set_var = set_var,
194 .set_gamma = set_gamma,
195 },
196};
197FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1289", &display);
198
199MODULE_ALIAS("spi:" DRVNAME);
200MODULE_ALIAS("platform:" DRVNAME);
201MODULE_ALIAS("spi:ssd1289");
202MODULE_ALIAS("platform:ssd1289");
203
204MODULE_DESCRIPTION("FB driver for the SSD1289 LCD Controller");
205MODULE_AUTHOR("Noralf Tronnes");
206MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c
new file mode 100644
index 000000000000..5ea195b0de1b
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1306.c
@@ -0,0 +1,229 @@
1/*
2 * FB driver for the SSD1306 OLED Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26
27#include "fbtft.h"
28
29#define DRVNAME "fb_ssd1306"
30#define WIDTH 128
31#define HEIGHT 64
32
33
34/*
35 write_reg() caveat:
36
37 This doesn't work because D/C has to be LOW for both values:
38 write_reg(par, val1, val2);
39
40 Do it like this:
41 write_reg(par, val1);
42 write_reg(par, val2);
43*/
44
45/* Init sequence taken from the Adafruit SSD1306 Arduino library */
46static int init_display(struct fbtft_par *par)
47{
48 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
49
50 par->fbtftops.reset(par);
51
52 if (par->gamma.curves[0] == 0) {
53 mutex_lock(&par->gamma.lock);
54 if (par->info->var.yres == 64)
55 par->gamma.curves[0] = 0xCF;
56 else
57 par->gamma.curves[0] = 0x8F;
58 mutex_unlock(&par->gamma.lock);
59 }
60
61 /* Set Display OFF */
62 write_reg(par, 0xAE);
63
64 /* Set Display Clock Divide Ratio/ Oscillator Frequency */
65 write_reg(par, 0xD5);
66 write_reg(par, 0x80);
67
68 /* Set Multiplex Ratio */
69 write_reg(par, 0xA8);
70 if (par->info->var.yres == 64)
71 write_reg(par, 0x3F);
72 else
73 write_reg(par, 0x1F);
74
75 /* Set Display Offset */
76 write_reg(par, 0xD3);
77 write_reg(par, 0x0);
78
79 /* Set Display Start Line */
80 write_reg(par, 0x40 | 0x0);
81
82 /* Charge Pump Setting */
83 write_reg(par, 0x8D);
84 /* A[2] = 1b, Enable charge pump during display on */
85 write_reg(par, 0x14);
86
87 /* Set Memory Addressing Mode */
88 write_reg(par, 0x20);
89 /* Vertical addressing mode */
90 write_reg(par, 0x01);
91
92 /*Set Segment Re-map */
93 /* column address 127 is mapped to SEG0 */
94 write_reg(par, 0xA0 | 0x1);
95
96 /* Set COM Output Scan Direction */
97 /* remapped mode. Scan from COM[N-1] to COM0 */
98 write_reg(par, 0xC8);
99
100 /* Set COM Pins Hardware Configuration */
101 write_reg(par, 0xDA);
102 if (par->info->var.yres == 64)
103 /* A[4]=1b, Alternative COM pin configuration */
104 write_reg(par, 0x12);
105 else
106 /* A[4]=0b, Sequential COM pin configuration */
107 write_reg(par, 0x02);
108
109 /* Set Pre-charge Period */
110 write_reg(par, 0xD9);
111 write_reg(par, 0xF1);
112
113 /* Set VCOMH Deselect Level */
114 write_reg(par, 0xDB);
115 /* according to the datasheet, this value is out of bounds */
116 write_reg(par, 0x40);
117
118 /* Entire Display ON */
119 /* Resume to RAM content display. Output follows RAM content */
120 write_reg(par, 0xA4);
121
122 /* Set Normal Display
123 0 in RAM: OFF in display panel
124 1 in RAM: ON in display panel */
125 write_reg(par, 0xA6);
126
127 /* Set Display ON */
128 write_reg(par, 0xAF);
129
130 return 0;
131}
132
133static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
134{
135 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
136 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
137
138 /* Set Lower Column Start Address for Page Addressing Mode */
139 write_reg(par, 0x00 | 0x0);
140 /* Set Higher Column Start Address for Page Addressing Mode */
141 write_reg(par, 0x10 | 0x0);
142 /* Set Display Start Line */
143 write_reg(par, 0x40 | 0x0);
144}
145
146static int blank(struct fbtft_par *par, bool on)
147{
148 fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n",
149 __func__, on ? "true" : "false");
150
151 if (on)
152 write_reg(par, 0xAE);
153 else
154 write_reg(par, 0xAF);
155 return 0;
156}
157
158/* Gamma is used to control Contrast */
159static int set_gamma(struct fbtft_par *par, unsigned long *curves)
160{
161 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
162
163 /* apply mask */
164 curves[0] &= 0xFF;
165
166 /* Set Contrast Control for BANK0 */
167 write_reg(par, 0x81);
168 write_reg(par, curves[0]);
169
170 return 0;
171}
172
173static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
174{
175 u16 *vmem16 = (u16 *)par->info->screen_base;
176 u8 *buf = par->txbuf.buf;
177 int x, y, i;
178 int ret = 0;
179
180 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
181
182 for (x = 0; x < par->info->var.xres; x++) {
183 for (y = 0; y < par->info->var.yres/8; y++) {
184 *buf = 0x00;
185 for (i = 0; i < 8; i++)
186 *buf |= (vmem16[(y*8+i)*par->info->var.xres+x] ? 1 : 0) << i;
187 buf++;
188 }
189 }
190
191 /* Write data */
192 gpio_set_value(par->gpio.dc, 1);
193 ret = par->fbtftops.write(par, par->txbuf.buf,
194 par->info->var.xres*par->info->var.yres/8);
195 if (ret < 0)
196 dev_err(par->info->device,
197 "%s: write failed and returned: %d\n", __func__, ret);
198
199 return ret;
200}
201
202
203static struct fbtft_display display = {
204 .regwidth = 8,
205 .width = WIDTH,
206 .height = HEIGHT,
207 .gamma_num = 1,
208 .gamma_len = 1,
209 .gamma = "00",
210 .fbtftops = {
211 .write_vmem = write_vmem,
212 .init_display = init_display,
213 .set_addr_win = set_addr_win,
214 .blank = blank,
215 .set_gamma = set_gamma,
216 },
217};
218
219
220FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1306", &display);
221
222MODULE_ALIAS("spi:" DRVNAME);
223MODULE_ALIAS("platform:" DRVNAME);
224MODULE_ALIAS("spi:ssd1306");
225MODULE_ALIAS("platform:ssd1306");
226
227MODULE_DESCRIPTION("SSD1306 OLED Driver");
228MODULE_AUTHOR("Noralf Tronnes");
229MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c
new file mode 100644
index 000000000000..da7464f90e37
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1331.c
@@ -0,0 +1,205 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/init.h>
4#include <linux/gpio.h>
5#include <linux/spi/spi.h>
6#include <linux/delay.h>
7
8#include "fbtft.h"
9
10#define DRVNAME "fb_ssd1331"
11#define WIDTH 96
12#define HEIGHT 64
13#define GAMMA_NUM 1
14#define GAMMA_LEN 63
15#define DEFAULT_GAMMA "0 2 2 2 2 2 2 2 " \
16 "2 2 2 2 2 2 2 2 " \
17 "2 2 2 2 2 2 2 2 " \
18 "2 2 2 2 2 2 2 2 " \
19 "2 2 2 2 2 2 2 2 " \
20 "2 2 2 2 2 2 2 2 " \
21 "2 2 2 2 2 2 2 2 " \
22 "2 2 2 2 2 2 2" \
23
24static int init_display(struct fbtft_par *par)
25{
26 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
27
28 par->fbtftops.reset(par);
29
30 write_reg(par, 0xae); /* Display Off */
31 write_reg(par, 0xa0, 0x70 | (par->bgr << 2)); /* Set Colour Depth */
32 write_reg(par, 0x72); // RGB colour
33 write_reg(par, 0xa1, 0x00); /* Set Display Start Line */
34 write_reg(par, 0xa2, 0x00); /* Set Display Offset */
35 write_reg(par, 0xa4); /* NORMALDISPLAY */
36 write_reg(par, 0xa8, 0x3f); // Set multiplex
37 write_reg(par, 0xad, 0x8e); // Set master
38 // write_reg(par, 0xb0, 0x0b); // Set power mode
39 write_reg(par, 0xb1, 0x31); // Precharge
40 write_reg(par, 0xb3, 0xf0); // Clock div
41 write_reg(par, 0x8a, 0x64); // Precharge A
42 write_reg(par, 0x8b, 0x78); // Precharge B
43 write_reg(par, 0x8c, 0x64); // Precharge C
44 write_reg(par, 0xbb, 0x3a); // Precharge level
45 write_reg(par, 0xbe, 0x3e); // vcomh
46 write_reg(par, 0x87, 0x06); // Master current
47 write_reg(par, 0x81, 0x91); // Contrast A
48 write_reg(par, 0x82, 0x50); // Contrast B
49 write_reg(par, 0x83, 0x7d); // Contrast C
50 write_reg(par, 0xaf); /* Set Sleep Mode Display On */
51
52 return 0;
53}
54
55static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
56{
57 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
58 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
59
60 write_reg(par, 0x15, xs, xe);
61 write_reg(par, 0x75, ys, ye);
62}
63
64static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
65{
66 va_list args;
67 int i, ret;
68 u8 *buf = (u8 *)par->buf;
69
70 if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
71 va_start(args, len);
72 for (i = 0; i < len; i++) {
73 buf[i] = (u8)va_arg(args, unsigned int);
74 }
75 va_end(args);
76 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device, u8, buf, len, "%s: ", __func__);
77 }
78
79 va_start(args, len);
80
81 *buf = (u8)va_arg(args, unsigned int);
82 if (par->gpio.dc != -1)
83 gpio_set_value(par->gpio.dc, 0);
84 ret = par->fbtftops.write(par, par->buf, sizeof(u8));
85 if (ret < 0) {
86 va_end(args);
87 dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret);
88 return;
89 }
90 len--;
91
92 if (len) {
93 i = len;
94 while (i--) {
95 *buf++ = (u8)va_arg(args, unsigned int);
96 }
97 ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8)));
98 if (ret < 0) {
99 va_end(args);
100 dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret);
101 return;
102 }
103 }
104 if (par->gpio.dc != -1)
105 gpio_set_value(par->gpio.dc, 1);
106 va_end(args);
107}
108
109/*
110 Grayscale Lookup Table
111 GS1 - GS63
112 The driver Gamma curve contains the relative values between the entries
113 in the Lookup table.
114
115 From datasheet:
116 8.8 Gray Scale Decoder
117
118 there are total 180 Gamma Settings (Setting 0 to Setting 180)
119 available for the Gray Scale table.
120
121 The gray scale is defined in incremental way, with reference
122 to the length of previous table entry:
123 Setting of GS1 has to be >= 0
124 Setting of GS2 has to be > Setting of GS1 +1
125 Setting of GS3 has to be > Setting of GS2 +1
126 :
127 Setting of GS63 has to be > Setting of GS62 +1
128
129
130*/
131static int set_gamma(struct fbtft_par *par, unsigned long *curves)
132{
133 unsigned long tmp[GAMMA_NUM * GAMMA_LEN];
134 int i, acc = 0;
135
136 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
137
138 for (i = 0; i < 63; i++) {
139 if (i > 0 && curves[i] < 2) {
140 dev_err(par->info->device,
141 "Illegal value in Grayscale Lookup Table at index %d. " \
142 "Must be greater than 1\n", i);
143 return -EINVAL;
144 }
145 acc += curves[i];
146 tmp[i] = acc;
147 if (acc > 180) {
148 dev_err(par->info->device,
149 "Illegal value(s) in Grayscale Lookup Table. " \
150 "At index=%d, the accumulated value has exceeded 180\n", i);
151 return -EINVAL;
152 }
153 }
154
155 write_reg(par, 0xB8,
156 tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7],
157 tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15],
158 tmp[16], tmp[17], tmp[18], tmp[19], tmp[20], tmp[21], tmp[22], tmp[23],
159 tmp[24], tmp[25], tmp[26], tmp[27], tmp[28], tmp[29], tmp[30], tmp[31],
160 tmp[32], tmp[33], tmp[34], tmp[35], tmp[36], tmp[37], tmp[38], tmp[39],
161 tmp[40], tmp[41], tmp[42], tmp[43], tmp[44], tmp[45], tmp[46], tmp[47],
162 tmp[48], tmp[49], tmp[50], tmp[51], tmp[52], tmp[53], tmp[54], tmp[55],
163 tmp[56], tmp[57], tmp[58], tmp[59], tmp[60], tmp[61], tmp[62]);
164
165 return 0;
166}
167
168static int blank(struct fbtft_par *par, bool on)
169{
170 fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n",
171 __func__, on ? "true" : "false");
172 if (on)
173 write_reg(par, 0xAE);
174 else
175 write_reg(par, 0xAF);
176 return 0;
177}
178
179
180static struct fbtft_display display = {
181 .regwidth = 8,
182 .width = WIDTH,
183 .height = HEIGHT,
184 .gamma_num = GAMMA_NUM,
185 .gamma_len = GAMMA_LEN,
186 .gamma = DEFAULT_GAMMA,
187 .fbtftops = {
188 .write_register = write_reg8_bus8,
189 .init_display = init_display,
190 .set_addr_win = set_addr_win,
191 .set_gamma = set_gamma,
192 .blank = blank,
193 },
194};
195
196FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1331", &display);
197
198MODULE_ALIAS("spi:" DRVNAME);
199MODULE_ALIAS("platform:" DRVNAME);
200MODULE_ALIAS("spi:ssd1331");
201MODULE_ALIAS("platform:ssd1331");
202
203MODULE_DESCRIPTION("SSD1331 OLED Driver");
204MODULE_AUTHOR("Alec Smecher (adapted from SSD1351 by James Davies)");
205MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c
new file mode 100644
index 000000000000..062d98660f63
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1351.c
@@ -0,0 +1,258 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/init.h>
4#include <linux/gpio.h>
5#include <linux/spi/spi.h>
6#include <linux/delay.h>
7
8#include "fbtft.h"
9
10#define DRVNAME "fb_ssd1351"
11#define WIDTH 128
12#define HEIGHT 128
13#define GAMMA_NUM 1
14#define GAMMA_LEN 63
15#define DEFAULT_GAMMA "0 2 2 2 2 2 2 2 " \
16 "2 2 2 2 2 2 2 2 " \
17 "2 2 2 2 2 2 2 2 " \
18 "2 2 2 2 2 2 2 2 " \
19 "2 2 2 2 2 2 2 2 " \
20 "2 2 2 2 2 2 2 2 " \
21 "2 2 2 2 2 2 2 2 " \
22 "2 2 2 2 2 2 2" \
23
24static void register_onboard_backlight(struct fbtft_par *par);
25
26static int init_display(struct fbtft_par *par)
27{
28 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
29
30 if (par->pdata
31 && par->pdata->display.backlight == FBTFT_ONBOARD_BACKLIGHT) {
32 /* module uses onboard GPIO for panel power */
33 par->fbtftops.register_backlight = register_onboard_backlight;
34 }
35
36 par->fbtftops.reset(par);
37
38 write_reg(par, 0xfd, 0x12); /* Command Lock */
39 write_reg(par, 0xfd, 0xb1); /* Command Lock */
40 write_reg(par, 0xae); /* Display Off */
41 write_reg(par, 0xb3, 0xf1); /* Front Clock Div */
42 write_reg(par, 0xca, 0x7f); /* Set Mux Ratio */
43 write_reg(par, 0x15, 0x00, 0x7f); /* Set Column Address */
44 write_reg(par, 0x75, 0x00, 0x7f); /* Set Row Address */
45 write_reg(par, 0xa1, 0x00); /* Set Display Start Line */
46 write_reg(par, 0xa2, 0x00); /* Set Display Offset */
47 write_reg(par, 0xb5, 0x00); /* Set GPIO */
48 write_reg(par, 0xab, 0x01); /* Set Function Selection */
49 write_reg(par, 0xb1, 0x32); /* Set Phase Length */
50 write_reg(par, 0xb4, 0xa0, 0xb5, 0x55); /* Set Segment Low Voltage */
51 write_reg(par, 0xbb, 0x17); /* Set Precharge Voltage */
52 write_reg(par, 0xbe, 0x05); /* Set VComH Voltage */
53 write_reg(par, 0xc1, 0xc8, 0x80, 0xc8); /* Set Contrast */
54 write_reg(par, 0xc7, 0x0f); /* Set Master Contrast */
55 write_reg(par, 0xb6, 0x01); /* Set Second Precharge Period */
56 write_reg(par, 0xa6); /* Set Display Mode Reset */
57 write_reg(par, 0xaf); /* Set Sleep Mode Display On */
58
59 return 0;
60}
61
62static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
63{
64 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
65 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
66
67 write_reg(par, 0x15, xs, xe);
68 write_reg(par, 0x75, ys, ye);
69 write_reg(par, 0x5c);
70}
71
72static int set_var(struct fbtft_par *par)
73{
74 unsigned remap;
75 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
76
77 if (par->fbtftops.init_display != init_display) {
78 /* don't risk messing up register A0h */
79 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
80 "%s: skipping since custom init_display() is used\n",
81 __func__);
82 return 0;
83 }
84
85 remap = 0x60 | (par->bgr << 2); /* Set Colour Depth */
86
87 switch (par->info->var.rotate) {
88 case 0:
89 write_reg(par, 0xA0, remap | 0b00 | 1<<4);
90 break;
91 case 270:
92 write_reg(par, 0xA0, remap | 0b11 | 1<<4);
93 break;
94 case 180:
95 write_reg(par, 0xA0, remap | 0b10);
96 break;
97 case 90:
98 write_reg(par, 0xA0, remap | 0b01);
99 break;
100 }
101
102 return 0;
103}
104
105/*
106 Grayscale Lookup Table
107 GS1 - GS63
108 The driver Gamma curve contains the relative values between the entries
109 in the Lookup table.
110
111 From datasheet:
112 8.8 Gray Scale Decoder
113
114 there are total 180 Gamma Settings (Setting 0 to Setting 180)
115 available for the Gray Scale table.
116
117 The gray scale is defined in incremental way, with reference
118 to the length of previous table entry:
119 Setting of GS1 has to be >= 0
120 Setting of GS2 has to be > Setting of GS1 +1
121 Setting of GS3 has to be > Setting of GS2 +1
122 :
123 Setting of GS63 has to be > Setting of GS62 +1
124
125
126*/
127static int set_gamma(struct fbtft_par *par, unsigned long *curves)
128{
129 unsigned long tmp[GAMMA_NUM * GAMMA_LEN];
130 int i, acc = 0;
131
132 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
133
134 for (i = 0; i < 63; i++) {
135 if (i > 0 && curves[i] < 2) {
136 dev_err(par->info->device,
137 "Illegal value in Grayscale Lookup Table at index %d. " \
138 "Must be greater than 1\n", i);
139 return -EINVAL;
140 }
141 acc += curves[i];
142 tmp[i] = acc;
143 if (acc > 180) {
144 dev_err(par->info->device,
145 "Illegal value(s) in Grayscale Lookup Table. " \
146 "At index=%d, the accumulated value has exceeded 180\n", i);
147 return -EINVAL;
148 }
149 }
150
151 write_reg(par, 0xB8,
152 tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7],
153 tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15],
154 tmp[16], tmp[17], tmp[18], tmp[19], tmp[20], tmp[21], tmp[22], tmp[23],
155 tmp[24], tmp[25], tmp[26], tmp[27], tmp[28], tmp[29], tmp[30], tmp[31],
156 tmp[32], tmp[33], tmp[34], tmp[35], tmp[36], tmp[37], tmp[38], tmp[39],
157 tmp[40], tmp[41], tmp[42], tmp[43], tmp[44], tmp[45], tmp[46], tmp[47],
158 tmp[48], tmp[49], tmp[50], tmp[51], tmp[52], tmp[53], tmp[54], tmp[55],
159 tmp[56], tmp[57], tmp[58], tmp[59], tmp[60], tmp[61], tmp[62]);
160
161 return 0;
162}
163
164static int blank(struct fbtft_par *par, bool on)
165{
166 fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n",
167 __func__, on ? "true" : "false");
168 if (on)
169 write_reg(par, 0xAE);
170 else
171 write_reg(par, 0xAF);
172 return 0;
173}
174
175
176static struct fbtft_display display = {
177 .regwidth = 8,
178 .width = WIDTH,
179 .height = HEIGHT,
180 .gamma_num = GAMMA_NUM,
181 .gamma_len = GAMMA_LEN,
182 .gamma = DEFAULT_GAMMA,
183 .fbtftops = {
184 .init_display = init_display,
185 .set_addr_win = set_addr_win,
186 .set_var = set_var,
187 .set_gamma = set_gamma,
188 .blank = blank,
189 },
190};
191
192#ifdef CONFIG_FB_BACKLIGHT
193static int update_onboard_backlight(struct backlight_device *bd)
194{
195 struct fbtft_par *par = bl_get_data(bd);
196 bool on;
197
198 fbtft_par_dbg(DEBUG_BACKLIGHT, par,
199 "%s: power=%d, fb_blank=%d\n",
200 __func__, bd->props.power, bd->props.fb_blank);
201
202 on = (bd->props.power == FB_BLANK_UNBLANK)
203 && (bd->props.fb_blank == FB_BLANK_UNBLANK);
204 /* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
205 write_reg(par, 0xB5, on ? 0x03 : 0x02);
206
207 return 0;
208}
209
210static void register_onboard_backlight(struct fbtft_par *par)
211{
212 struct backlight_device *bd;
213 struct backlight_properties bl_props = { 0, };
214 struct backlight_ops *bl_ops;
215
216 fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
217
218 bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
219 GFP_KERNEL);
220 if (!bl_ops) {
221 dev_err(par->info->device,
222 "%s: could not allocate memory for backlight operations.\n",
223 __func__);
224 return;
225 }
226
227 bl_ops->update_status = update_onboard_backlight;
228 bl_props.type = BACKLIGHT_RAW;
229 bl_props.power = FB_BLANK_POWERDOWN;
230
231 bd = backlight_device_register(dev_driver_string(par->info->device),
232 par->info->device, par, bl_ops, &bl_props);
233 if (IS_ERR(bd)) {
234 dev_err(par->info->device,
235 "cannot register backlight device (%ld)\n",
236 PTR_ERR(bd));
237 return;
238 }
239 par->info->bl_dev = bd;
240
241 if (!par->fbtftops.unregister_backlight)
242 par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
243}
244#else
245static void register_onboard_backlight(struct fbtft_par *par) { };
246#endif
247
248
249FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1351", &display);
250
251MODULE_ALIAS("spi:" DRVNAME);
252MODULE_ALIAS("platform:" DRVNAME);
253MODULE_ALIAS("spi:ssd1351");
254MODULE_ALIAS("platform:ssd1351");
255
256MODULE_DESCRIPTION("SSD1351 OLED Driver");
257MODULE_AUTHOR("James Davies");
258MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_st7735r.c b/drivers/staging/fbtft/fb_st7735r.c
new file mode 100644
index 000000000000..b63aa38e51cf
--- /dev/null
+++ b/drivers/staging/fbtft/fb_st7735r.c
@@ -0,0 +1,195 @@
1/*
2 * FB driver for the ST7735R LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24
25#include "fbtft.h"
26
27#define DRVNAME "fb_st7735r"
28#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
29 "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
30
31
32static int default_init_sequence[] = {
33 /* SWRESET - Software reset */
34 -1, 0x01,
35 -2, 150, /* delay */
36
37 /* SLPOUT - Sleep out & booster on */
38 -1, 0x11,
39 -2, 500, /* delay */
40
41 /* FRMCTR1 - frame rate control: normal mode
42 frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */
43 -1, 0xB1, 0x01, 0x2C, 0x2D,
44
45 /* FRMCTR2 - frame rate control: idle mode
46 frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */
47 -1, 0xB2, 0x01, 0x2C, 0x2D,
48
49 /* FRMCTR3 - frame rate control - partial mode
50 dot inversion mode, line inversion mode */
51 -1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
52
53 /* INVCTR - display inversion control
54 no inversion */
55 -1, 0xB4, 0x07,
56
57 /* PWCTR1 - Power Control
58 -4.6V, AUTO mode */
59 -1, 0xC0, 0xA2, 0x02, 0x84,
60
61 /* PWCTR2 - Power Control
62 VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
63 -1, 0xC1, 0xC5,
64
65 /* PWCTR3 - Power Control
66 Opamp current small, Boost frequency */
67 -1, 0xC2, 0x0A, 0x00,
68
69 /* PWCTR4 - Power Control
70 BCLK/2, Opamp current small & Medium low */
71 -1, 0xC3,0x8A,0x2A,
72
73 /* PWCTR5 - Power Control */
74 -1, 0xC4, 0x8A, 0xEE,
75
76 /* VMCTR1 - Power Control */
77 -1, 0xC5, 0x0E,
78
79 /* INVOFF - Display inversion off */
80 -1, 0x20,
81
82 /* COLMOD - Interface pixel format */
83 -1, 0x3A, 0x05,
84
85 /* DISPON - Display On */
86 -1, 0x29,
87 -2, 100, /* delay */
88
89 /* NORON - Partial off (Normal) */
90 -1, 0x13,
91 -2, 10, /* delay */
92
93 /* end marker */
94 -3
95};
96
97static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
98{
99 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
100 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
101
102 /* Column address */
103 write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
104
105 /* Row adress */
106 write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
107
108 /* Memory write */
109 write_reg(par, 0x2C);
110}
111
112#define MY (1 << 7)
113#define MX (1 << 6)
114#define MV (1 << 5)
115static int set_var(struct fbtft_par *par)
116{
117 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
118
119 /* MADCTL - Memory data access control
120 RGB/BGR:
121 1. Mode selection pin SRGB
122 RGB H/W pin for color filter setting: 0=RGB, 1=BGR
123 2. MADCTL RGB bit
124 RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR */
125 switch (par->info->var.rotate) {
126 case 0:
127 write_reg(par, 0x36, MX | MY | (par->bgr << 3));
128 break;
129 case 270:
130 write_reg(par, 0x36, MY | MV | (par->bgr << 3));
131 break;
132 case 180:
133 write_reg(par, 0x36, (par->bgr << 3));
134 break;
135 case 90:
136 write_reg(par, 0x36, MX | MV | (par->bgr << 3));
137 break;
138 }
139
140 return 0;
141}
142
143/*
144 Gamma string format:
145 VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
146 VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
147*/
148#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
149static int set_gamma(struct fbtft_par *par, unsigned long *curves)
150{
151 int i,j;
152
153 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
154
155 /* apply mask */
156 for (i = 0; i < par->gamma.num_curves; i++)
157 for (j = 0; j < par->gamma.num_values; j++)
158 CURVE(i,j) &= 0b111111;
159
160 for (i = 0; i < par->gamma.num_curves; i++)
161 write_reg(par, 0xE0 + i,
162 CURVE(i, 0), CURVE(i, 1), CURVE(i, 2), CURVE(i, 3),
163 CURVE(i, 4), CURVE(i, 5), CURVE(i, 6), CURVE(i, 7),
164 CURVE(i, 8), CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
165 CURVE(i, 12), CURVE(i, 13), CURVE(i, 14), CURVE(i,15));
166
167 return 0;
168}
169#undef CURVE
170
171
172static struct fbtft_display display = {
173 .regwidth = 8,
174 .width = 128,
175 .height = 160,
176 .init_sequence = default_init_sequence,
177 .gamma_num = 2,
178 .gamma_len = 16,
179 .gamma = DEFAULT_GAMMA,
180 .fbtftops = {
181 .set_addr_win = set_addr_win,
182 .set_var = set_var,
183 .set_gamma = set_gamma,
184 },
185};
186FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
187
188MODULE_ALIAS("spi:" DRVNAME);
189MODULE_ALIAS("platform:" DRVNAME);
190MODULE_ALIAS("spi:st7735r");
191MODULE_ALIAS("platform:st7735r");
192
193MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
194MODULE_AUTHOR("Noralf Tronnes");
195MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c
new file mode 100644
index 000000000000..ca98bfb5c7df
--- /dev/null
+++ b/drivers/staging/fbtft/fb_tinylcd.c
@@ -0,0 +1,124 @@
1/*
2 * Custom FB driver for tinylcd.com display
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25
26#include "fbtft.h"
27
28#define DRVNAME "fb_tinylcd"
29#define WIDTH 320
30#define HEIGHT 480
31
32
33static int init_display(struct fbtft_par *par)
34{
35 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
36
37 par->fbtftops.reset(par);
38
39 write_reg(par, 0xB0, 0x80);
40 write_reg(par, 0xC0, 0x0A, 0x0A);
41 write_reg(par, 0xC1, 0x45, 0x07);
42 write_reg(par, 0xC2, 0x33);
43 write_reg(par, 0xC5, 0x00, 0x42, 0x80);
44 write_reg(par, 0xB1, 0xD0, 0x11);
45 write_reg(par, 0xB4, 0x02);
46 write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
47 write_reg(par, 0xB7, 0x07);
48 write_reg(par, 0x36, 0x58);
49 write_reg(par, 0xF0, 0x36, 0xA5, 0xD3);
50 write_reg(par, 0xE5, 0x80);
51 write_reg(par, 0xE5, 0x01);
52 write_reg(par, 0xB3, 0x00);
53 write_reg(par, 0xE5, 0x00);
54 write_reg(par, 0xF0, 0x36, 0xA5, 0x53);
55 write_reg(par, 0xE0, 0x00, 0x35, 0x33, 0x00, 0x00, 0x00,
56 0x00, 0x35, 0x33, 0x00, 0x00, 0x00);
57 write_reg(par, 0x3A, 0x55);
58 write_reg(par, 0x11);
59 udelay(250);
60 write_reg(par, 0x29);
61
62 return 0;
63}
64
65static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
66{
67 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
68 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
69
70 /* Column address */
71 write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
72
73 /* Row adress */
74 write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
75
76 /* Memory write */
77 write_reg(par, 0x2C);
78}
79
80static int set_var(struct fbtft_par *par)
81{
82 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
83
84 switch (par->info->var.rotate) {
85 case 270:
86 write_reg(par, 0xB6, 0x00, 0x02, 0x3B);
87 write_reg(par, 0x36, 0x28);
88 break;
89 case 180:
90 write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
91 write_reg(par, 0x36, 0x58);
92 break;
93 case 90:
94 write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
95 write_reg(par, 0x36, 0x38);
96 break;
97 default:
98 write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
99 write_reg(par, 0x36, 0x08);
100 break;
101 }
102
103 return 0;
104}
105
106
107static struct fbtft_display display = {
108 .regwidth = 8,
109 .width = WIDTH,
110 .height = HEIGHT,
111 .fbtftops = {
112 .init_display = init_display,
113 .set_addr_win = set_addr_win,
114 .set_var = set_var,
115 },
116};
117FBTFT_REGISTER_DRIVER(DRVNAME, "neosec,tinylcd", &display);
118
119MODULE_ALIAS("spi:" DRVNAME);
120MODULE_ALIAS("spi:tinylcd");
121
122MODULE_DESCRIPTION("Custom FB driver for tinylcd.com display");
123MODULE_AUTHOR("Noralf Tronnes");
124MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c
new file mode 100644
index 000000000000..8738c7a7bfda
--- /dev/null
+++ b/drivers/staging/fbtft/fb_tls8204.c
@@ -0,0 +1,176 @@
1/*
2 * FB driver for the TLS8204 LCD Controller
3 *
4 * The display is monochrome and the video memory is RGB565.
5 * Any pixel value except 0 turns the pixel on.
6 *
7 * Copyright (C) 2013 Noralf Tronnes
8 * Copyright (C) 2014 Michael Hope (adapted for the TLS8204)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/gpio.h>
29#include <linux/spi/spi.h>
30#include <linux/delay.h>
31
32#include "fbtft.h"
33
34#define DRVNAME "fb_tls8204"
35#define WIDTH 84
36#define HEIGHT 48
37#define TXBUFLEN WIDTH
38#define DEFAULT_GAMMA "40" /* gamma is used to control contrast in this driver */
39
40static unsigned bs = 4;
41module_param(bs, uint, 0);
42MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
43
44static int init_display(struct fbtft_par *par)
45{
46 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
47
48 par->fbtftops.reset(par);
49
50 /* Enter extended command mode */
51 write_reg(par, 0x21); /* 5:1 1
52 2:0 PD - Powerdown control: chip is active
53 1:0 V - Entry mode: horizontal addressing
54 0:1 H - Extended instruction set control: extended
55 */
56
57 /* H=1 Bias system */
58 write_reg(par, 0x10 | (bs & 0x7)); /*
59 4:1 1
60 3:0 0
61 2:x BS2 - Bias System
62 1:x BS1
63 0:x BS0
64 */
65
66 /* Set the address of the first display line. */
67 write_reg(par, 0x04 | (64 >> 6));
68 write_reg(par, 0x40 | (64 & 0x3F));
69
70 /* Enter H=0 standard command mode */
71 write_reg(par, 0x20);
72
73 /* H=0 Display control */
74 write_reg(par, 0x08 | 4); /*
75 3:1 1
76 2:1 D - DE: 10=normal mode
77 1:0 0
78 0:0 E
79 */
80
81 return 0;
82}
83
84static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
85{
86 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
87
88 /* H=0 Set X address of RAM */
89 write_reg(par, 0x80); /* 7:1 1
90 6-0: X[6:0] - 0x00
91 */
92
93 /* H=0 Set Y address of RAM */
94 write_reg(par, 0x40); /* 7:0 0
95 6:1 1
96 2-0: Y[2:0] - 0x0
97 */
98}
99
100static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
101{
102 u16 *vmem16 = (u16 *)par->info->screen_base;
103 int x, y, i;
104 int ret = 0;
105
106 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
107
108 for (y = 0; y < HEIGHT/8; y++) {
109 u8 *buf = par->txbuf.buf;
110 /* The display is 102x68 but the LCD is 84x48. Set
111 the write pointer at the start of each row. */
112 gpio_set_value(par->gpio.dc, 0);
113 write_reg(par, 0x80 | 0);
114 write_reg(par, 0x40 | y);
115
116 for (x = 0; x < WIDTH; x++) {
117 u8 ch = 0;
118 for (i = 0; i < 8*WIDTH; i += WIDTH) {
119 ch >>= 1;
120 if (vmem16[(y*8*WIDTH)+i+x])
121 ch |= 0x80;
122 }
123 *buf++ = ch;
124 }
125 /* Write the row */
126 gpio_set_value(par->gpio.dc, 1);
127 ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH);
128 if (ret < 0) {
129 dev_err(par->info->device,
130 "%s: write failed and returned: %d\n", __func__, ret);
131 break;
132 }
133 }
134
135 return ret;
136}
137
138static int set_gamma(struct fbtft_par *par, unsigned long *curves)
139{
140 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
141
142 /* apply mask */
143 curves[0] &= 0x7F;
144
145 write_reg(par, 0x21); /* turn on extended instruction set */
146 write_reg(par, 0x80 | curves[0]);
147 write_reg(par, 0x20); /* turn off extended instruction set */
148
149 return 0;
150}
151
152
153static struct fbtft_display display = {
154 .regwidth = 8,
155 .width = WIDTH,
156 .height = HEIGHT,
157 .txbuflen = TXBUFLEN,
158 .gamma_num = 1,
159 .gamma_len = 1,
160 .gamma = DEFAULT_GAMMA,
161 .fbtftops = {
162 .init_display = init_display,
163 .set_addr_win = set_addr_win,
164 .write_vmem = write_vmem,
165 .set_gamma = set_gamma,
166 },
167 .backlight = 1,
168};
169FBTFT_REGISTER_DRIVER(DRVNAME, "teralane,tls8204", &display);
170
171MODULE_ALIAS("spi:" DRVNAME);
172MODULE_ALIAS("spi:tls8204");
173
174MODULE_DESCRIPTION("FB driver for the TLS8204 LCD Controller");
175MODULE_AUTHOR("Michael Hope");
176MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c
new file mode 100644
index 000000000000..d70ac524278c
--- /dev/null
+++ b/drivers/staging/fbtft/fb_uc1701.c
@@ -0,0 +1,210 @@
1/*
2 * FB driver for the UC1701 LCD Controller
3 *
4 * The display is monochrome and the video memory is RGB565.
5 * Any pixel value except 0 turns the pixel on.
6 *
7 * Copyright (C) 2014 Juergen Holzmann
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/gpio.h>
28#include <linux/spi/spi.h>
29#include <linux/delay.h>
30
31#include "fbtft.h"
32
33#define DRVNAME "fb_uc1701"
34#define WIDTH 102
35#define HEIGHT 64
36#define PAGES (HEIGHT/8)
37
38/* 1: Display on/off */
39#define LCD_DISPLAY_ENABLE 0xAE
40/* 2: display start line set */
41#define LCD_START_LINE 0x40
42/* 3: Page address set (lower 4 bits select one of the pages) */
43#define LCD_PAGE_ADDRESS 0xB0
44/* 4: column address */
45#define LCD_COL_ADDRESS 0x10
46/* 8: select orientation */
47#define LCD_BOTTOMVIEW 0xA0
48/* 9: inverted display */
49#define LCD_DISPLAY_INVERT 0xA6
50/* 10: show memory content or switch all pixels on */
51#define LCD_ALL_PIXEL 0xA4
52/* 11: lcd bias set */
53#define LCD_BIAS 0xA2
54/* 14: Reset Controller */
55#define LCD_RESET_CMD 0xE2
56/* 15: output mode select (turns display upside-down) */
57#define LCD_SCAN_DIR 0xC0
58/* 16: power control set */
59#define LCD_POWER_CONTROL 0x28
60/* 17: voltage regulator resistor ratio set */
61#define LCD_VOLTAGE 0x20
62/* 18: Volume mode set */
63#define LCD_VOLUME_MODE 0x81
64/* 22: NOP command */
65#define LCD_NO_OP 0xE3
66/* 25: advanced program control */
67#define LCD_ADV_PROG_CTRL 0xFA
68/* 25: advanced program control2 */
69#define LCD_ADV_PROG_CTRL2 0x10
70#define LCD_TEMPCOMP_HIGH 0x80
71/* column offset for normal orientation */
72#define SHIFT_ADDR_NORMAL 0
73/* column offset for bottom view orientation */
74#define SHIFT_ADDR_TOPVIEW 30
75
76
77static int init_display(struct fbtft_par *par)
78{
79 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
80
81 par->fbtftops.reset(par);
82
83 /* softreset of LCD */
84 write_reg(par, LCD_RESET_CMD);
85 mdelay(10);
86
87 /* set startpoint */
88 /* LCD_START_LINE | (pos & 0x3F) */
89 write_reg(par, LCD_START_LINE);
90
91 /* select orientation BOTTOMVIEW */
92 write_reg(par, LCD_BOTTOMVIEW | 1);
93 /* output mode select (turns display upside-down) */
94 write_reg(par, LCD_SCAN_DIR | 0x00);
95
96 /* Normal Pixel mode */
97 write_reg(par, LCD_ALL_PIXEL | 0);
98
99 /* positive display */
100 write_reg(par, LCD_DISPLAY_INVERT | 0);
101
102 /* bias 1/9 */
103 write_reg(par, LCD_BIAS | 0);
104
105 /* power control mode: all features on */
106 /* LCD_POWER_CONTROL | (val&0x07) */
107 write_reg(par, LCD_POWER_CONTROL | 0x07);
108
109 /* set voltage regulator R/R */
110 /* LCD_VOLTAGE | (val&0x07) */
111 write_reg(par, LCD_VOLTAGE | 0x07);
112
113 /* volume mode set */
114 /* LCD_VOLUME_MODE,val&0x3f,LCD_NO_OP */
115 write_reg(par, LCD_VOLUME_MODE);
116 /* LCD_VOLUME_MODE,val&0x3f,LCD_NO_OP */
117 write_reg(par, 0x09);
118 /* ???? */
119 /* LCD_VOLUME_MODE,val&0x3f,LCD_NO_OP */
120 write_reg(par, LCD_NO_OP);
121
122 /* advanced program control */
123 write_reg(par, LCD_ADV_PROG_CTRL);
124 write_reg(par, LCD_ADV_PROG_CTRL2|LCD_TEMPCOMP_HIGH);
125
126 /* enable display */
127 write_reg(par, LCD_DISPLAY_ENABLE | 1);
128
129 return 0;
130}
131
132static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
133{
134 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
135
136 /* goto address */
137 /* LCD_PAGE_ADDRESS | ((page) & 0x1F),
138 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
139 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
140 write_reg(par, LCD_PAGE_ADDRESS);
141 /* LCD_PAGE_ADDRESS | ((page) & 0x1F),
142 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
143 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
144 write_reg(par, 0x00);
145 /* LCD_PAGE_ADDRESS | ((page) & 0x1F),
146 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
147 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
148 write_reg(par, LCD_COL_ADDRESS);
149}
150
151static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
152{
153 u16 *vmem16 = (u16 *)par->info->screen_base;
154 u8 *buf = par->txbuf.buf;
155 int x, y, i;
156 int ret = 0;
157
158 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
159
160 for (y = 0; y < PAGES; y++) {
161 buf = par->txbuf.buf;
162 for (x = 0; x < WIDTH; x++) {
163 *buf = 0x00;
164 for (i = 0; i < 8; i++)
165 *buf |= (vmem16[((y*8*WIDTH)+(i*WIDTH))+x] ? 1 : 0) << i;
166 buf++;
167 }
168 /* LCD_PAGE_ADDRESS | ((page) & 0x1F),
169 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
170 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
171 write_reg(par, LCD_PAGE_ADDRESS|(u8)y);
172 /* LCD_PAGE_ADDRESS | ((page) & 0x1F),
173 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
174 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
175 write_reg(par, 0x00);
176 /* LCD_PAGE_ADDRESS | ((page) & 0x1F),
177 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
178 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
179 write_reg(par, LCD_COL_ADDRESS);
180 gpio_set_value(par->gpio.dc, 1);
181 ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH);
182 gpio_set_value(par->gpio.dc, 0);
183 }
184
185 if (ret < 0)
186 dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret);
187
188 return ret;
189}
190
191
192static struct fbtft_display display = {
193 .regwidth = 8,
194 .width = WIDTH,
195 .height = HEIGHT,
196 .fbtftops = {
197 .init_display = init_display,
198 .set_addr_win = set_addr_win,
199 .write_vmem = write_vmem,
200 },
201 .backlight = 1,
202};
203FBTFT_REGISTER_DRIVER(DRVNAME, "UltraChip,uc1701", &display);
204
205MODULE_ALIAS("spi:" DRVNAME);
206MODULE_ALIAS("spi:uc1701");
207
208MODULE_DESCRIPTION("FB driver for the UC1701 LCD Controller");
209MODULE_AUTHOR("Juergen Holzmann");
210MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c
new file mode 100644
index 000000000000..fff57b330ba2
--- /dev/null
+++ b/drivers/staging/fbtft/fb_upd161704.c
@@ -0,0 +1,206 @@
1/*
2 * FB driver for the uPD161704 LCD Controller
3 *
4 * Copyright (C) 2014 Seong-Woo Kim
5 *
6 * Based on fb_ili9325.c by Noralf Tronnes
7 * Based on ili9325.c by Jeroen Domburg
8 * Init code from UTFT library by Henning Karlsen
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/gpio.h>
29#include <linux/delay.h>
30
31#include "fbtft.h"
32
33#define DRVNAME "fb_upd161704"
34#define WIDTH 240
35#define HEIGHT 320
36#define BPP 16
37
38static int init_display(struct fbtft_par *par)
39{
40 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
41
42 par->fbtftops.reset(par);
43
44 if (par->gpio.cs != -1)
45 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
46
47 /* Initialization sequence from Lib_UTFT */
48
49 /* register reset */
50 write_reg(par, 0x0003,0x0001); /* Soft reset */
51
52 /* oscillator start */
53 write_reg(par, 0x003A,0x0001); /*Oscillator 0: stop, 1: operation */
54 udelay(100);
55
56 /* y-setting */
57 write_reg(par, 0x0024,0x007B); /* amplitude setting */
58 udelay(10);
59 write_reg(par, 0x0025,0x003B); /* amplitude setting */
60 write_reg(par, 0x0026,0x0034); /* amplitude setting */
61 udelay(10);
62 write_reg(par, 0x0027,0x0004); /* amplitude setting */
63 write_reg(par, 0x0052,0x0025); /* circuit setting 1 */
64 udelay(10);
65 write_reg(par, 0x0053,0x0033); /* circuit setting 2 */
66 write_reg(par, 0x0061,0x001C); /* adjustment V10 positive polarity */
67 udelay(10);
68 write_reg(par, 0x0062,0x002C); /* adjustment V9 negative polarity */
69 write_reg(par, 0x0063,0x0022); /* adjustment V34 positive polarity */
70 udelay(10);
71 write_reg(par, 0x0064,0x0027); /* adjustment V31 negative polarity */
72 udelay(10);
73 write_reg(par, 0x0065,0x0014); /* adjustment V61 negative polarity */
74 udelay(10);
75 write_reg(par, 0x0066,0x0010); /* adjustment V61 negative polarity */
76
77 /* Basical clock for 1 line (BASECOUNT[7:0]) number specified */
78 write_reg(par, 0x002E,0x002D);
79
80 /* Power supply setting */
81 write_reg(par, 0x0019,0x0000); /* DC/DC output setting */
82 udelay(200);
83 write_reg(par, 0x001A,0x1000); /* DC/DC frequency setting */
84 write_reg(par, 0x001B,0x0023); /* DC/DC rising setting */
85 write_reg(par, 0x001C,0x0C01); /* Regulator voltage setting */
86 write_reg(par, 0x001D,0x0000); /* Regulator current setting */
87 write_reg(par, 0x001E,0x0009); /* VCOM output setting */
88 write_reg(par, 0x001F,0x0035); /* VCOM amplitude setting */
89 write_reg(par, 0x0020,0x0015); /* VCOMM cencter setting */
90 write_reg(par, 0x0018,0x1E7B); /* DC/DC operation setting */
91
92 /* windows setting */
93 write_reg(par, 0x0008,0x0000); /* Minimum X address */
94 write_reg(par, 0x0009,0x00EF); /* Maximum X address */
95 write_reg(par, 0x000a,0x0000); /* Minimum Y address */
96 write_reg(par, 0x000b,0x013F); /* Maximum Y address */
97
98 /* LCD display area setting */
99 write_reg(par, 0x0029,0x0000); /* [LCDSIZE] X MIN. size set */
100 write_reg(par, 0x002A,0x0000); /* [LCDSIZE] Y MIN. size set */
101 write_reg(par, 0x002B,0x00EF); /* [LCDSIZE] X MAX. size set */
102 write_reg(par, 0x002C,0x013F); /* [LCDSIZE] Y MAX. size set */
103
104 /* Gate scan setting */
105 write_reg(par, 0x0032,0x0002);
106
107 /* n line inversion line number */
108 write_reg(par, 0x0033,0x0000);
109
110 /* Line inversion/frame inversion/interlace setting */
111 write_reg(par, 0x0037,0x0000);
112
113 /* Gate scan operation setting register */
114 write_reg(par, 0x003B,0x0001);
115
116 /* Color mode */
117 /*GS = 0: 260-k color (64 gray scale), GS = 1: 8 color (2 gray scale) */
118 write_reg(par, 0x0004,0x0000);
119
120 /* RAM control register */
121 write_reg(par, 0x0005,0x0000); /*Window access 00:Normal, 10:Window */
122
123 /* Display setting register 2 */
124 write_reg(par, 0x0001,0x0000);
125
126 /* display setting */
127 write_reg(par, 0x0000,0x0000); /* display on */
128
129 return 0;
130}
131
132static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
133{
134 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
135 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
136 switch (par->info->var.rotate) {
137 /* R20h = Horizontal GRAM Start Address */
138 /* R21h = Vertical GRAM Start Address */
139 case 0:
140 write_reg(par, 0x0006, xs);
141 write_reg(par, 0x0007, ys);
142 break;
143 case 180:
144 write_reg(par, 0x0006, WIDTH - 1 - xs);
145 write_reg(par, 0x0007, HEIGHT - 1 - ys);
146 break;
147 case 270:
148 write_reg(par, 0x0006, WIDTH - 1 - ys);
149 write_reg(par, 0x0007, xs);
150 break;
151 case 90:
152 write_reg(par, 0x0006, ys);
153 write_reg(par, 0x0007, HEIGHT - 1 - xs);
154 break;
155 }
156
157 write_reg(par, 0x0e); /* Write Data to GRAM */
158}
159
160static int set_var(struct fbtft_par *par)
161{
162 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
163
164 switch (par->info->var.rotate) {
165 /* AM: GRAM update direction */
166 case 0:
167 write_reg(par, 0x01, 0x0000);
168 write_reg(par, 0x05, 0x0000);
169 break;
170 case 180:
171 write_reg(par, 0x01, 0x00C0);
172 write_reg(par, 0x05, 0x0000);
173 break;
174 case 270:
175 write_reg(par, 0x01, 0x0080);
176 write_reg(par, 0x05, 0x0001);
177 break;
178 case 90:
179 write_reg(par, 0x01, 0x0040);
180 write_reg(par, 0x05, 0x0001);
181 break;
182 }
183
184 return 0;
185}
186
187static struct fbtft_display display = {
188 .regwidth = 16,
189 .width = WIDTH,
190 .height = HEIGHT,
191 .fbtftops = {
192 .init_display = init_display,
193 .set_addr_win = set_addr_win,
194 .set_var = set_var,
195 },
196};
197FBTFT_REGISTER_DRIVER(DRVNAME, "nec,upd161704", &display);
198
199MODULE_ALIAS("spi:" DRVNAME);
200MODULE_ALIAS("platform:" DRVNAME);
201MODULE_ALIAS("spi:upd161704");
202MODULE_ALIAS("platform:upd161704");
203
204MODULE_DESCRIPTION("FB driver for the uPD161704 LCD Controller");
205MODULE_AUTHOR("Seong-Woo Kim");
206MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c
new file mode 100644
index 000000000000..975b579359f3
--- /dev/null
+++ b/drivers/staging/fbtft/fb_watterott.c
@@ -0,0 +1,324 @@
1/*
2 * FB driver for the Watterott LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26
27#include "fbtft.h"
28
29#define DRVNAME "fb_watterott"
30#define WIDTH 320
31#define HEIGHT 240
32#define FPS 5
33#define TXBUFLEN 1024
34#define DEFAULT_BRIGHTNESS 50
35
36#define CMD_VERSION 0x01
37#define CMD_LCD_LED 0x10
38#define CMD_LCD_RESET 0x11
39#define CMD_LCD_ORIENTATION 0x20
40#define CMD_LCD_DRAWIMAGE 0x27
41#define COLOR_RGB323 8
42#define COLOR_RGB332 9
43#define COLOR_RGB233 10
44#define COLOR_RGB565 16
45
46
47static short mode = 565;
48module_param(mode, short, 0);
49MODULE_PARM_DESC(mode, "RGB color transfer mode: 332, 565 (default)");
50
51static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
52{
53 va_list args;
54 int i, ret;
55 u8 *buf = par->buf;
56
57 va_start(args, len);
58 for (i = 0; i < len; i++)
59 *buf++ = (u8)va_arg(args, unsigned int);
60 va_end(args);
61
62 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par,
63 par->info->device, u8, par->buf, len, "%s: ", __func__);
64
65 ret = par->fbtftops.write(par, par->buf, len);
66 if (ret < 0) {
67 dev_err(par->info->device,
68 "%s: write() failed and returned %d\n", __func__, ret);
69 return;
70 }
71}
72
73static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
74{
75 unsigned start_line, end_line;
76 u16 *vmem16 = (u16 *)(par->info->screen_base + offset);
77 u16 *pos = par->txbuf.buf + 1;
78 u16 *buf16 = par->txbuf.buf + 10;
79 int i, j;
80 int ret = 0;
81
82 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
83
84 start_line = offset / par->info->fix.line_length;
85 end_line = start_line + (len / par->info->fix.line_length) - 1;
86
87 /* Set command header. pos: x, y, w, h */
88 ((u8 *)par->txbuf.buf)[0] = CMD_LCD_DRAWIMAGE;
89 pos[0] = 0;
90 pos[2] = cpu_to_be16(par->info->var.xres);
91 pos[3] = cpu_to_be16(1);
92 ((u8 *)par->txbuf.buf)[9] = COLOR_RGB565;
93
94 for (i = start_line; i <= end_line; i++) {
95 pos[1] = cpu_to_be16(i);
96 for (j = 0; j < par->info->var.xres; j++)
97 buf16[j] = cpu_to_be16(*vmem16++);
98 ret = par->fbtftops.write(par,
99 par->txbuf.buf, 10 + par->info->fix.line_length);
100 if (ret < 0)
101 return ret;
102 udelay(300);
103 }
104
105 return 0;
106}
107
108#define RGB565toRGB323(c) (((c&0xE000)>>8) | ((c&0600)>>6) | ((c&0x001C)>>2))
109#define RGB565toRGB332(c) (((c&0xE000)>>8) | ((c&0700)>>6) | ((c&0x0018)>>3))
110#define RGB565toRGB233(c) (((c&0xC000)>>8) | ((c&0700)>>5) | ((c&0x001C)>>2))
111
112static int write_vmem_8bit(struct fbtft_par *par, size_t offset, size_t len)
113{
114 unsigned start_line, end_line;
115 u16 *vmem16 = (u16 *)(par->info->screen_base + offset);
116 u16 *pos = par->txbuf.buf + 1;
117 u8 *buf8 = par->txbuf.buf + 10;
118 int i, j;
119 int ret = 0;
120
121 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
122
123 start_line = offset / par->info->fix.line_length;
124 end_line = start_line + (len / par->info->fix.line_length) - 1;
125
126 /* Set command header. pos: x, y, w, h */
127 ((u8 *)par->txbuf.buf)[0] = CMD_LCD_DRAWIMAGE;
128 pos[0] = 0;
129 pos[2] = cpu_to_be16(par->info->var.xres);
130 pos[3] = cpu_to_be16(1);
131 ((u8 *)par->txbuf.buf)[9] = COLOR_RGB332;
132
133 for (i = start_line; i <= end_line; i++) {
134 pos[1] = cpu_to_be16(i);
135 for (j = 0; j < par->info->var.xres; j++) {
136 buf8[j] = RGB565toRGB332(*vmem16);
137 vmem16++;
138 }
139 ret = par->fbtftops.write(par,
140 par->txbuf.buf, 10 + par->info->var.xres);
141 if (ret < 0)
142 return ret;
143 udelay(700);
144 }
145
146 return 0;
147}
148
149static unsigned firmware_version(struct fbtft_par *par)
150{
151 u8 rxbuf[4] = {0, };
152
153 write_reg(par, CMD_VERSION);
154 par->fbtftops.read(par, rxbuf, 4);
155 if (rxbuf[1] != '.')
156 return 0;
157
158 return (rxbuf[0] - '0') << 8 | (rxbuf[2] - '0') << 4 | (rxbuf[3] - '0');
159}
160
161static int init_display(struct fbtft_par *par)
162{
163 int ret;
164 unsigned version;
165 u8 save_mode;
166
167 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
168
169 /* enable SPI interface by having CS and MOSI low during reset */
170 save_mode = par->spi->mode;
171 par->spi->mode |= SPI_CS_HIGH;
172 ret = par->spi->master->setup(par->spi); /* set CS inactive low */
173 if (ret) {
174 dev_err(par->info->device, "Could not set SPI_CS_HIGH\n");
175 return ret;
176 }
177 write_reg(par, 0x00); /* make sure mode is set */
178
179 mdelay(50);
180 par->fbtftops.reset(par);
181 mdelay(1000);
182 par->spi->mode = save_mode;
183 ret = par->spi->master->setup(par->spi);
184 if (ret) {
185 dev_err(par->info->device, "Could not restore SPI mode\n");
186 return ret;
187 }
188 write_reg(par, 0x00);
189
190 version = firmware_version(par);
191 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "Firmware version: %x.%02x\n",
192 version >> 8, version & 0xFF);
193
194 if (mode == 332)
195 par->fbtftops.write_vmem = write_vmem_8bit;
196 return 0;
197}
198
199static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
200{
201 /* not used on this controller */
202}
203
204static int set_var(struct fbtft_par *par)
205{
206 u8 rotate;
207
208 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
209
210 /* this controller rotates clock wise */
211 switch (par->info->var.rotate) {
212 case 90:
213 rotate = 27;
214 break;
215 case 180:
216 rotate = 18;
217 break;
218 case 270:
219 rotate = 9;
220 break;
221 default:
222 rotate = 0;
223 }
224 write_reg(par, CMD_LCD_ORIENTATION, rotate);
225
226 return 0;
227}
228
229static int verify_gpios(struct fbtft_par *par)
230{
231 if (par->gpio.reset < 0) {
232 dev_err(par->info->device, "Missing 'reset' gpio. Aborting.\n");
233 return -EINVAL;
234 }
235 return 0;
236}
237
238#ifdef CONFIG_FB_BACKLIGHT
239static int backlight_chip_update_status(struct backlight_device *bd)
240{
241 struct fbtft_par *par = bl_get_data(bd);
242 int brightness = bd->props.brightness;
243
244 fbtft_par_dbg(DEBUG_BACKLIGHT, par,
245 "%s: brightness=%d, power=%d, fb_blank=%d\n",
246 __func__, bd->props.brightness, bd->props.power,
247 bd->props.fb_blank);
248
249 if (bd->props.power != FB_BLANK_UNBLANK)
250 brightness = 0;
251
252 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
253 brightness = 0;
254
255 write_reg(par, CMD_LCD_LED, brightness);
256
257 return 0;
258}
259
260static void register_chip_backlight(struct fbtft_par *par)
261{
262 struct backlight_device *bd;
263 struct backlight_properties bl_props = { 0, };
264 struct backlight_ops *bl_ops;
265
266 fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
267
268 bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
269 GFP_KERNEL);
270 if (!bl_ops) {
271 dev_err(par->info->device,
272 "%s: could not allocate memory for backlight operations.\n",
273 __func__);
274 return;
275 }
276
277 bl_ops->update_status = backlight_chip_update_status;
278 bl_props.type = BACKLIGHT_RAW;
279 bl_props.power = FB_BLANK_POWERDOWN;
280 bl_props.max_brightness = 100;
281 bl_props.brightness = DEFAULT_BRIGHTNESS;
282
283 bd = backlight_device_register(dev_driver_string(par->info->device),
284 par->info->device, par, bl_ops, &bl_props);
285 if (IS_ERR(bd)) {
286 dev_err(par->info->device,
287 "cannot register backlight device (%ld)\n",
288 PTR_ERR(bd));
289 return;
290 }
291 par->info->bl_dev = bd;
292
293 if (!par->fbtftops.unregister_backlight)
294 par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
295}
296#else
297#define register_chip_backlight NULL
298#endif
299
300
301static struct fbtft_display display = {
302 .regwidth = 8,
303 .buswidth = 8,
304 .width = WIDTH,
305 .height = HEIGHT,
306 .fps = FPS,
307 .txbuflen = TXBUFLEN,
308 .fbtftops = {
309 .write_register = write_reg8_bus8,
310 .write_vmem = write_vmem,
311 .init_display = init_display,
312 .set_addr_win = set_addr_win,
313 .set_var = set_var,
314 .verify_gpios = verify_gpios,
315 .register_backlight = register_chip_backlight,
316 },
317};
318FBTFT_REGISTER_DRIVER(DRVNAME, "watterott,openlcd", &display);
319
320MODULE_ALIAS("spi:" DRVNAME);
321
322MODULE_DESCRIPTION("FB driver for the Watterott LCD Controller");
323MODULE_AUTHOR("Noralf Tronnes");
324MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
new file mode 100644
index 000000000000..b3cddb0b3d69
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-bus.c
@@ -0,0 +1,256 @@
1#include <linux/export.h>
2#include <linux/errno.h>
3#include <linux/gpio.h>
4#include <linux/spi/spi.h>
5#include "fbtft.h"
6
7
8
9
10/*****************************************************************************
11 *
12 * void (*write_reg)(struct fbtft_par *par, int len, ...);
13 *
14 *****************************************************************************/
15
16#define define_fbtft_write_reg(func, type, modifier) \
17void func(struct fbtft_par *par, int len, ...) \
18{ \
19 va_list args; \
20 int i, ret; \
21 int offset = 0; \
22 type *buf = (type *)par->buf; \
23 \
24 if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) { \
25 va_start(args, len); \
26 for (i = 0; i < len; i++) { \
27 buf[i] = (type)va_arg(args, unsigned int); \
28 } \
29 va_end(args); \
30 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device, type, buf, len, "%s: ", __func__); \
31 } \
32 \
33 va_start(args, len); \
34 \
35 if (par->startbyte) { \
36 *(u8 *)par->buf = par->startbyte; \
37 buf = (type *)(par->buf + 1); \
38 offset = 1; \
39 } \
40 \
41 *buf = modifier((type)va_arg(args, unsigned int)); \
42 if (par->gpio.dc != -1) \
43 gpio_set_value(par->gpio.dc, 0); \
44 ret = par->fbtftops.write(par, par->buf, sizeof(type)+offset); \
45 if (ret < 0) { \
46 va_end(args); \
47 dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); \
48 return; \
49 } \
50 len--; \
51 \
52 if (par->startbyte) \
53 *(u8 *)par->buf = par->startbyte | 0x2; \
54 \
55 if (len) { \
56 i = len; \
57 while (i--) { \
58 *buf++ = modifier((type)va_arg(args, unsigned int)); \
59 } \
60 if (par->gpio.dc != -1) \
61 gpio_set_value(par->gpio.dc, 1); \
62 ret = par->fbtftops.write(par, par->buf, len * (sizeof(type)+offset)); \
63 if (ret < 0) { \
64 va_end(args); \
65 dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); \
66 return; \
67 } \
68 } \
69 va_end(args); \
70} \
71EXPORT_SYMBOL(func);
72
73define_fbtft_write_reg(fbtft_write_reg8_bus8, u8, )
74define_fbtft_write_reg(fbtft_write_reg16_bus8, u16, cpu_to_be16)
75define_fbtft_write_reg(fbtft_write_reg16_bus16, u16, )
76
77void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
78{
79 va_list args;
80 int i, ret;
81 int pad = 0;
82 u16 *buf = (u16 *)par->buf;
83
84 if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
85 va_start(args, len);
86 for (i = 0; i < len; i++)
87 *(((u8 *)buf) + i) = (u8)va_arg(args, unsigned int);
88 va_end(args);
89 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par,
90 par->info->device, u8, buf, len, "%s: ", __func__);
91 }
92 if (len <= 0)
93 return;
94
95 if (par->spi && (par->spi->bits_per_word == 8)) {
96 /* we're emulating 9-bit, pad start of buffer with no-ops
97 (assuming here that zero is a no-op) */
98 pad = (len % 4) ? 4 - (len % 4) : 0;
99 for (i = 0; i < pad; i++)
100 *buf++ = 0x000;
101 }
102
103 va_start(args, len);
104 *buf++ = (u8)va_arg(args, unsigned int);
105 i = len - 1;
106 while (i--) {
107 *buf = (u8)va_arg(args, unsigned int);
108 *buf++ |= 0x100; /* dc=1 */
109 }
110 va_end(args);
111 ret = par->fbtftops.write(par, par->buf, (len + pad) * sizeof(u16));
112 if (ret < 0) {
113 dev_err(par->info->device,
114 "%s: write() failed and returned %d\n", __func__, ret);
115 return;
116 }
117}
118EXPORT_SYMBOL(fbtft_write_reg8_bus9);
119
120
121
122
123/*****************************************************************************
124 *
125 * int (*write_vmem)(struct fbtft_par *par);
126 *
127 *****************************************************************************/
128
129/* 16 bit pixel over 8-bit databus */
130int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
131{
132 u16 *vmem16;
133 u16 *txbuf16 = (u16 *)par->txbuf.buf;
134 size_t remain;
135 size_t to_copy;
136 size_t tx_array_size;
137 int i;
138 int ret = 0;
139 size_t startbyte_size = 0;
140
141 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
142 __func__, offset, len);
143
144 remain = len / 2;
145 vmem16 = (u16 *)(par->info->screen_base + offset);
146
147 if (par->gpio.dc != -1)
148 gpio_set_value(par->gpio.dc, 1);
149
150 /* non buffered write */
151 if (!par->txbuf.buf)
152 return par->fbtftops.write(par, vmem16, len);
153
154 /* buffered write */
155 tx_array_size = par->txbuf.len / 2;
156
157 if (par->startbyte) {
158 txbuf16 = (u16 *)(par->txbuf.buf + 1);
159 tx_array_size -= 2;
160 *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
161 startbyte_size = 1;
162 }
163
164 while (remain) {
165 to_copy = remain > tx_array_size ? tx_array_size : remain;
166 dev_dbg(par->info->device, " to_copy=%zu, remain=%zu\n",
167 to_copy, remain - to_copy);
168
169 for (i = 0; i < to_copy; i++)
170 txbuf16[i] = cpu_to_be16(vmem16[i]);
171
172 vmem16 = vmem16 + to_copy;
173 ret = par->fbtftops.write(par, par->txbuf.buf,
174 startbyte_size + to_copy * 2);
175 if (ret < 0)
176 return ret;
177 remain -= to_copy;
178 }
179
180 return ret;
181}
182EXPORT_SYMBOL(fbtft_write_vmem16_bus8);
183
184/* 16 bit pixel over 9-bit SPI bus: dc + high byte, dc + low byte */
185int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len)
186{
187 u8 *vmem8;
188 u16 *txbuf16 = par->txbuf.buf;
189 size_t remain;
190 size_t to_copy;
191 size_t tx_array_size;
192 int i;
193 int ret = 0;
194
195 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
196 __func__, offset, len);
197
198 if (!par->txbuf.buf) {
199 dev_err(par->info->device, "%s: txbuf.buf is NULL\n", __func__);
200 return -1;
201 }
202
203 remain = len;
204 vmem8 = par->info->screen_base + offset;
205
206 tx_array_size = par->txbuf.len / 2;
207
208 while (remain) {
209 to_copy = remain > tx_array_size ? tx_array_size : remain;
210 dev_dbg(par->info->device, " to_copy=%zu, remain=%zu\n",
211 to_copy, remain - to_copy);
212
213#ifdef __LITTLE_ENDIAN
214 for (i = 0; i < to_copy; i += 2) {
215 txbuf16[i] = 0x0100 | vmem8[i+1];
216 txbuf16[i+1] = 0x0100 | vmem8[i];
217 }
218#else
219 for (i = 0; i < to_copy; i++)
220 txbuf16[i] = 0x0100 | vmem8[i];
221#endif
222 vmem8 = vmem8 + to_copy;
223 ret = par->fbtftops.write(par, par->txbuf.buf, to_copy*2);
224 if (ret < 0)
225 return ret;
226 remain -= to_copy;
227 }
228
229 return ret;
230}
231EXPORT_SYMBOL(fbtft_write_vmem16_bus9);
232
233int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len)
234{
235 dev_err(par->info->device, "%s: function not implemented\n", __func__);
236 return -1;
237}
238EXPORT_SYMBOL(fbtft_write_vmem8_bus8);
239
240/* 16 bit pixel over 16-bit databus */
241int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len)
242{
243 u16 *vmem16;
244
245 fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
246 __func__, offset, len);
247
248 vmem16 = (u16 *)(par->info->screen_base + offset);
249
250 if (par->gpio.dc != -1)
251 gpio_set_value(par->gpio.dc, 1);
252
253 /* no need for buffered write with 16-bit bus */
254 return par->fbtftops.write(par, vmem16, len);
255}
256EXPORT_SYMBOL(fbtft_write_vmem16_bus16);
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
new file mode 100644
index 000000000000..37dcf7eb191a
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -0,0 +1,1521 @@
1/*
2 * Copyright (C) 2013 Noralf Tronnes
3 *
4 * This driver is inspired by:
5 * st7735fb.c, Copyright (C) 2011, Matt Porter
6 * broadsheetfb.c, Copyright (C) 2008, Jaya Kumar
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/errno.h>
26#include <linux/string.h>
27#include <linux/mm.h>
28#include <linux/vmalloc.h>
29#include <linux/slab.h>
30#include <linux/init.h>
31#include <linux/fb.h>
32#include <linux/gpio.h>
33#include <linux/spi/spi.h>
34#include <linux/delay.h>
35#include <linux/uaccess.h>
36#include <linux/backlight.h>
37#include <linux/platform_device.h>
38#include <linux/spinlock.h>
39#include <linux/dma-mapping.h>
40#include <linux/of.h>
41#include <linux/of_gpio.h>
42
43#include "fbtft.h"
44
45extern void fbtft_sysfs_init(struct fbtft_par *par);
46extern void fbtft_sysfs_exit(struct fbtft_par *par);
47extern void fbtft_expand_debug_value(unsigned long *debug);
48extern int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves,
49 const char *str, int size);
50
51static unsigned long debug;
52module_param(debug, ulong , 0);
53MODULE_PARM_DESC(debug, "override device debug level");
54
55static bool dma = true;
56module_param(dma, bool, 0);
57MODULE_PARM_DESC(dma, "Use DMA buffer");
58
59
60void fbtft_dbg_hex(const struct device *dev, int groupsize,
61 void *buf, size_t len, const char *fmt, ...)
62{
63 va_list args;
64 static char textbuf[512];
65 char *text = textbuf;
66 size_t text_len;
67
68 va_start(args, fmt);
69 text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
70 va_end(args);
71
72 hex_dump_to_buffer(buf, len, 32, groupsize, text + text_len,
73 512 - text_len, false);
74
75 if (len > 32)
76 dev_info(dev, "%s ...\n", text);
77 else
78 dev_info(dev, "%s\n", text);
79}
80EXPORT_SYMBOL(fbtft_dbg_hex);
81
82static unsigned long fbtft_request_gpios_match(struct fbtft_par *par,
83 const struct fbtft_gpio *gpio)
84{
85 int ret;
86 long val;
87
88 fbtft_par_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, "%s('%s')\n",
89 __func__, gpio->name);
90
91 if (strcasecmp(gpio->name, "reset") == 0) {
92 par->gpio.reset = gpio->gpio;
93 return GPIOF_OUT_INIT_HIGH;
94 } else if (strcasecmp(gpio->name, "dc") == 0) {
95 par->gpio.dc = gpio->gpio;
96 return GPIOF_OUT_INIT_LOW;
97 } else if (strcasecmp(gpio->name, "cs") == 0) {
98 par->gpio.cs = gpio->gpio;
99 return GPIOF_OUT_INIT_HIGH;
100 } else if (strcasecmp(gpio->name, "wr") == 0) {
101 par->gpio.wr = gpio->gpio;
102 return GPIOF_OUT_INIT_HIGH;
103 } else if (strcasecmp(gpio->name, "rd") == 0) {
104 par->gpio.rd = gpio->gpio;
105 return GPIOF_OUT_INIT_HIGH;
106 } else if (strcasecmp(gpio->name, "latch") == 0) {
107 par->gpio.latch = gpio->gpio;
108 return GPIOF_OUT_INIT_LOW;
109 } else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') {
110 ret = kstrtol(&gpio->name[2], 10, &val);
111 if (ret == 0 && val < 16) {
112 par->gpio.db[val] = gpio->gpio;
113 return GPIOF_OUT_INIT_LOW;
114 }
115 } else if (strcasecmp(gpio->name, "led") == 0) {
116 par->gpio.led[0] = gpio->gpio;
117 return GPIOF_OUT_INIT_LOW;
118 } else if (strcasecmp(gpio->name, "led_") == 0) {
119 par->gpio.led[0] = gpio->gpio;
120 return GPIOF_OUT_INIT_HIGH;
121 }
122
123 return FBTFT_GPIO_NO_MATCH;
124}
125
126static int fbtft_request_gpios(struct fbtft_par *par)
127{
128 struct fbtft_platform_data *pdata = par->pdata;
129 const struct fbtft_gpio *gpio;
130 unsigned long flags;
131 int ret;
132
133 if (pdata && pdata->gpios) {
134 gpio = pdata->gpios;
135 while (gpio->name[0]) {
136 flags = FBTFT_GPIO_NO_MATCH;
137 /* if driver provides match function, try it first,
138 if no match use our own */
139 if (par->fbtftops.request_gpios_match)
140 flags = par->fbtftops.request_gpios_match(par, gpio);
141 if (flags == FBTFT_GPIO_NO_MATCH)
142 flags = fbtft_request_gpios_match(par, gpio);
143 if (flags != FBTFT_GPIO_NO_MATCH) {
144 ret = devm_gpio_request_one(par->info->device,
145 gpio->gpio, flags,
146 par->info->device->driver->name);
147 if (ret < 0) {
148 dev_err(par->info->device,
149 "%s: gpio_request_one('%s'=%d) failed with %d\n",
150 __func__, gpio->name,
151 gpio->gpio, ret);
152 return ret;
153 }
154 fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par,
155 "%s: '%s' = GPIO%d\n",
156 __func__, gpio->name, gpio->gpio);
157 }
158 gpio++;
159 }
160 }
161
162 return 0;
163}
164
165#ifdef CONFIG_OF
166static int fbtft_request_one_gpio(struct fbtft_par *par,
167 const char *name, int index, int *gpiop)
168{
169 struct device *dev = par->info->device;
170 struct device_node *node = dev->of_node;
171 int gpio, flags, ret = 0;
172 enum of_gpio_flags of_flags;
173
174 if (of_find_property(node, name, NULL)) {
175 gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
176 if (gpio == -ENOENT)
177 return 0;
178 if (gpio == -EPROBE_DEFER)
179 return gpio;
180 if (gpio < 0) {
181 dev_err(dev,
182 "failed to get '%s' from DT\n", name);
183 return gpio;
184 }
185
186 /* active low translates to initially low */
187 flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW :
188 GPIOF_OUT_INIT_HIGH;
189 ret = devm_gpio_request_one(dev, gpio, flags,
190 dev->driver->name);
191 if (ret) {
192 dev_err(dev,
193 "gpio_request_one('%s'=%d) failed with %d\n",
194 name, gpio, ret);
195 return ret;
196 }
197 if (gpiop)
198 *gpiop = gpio;
199 fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n",
200 __func__, name, gpio);
201 }
202
203 return ret;
204}
205
206static int fbtft_request_gpios_dt(struct fbtft_par *par)
207{
208 int i;
209 int ret;
210
211 if (!par->info->device->of_node)
212 return -EINVAL;
213
214 ret = fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset);
215 if (ret)
216 return ret;
217 ret = fbtft_request_one_gpio(par, "dc-gpios", 0, &par->gpio.dc);
218 if (ret)
219 return ret;
220 ret = fbtft_request_one_gpio(par, "rd-gpios", 0, &par->gpio.rd);
221 if (ret)
222 return ret;
223 ret = fbtft_request_one_gpio(par, "wr-gpios", 0, &par->gpio.wr);
224 if (ret)
225 return ret;
226 ret = fbtft_request_one_gpio(par, "cs-gpios", 0, &par->gpio.cs);
227 if (ret)
228 return ret;
229 ret = fbtft_request_one_gpio(par, "latch-gpios", 0, &par->gpio.latch);
230 if (ret)
231 return ret;
232 for (i = 0; i < 16; i++) {
233 ret = fbtft_request_one_gpio(par, "db-gpios", i,
234 &par->gpio.db[i]);
235 if (ret)
236 return ret;
237 ret = fbtft_request_one_gpio(par, "led-gpios", i,
238 &par->gpio.led[i]);
239 if (ret)
240 return ret;
241 ret = fbtft_request_one_gpio(par, "aux-gpios", i,
242 &par->gpio.aux[i]);
243 if (ret)
244 return ret;
245 }
246
247 return 0;
248}
249#endif
250
251#ifdef CONFIG_FB_BACKLIGHT
252static int fbtft_backlight_update_status(struct backlight_device *bd)
253{
254 struct fbtft_par *par = bl_get_data(bd);
255 bool polarity = !!(bd->props.state & BL_CORE_DRIVER1);
256
257 fbtft_par_dbg(DEBUG_BACKLIGHT, par,
258 "%s: polarity=%d, power=%d, fb_blank=%d\n",
259 __func__, polarity, bd->props.power, bd->props.fb_blank);
260
261 if ((bd->props.power == FB_BLANK_UNBLANK) && (bd->props.fb_blank == FB_BLANK_UNBLANK))
262 gpio_set_value(par->gpio.led[0], polarity);
263 else
264 gpio_set_value(par->gpio.led[0], !polarity);
265
266 return 0;
267}
268
269static int fbtft_backlight_get_brightness(struct backlight_device *bd)
270{
271 return bd->props.brightness;
272}
273
274void fbtft_unregister_backlight(struct fbtft_par *par)
275{
276 const struct backlight_ops *bl_ops;
277
278 fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
279
280 if (par->info->bl_dev) {
281 par->info->bl_dev->props.power = FB_BLANK_POWERDOWN;
282 backlight_update_status(par->info->bl_dev);
283 bl_ops = par->info->bl_dev->ops;
284 backlight_device_unregister(par->info->bl_dev);
285 par->info->bl_dev = NULL;
286 }
287}
288
289void fbtft_register_backlight(struct fbtft_par *par)
290{
291 struct backlight_device *bd;
292 struct backlight_properties bl_props = { 0, };
293 struct backlight_ops *bl_ops;
294
295 fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
296
297 if (par->gpio.led[0] == -1) {
298 fbtft_par_dbg(DEBUG_BACKLIGHT, par,
299 "%s(): led pin not set, exiting.\n", __func__);
300 return;
301 }
302
303 bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
304 GFP_KERNEL);
305 if (!bl_ops) {
306 dev_err(par->info->device,
307 "%s: could not allocate memeory for backlight operations.\n",
308 __func__);
309 return;
310 }
311
312 bl_ops->get_brightness = fbtft_backlight_get_brightness;
313 bl_ops->update_status = fbtft_backlight_update_status;
314 bl_props.type = BACKLIGHT_RAW;
315 /* Assume backlight is off, get polarity from current state of pin */
316 bl_props.power = FB_BLANK_POWERDOWN;
317 if (!gpio_get_value(par->gpio.led[0]))
318 bl_props.state |= BL_CORE_DRIVER1;
319
320 bd = backlight_device_register(dev_driver_string(par->info->device),
321 par->info->device, par, bl_ops, &bl_props);
322 if (IS_ERR(bd)) {
323 dev_err(par->info->device,
324 "cannot register backlight device (%ld)\n",
325 PTR_ERR(bd));
326 return;
327 }
328 par->info->bl_dev = bd;
329
330 if (!par->fbtftops.unregister_backlight)
331 par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
332}
333#else
334void fbtft_register_backlight(struct fbtft_par *par) { };
335void fbtft_unregister_backlight(struct fbtft_par *par) { };
336#endif
337EXPORT_SYMBOL(fbtft_register_backlight);
338EXPORT_SYMBOL(fbtft_unregister_backlight);
339
340static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
341 int ye)
342{
343 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
344 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
345
346 /* Column address set */
347 write_reg(par, 0x2A,
348 (xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
349
350 /* Row adress set */
351 write_reg(par, 0x2B,
352 (ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
353
354 /* Memory write */
355 write_reg(par, 0x2C);
356}
357
358
359static void fbtft_reset(struct fbtft_par *par)
360{
361 if (par->gpio.reset == -1)
362 return;
363 fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
364 gpio_set_value(par->gpio.reset, 0);
365 udelay(20);
366 gpio_set_value(par->gpio.reset, 1);
367 mdelay(120);
368}
369
370
371static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
372 unsigned end_line)
373{
374 size_t offset, len;
375 struct timespec ts_start, ts_end, ts_fps, ts_duration;
376 long fps_ms, fps_us, duration_ms, duration_us;
377 long fps, throughput;
378 bool timeit = false;
379 int ret = 0;
380
381 if (unlikely(par->debug & (DEBUG_TIME_FIRST_UPDATE | DEBUG_TIME_EACH_UPDATE))) {
382 if ((par->debug & DEBUG_TIME_EACH_UPDATE) || \
383 ((par->debug & DEBUG_TIME_FIRST_UPDATE) && !par->first_update_done)) {
384 getnstimeofday(&ts_start);
385 timeit = true;
386 }
387 }
388
389 /* Sanity checks */
390 if (start_line > end_line) {
391 dev_warn(par->info->device,
392 "%s: start_line=%u is larger than end_line=%u. Shouldn't happen, will do full display update\n",
393 __func__, start_line, end_line);
394 start_line = 0;
395 end_line = par->info->var.yres - 1;
396 }
397 if (start_line > par->info->var.yres - 1 || end_line > par->info->var.yres - 1) {
398 dev_warn(par->info->device,
399 "%s: start_line=%u or end_line=%u is larger than max=%d. Shouldn't happen, will do full display update\n",
400 __func__, start_line, end_line, par->info->var.yres - 1);
401 start_line = 0;
402 end_line = par->info->var.yres - 1;
403 }
404
405 fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n",
406 __func__, start_line, end_line);
407
408 if (par->fbtftops.set_addr_win)
409 par->fbtftops.set_addr_win(par, 0, start_line,
410 par->info->var.xres-1, end_line);
411
412 offset = start_line * par->info->fix.line_length;
413 len = (end_line - start_line + 1) * par->info->fix.line_length;
414 ret = par->fbtftops.write_vmem(par, offset, len);
415 if (ret < 0)
416 dev_err(par->info->device,
417 "%s: write_vmem failed to update display buffer\n",
418 __func__);
419
420 if (unlikely(timeit)) {
421 getnstimeofday(&ts_end);
422 if (par->update_time.tv_nsec == 0 && par->update_time.tv_sec == 0) {
423 par->update_time.tv_sec = ts_start.tv_sec;
424 par->update_time.tv_nsec = ts_start.tv_nsec;
425 }
426 ts_fps = timespec_sub(ts_start, par->update_time);
427 par->update_time.tv_sec = ts_start.tv_sec;
428 par->update_time.tv_nsec = ts_start.tv_nsec;
429 fps_ms = (ts_fps.tv_sec * 1000) + ((ts_fps.tv_nsec / 1000000) % 1000);
430 fps_us = (ts_fps.tv_nsec / 1000) % 1000;
431 fps = fps_ms * 1000 + fps_us;
432 fps = fps ? 1000000 / fps : 0;
433
434 ts_duration = timespec_sub(ts_end, ts_start);
435 duration_ms = (ts_duration.tv_sec * 1000) + ((ts_duration.tv_nsec / 1000000) % 1000);
436 duration_us = (ts_duration.tv_nsec / 1000) % 1000;
437 throughput = duration_ms * 1000 + duration_us;
438 throughput = throughput ? (len * 1000) / throughput : 0;
439 throughput = throughput * 1000 / 1024;
440
441 dev_info(par->info->device,
442 "Display update: %ld kB/s (%ld.%.3ld ms), fps=%ld (%ld.%.3ld ms)\n",
443 throughput, duration_ms, duration_us,
444 fps, fps_ms, fps_us);
445 par->first_update_done = true;
446 }
447}
448
449
450static void fbtft_mkdirty(struct fb_info *info, int y, int height)
451{
452 struct fbtft_par *par = info->par;
453 struct fb_deferred_io *fbdefio = info->fbdefio;
454
455 /* special case, needed ? */
456 if (y == -1) {
457 y = 0;
458 height = info->var.yres - 1;
459 }
460
461 /* Mark display lines/area as dirty */
462 spin_lock(&par->dirty_lock);
463 if (y < par->dirty_lines_start)
464 par->dirty_lines_start = y;
465 if (y + height - 1 > par->dirty_lines_end)
466 par->dirty_lines_end = y + height - 1;
467 spin_unlock(&par->dirty_lock);
468
469 /* Schedule deferred_io to update display (no-op if already on queue)*/
470 schedule_delayed_work(&info->deferred_work, fbdefio->delay);
471}
472
473static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
474{
475 struct fbtft_par *par = info->par;
476 unsigned dirty_lines_start, dirty_lines_end;
477 struct page *page;
478 unsigned long index;
479 unsigned y_low = 0, y_high = 0;
480 int count = 0;
481
482 spin_lock(&par->dirty_lock);
483 dirty_lines_start = par->dirty_lines_start;
484 dirty_lines_end = par->dirty_lines_end;
485 /* set display line markers as clean */
486 par->dirty_lines_start = par->info->var.yres - 1;
487 par->dirty_lines_end = 0;
488 spin_unlock(&par->dirty_lock);
489
490 /* Mark display lines as dirty */
491 list_for_each_entry(page, pagelist, lru) {
492 count++;
493 index = page->index << PAGE_SHIFT;
494 y_low = index / info->fix.line_length;
495 y_high = (index + PAGE_SIZE - 1) / info->fix.line_length;
496 fbtft_dev_dbg(DEBUG_DEFERRED_IO, par, info->device,
497 "page->index=%lu y_low=%d y_high=%d\n",
498 page->index, y_low, y_high);
499 if (y_high > info->var.yres - 1)
500 y_high = info->var.yres - 1;
501 if (y_low < dirty_lines_start)
502 dirty_lines_start = y_low;
503 if (y_high > dirty_lines_end)
504 dirty_lines_end = y_high;
505 }
506
507 par->fbtftops.update_display(info->par,
508 dirty_lines_start, dirty_lines_end);
509}
510
511
512static void fbtft_fb_fillrect(struct fb_info *info,
513 const struct fb_fillrect *rect)
514{
515 struct fbtft_par *par = info->par;
516
517 fbtft_dev_dbg(DEBUG_FB_FILLRECT, par, info->dev,
518 "%s: dx=%d, dy=%d, width=%d, height=%d\n",
519 __func__, rect->dx, rect->dy, rect->width, rect->height);
520 sys_fillrect(info, rect);
521
522 par->fbtftops.mkdirty(info, rect->dy, rect->height);
523}
524
525static void fbtft_fb_copyarea(struct fb_info *info,
526 const struct fb_copyarea *area)
527{
528 struct fbtft_par *par = info->par;
529
530 fbtft_dev_dbg(DEBUG_FB_COPYAREA, par, info->dev,
531 "%s: dx=%d, dy=%d, width=%d, height=%d\n",
532 __func__, area->dx, area->dy, area->width, area->height);
533 sys_copyarea(info, area);
534
535 par->fbtftops.mkdirty(info, area->dy, area->height);
536}
537
538static void fbtft_fb_imageblit(struct fb_info *info,
539 const struct fb_image *image)
540{
541 struct fbtft_par *par = info->par;
542
543 fbtft_dev_dbg(DEBUG_FB_IMAGEBLIT, par, info->dev,
544 "%s: dx=%d, dy=%d, width=%d, height=%d\n",
545 __func__, image->dx, image->dy, image->width, image->height);
546 sys_imageblit(info, image);
547
548 par->fbtftops.mkdirty(info, image->dy, image->height);
549}
550
551static ssize_t fbtft_fb_write(struct fb_info *info, const char __user *buf,
552 size_t count, loff_t *ppos)
553{
554 struct fbtft_par *par = info->par;
555 ssize_t res;
556
557 fbtft_dev_dbg(DEBUG_FB_WRITE, par, info->dev,
558 "%s: count=%zd, ppos=%llu\n", __func__, count, *ppos);
559 res = fb_sys_write(info, buf, count, ppos);
560
561 /* TODO: only mark changed area
562 update all for now */
563 par->fbtftops.mkdirty(info, -1, 0);
564
565 return res;
566}
567
568/* from pxafb.c */
569static unsigned int chan_to_field(unsigned chan, struct fb_bitfield *bf)
570{
571 chan &= 0xffff;
572 chan >>= 16 - bf->length;
573 return chan << bf->offset;
574}
575
576static int fbtft_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
577 unsigned blue, unsigned transp,
578 struct fb_info *info)
579{
580 struct fbtft_par *par = info->par;
581 unsigned val;
582 int ret = 1;
583
584 fbtft_dev_dbg(DEBUG_FB_SETCOLREG, par, info->dev,
585 "%s(regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X)\n",
586 __func__, regno, red, green, blue, transp);
587
588 switch (info->fix.visual) {
589 case FB_VISUAL_TRUECOLOR:
590 if (regno < 16) {
591 u32 *pal = info->pseudo_palette;
592
593 val = chan_to_field(red, &info->var.red);
594 val |= chan_to_field(green, &info->var.green);
595 val |= chan_to_field(blue, &info->var.blue);
596
597 pal[regno] = val;
598 ret = 0;
599 }
600 break;
601
602 }
603 return ret;
604}
605
606static int fbtft_fb_blank(int blank, struct fb_info *info)
607{
608 struct fbtft_par *par = info->par;
609 int ret = -EINVAL;
610
611 fbtft_dev_dbg(DEBUG_FB_BLANK, par, info->dev, "%s(blank=%d)\n",
612 __func__, blank);
613
614 if (!par->fbtftops.blank)
615 return ret;
616
617 switch (blank) {
618 case FB_BLANK_POWERDOWN:
619 case FB_BLANK_VSYNC_SUSPEND:
620 case FB_BLANK_HSYNC_SUSPEND:
621 case FB_BLANK_NORMAL:
622 ret = par->fbtftops.blank(par, true);
623 break;
624 case FB_BLANK_UNBLANK:
625 ret = par->fbtftops.blank(par, false);
626 break;
627 }
628 return ret;
629}
630
631static void fbtft_merge_fbtftops(struct fbtft_ops *dst, struct fbtft_ops *src)
632{
633 if (src->write)
634 dst->write = src->write;
635 if (src->read)
636 dst->read = src->read;
637 if (src->write_vmem)
638 dst->write_vmem = src->write_vmem;
639 if (src->write_register)
640 dst->write_register = src->write_register;
641 if (src->set_addr_win)
642 dst->set_addr_win = src->set_addr_win;
643 if (src->reset)
644 dst->reset = src->reset;
645 if (src->mkdirty)
646 dst->mkdirty = src->mkdirty;
647 if (src->update_display)
648 dst->update_display = src->update_display;
649 if (src->init_display)
650 dst->init_display = src->init_display;
651 if (src->blank)
652 dst->blank = src->blank;
653 if (src->request_gpios_match)
654 dst->request_gpios_match = src->request_gpios_match;
655 if (src->request_gpios)
656 dst->request_gpios = src->request_gpios;
657 if (src->verify_gpios)
658 dst->verify_gpios = src->verify_gpios;
659 if (src->register_backlight)
660 dst->register_backlight = src->register_backlight;
661 if (src->unregister_backlight)
662 dst->unregister_backlight = src->unregister_backlight;
663 if (src->set_var)
664 dst->set_var = src->set_var;
665 if (src->set_gamma)
666 dst->set_gamma = src->set_gamma;
667}
668
669/**
670 * fbtft_framebuffer_alloc - creates a new frame buffer info structure
671 *
672 * @display: pointer to structure describing the display
673 * @dev: pointer to the device for this fb, this can be NULL
674 *
675 * Creates a new frame buffer info structure.
676 *
677 * Also creates and populates the following structures:
678 * info->fbops
679 * info->fbdefio
680 * info->pseudo_palette
681 * par->fbtftops
682 * par->txbuf
683 *
684 * Returns the new structure, or NULL if an error occurred.
685 *
686 */
687struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
688 struct device *dev)
689{
690 struct fb_info *info;
691 struct fbtft_par *par;
692 struct fb_ops *fbops = NULL;
693 struct fb_deferred_io *fbdefio = NULL;
694 struct fbtft_platform_data *pdata = dev->platform_data;
695 u8 *vmem = NULL;
696 void *txbuf = NULL;
697 void *buf = NULL;
698 unsigned width;
699 unsigned height;
700 int txbuflen = display->txbuflen;
701 unsigned bpp = display->bpp;
702 unsigned fps = display->fps;
703 int vmem_size, i;
704 int *init_sequence = display->init_sequence;
705 char *gamma = display->gamma;
706 unsigned long *gamma_curves = NULL;
707
708 /* sanity check */
709 if (display->gamma_num * display->gamma_len > FBTFT_GAMMA_MAX_VALUES_TOTAL) {
710 dev_err(dev,
711 "%s: FBTFT_GAMMA_MAX_VALUES_TOTAL=%d is exceeded\n",
712 __func__, FBTFT_GAMMA_MAX_VALUES_TOTAL);
713 return NULL;
714 }
715
716 /* defaults */
717 if (!fps)
718 fps = 20;
719 if (!bpp)
720 bpp = 16;
721
722 if (!pdata) {
723 dev_err(dev, "platform data is missing\n");
724 return NULL;
725 }
726
727 /* override driver values? */
728 if (pdata->fps)
729 fps = pdata->fps;
730 if (pdata->txbuflen)
731 txbuflen = pdata->txbuflen;
732 if (pdata->display.init_sequence)
733 init_sequence = pdata->display.init_sequence;
734 if (pdata->gamma)
735 gamma = pdata->gamma;
736 if (pdata->display.debug)
737 display->debug = pdata->display.debug;
738 if (pdata->display.backlight)
739 display->backlight = pdata->display.backlight;
740 if (pdata->display.width)
741 display->width = pdata->display.width;
742 if (pdata->display.height)
743 display->height = pdata->display.height;
744 if (pdata->display.buswidth)
745 display->buswidth = pdata->display.buswidth;
746 if (pdata->display.regwidth)
747 display->regwidth = pdata->display.regwidth;
748
749 display->debug |= debug;
750 fbtft_expand_debug_value(&display->debug);
751
752 switch (pdata->rotate) {
753 case 90:
754 case 270:
755 width = display->height;
756 height = display->width;
757 break;
758 default:
759 width = display->width;
760 height = display->height;
761 }
762
763 vmem_size = display->width * display->height * bpp / 8;
764 vmem = vzalloc(vmem_size);
765 if (!vmem)
766 goto alloc_fail;
767
768 fbops = devm_kzalloc(dev, sizeof(struct fb_ops), GFP_KERNEL);
769 if (!fbops)
770 goto alloc_fail;
771
772 fbdefio = devm_kzalloc(dev, sizeof(struct fb_deferred_io), GFP_KERNEL);
773 if (!fbdefio)
774 goto alloc_fail;
775
776 buf = devm_kzalloc(dev, 128, GFP_KERNEL);
777 if (!buf)
778 goto alloc_fail;
779
780 if (display->gamma_num && display->gamma_len) {
781 gamma_curves = devm_kzalloc(dev, display->gamma_num * display->gamma_len * sizeof(gamma_curves[0]),
782 GFP_KERNEL);
783 if (!gamma_curves)
784 goto alloc_fail;
785 }
786
787 info = framebuffer_alloc(sizeof(struct fbtft_par), dev);
788 if (!info)
789 goto alloc_fail;
790
791 info->screen_base = (u8 __force __iomem *)vmem;
792 info->fbops = fbops;
793 info->fbdefio = fbdefio;
794
795 fbops->owner = dev->driver->owner;
796 fbops->fb_read = fb_sys_read;
797 fbops->fb_write = fbtft_fb_write;
798 fbops->fb_fillrect = fbtft_fb_fillrect;
799 fbops->fb_copyarea = fbtft_fb_copyarea;
800 fbops->fb_imageblit = fbtft_fb_imageblit;
801 fbops->fb_setcolreg = fbtft_fb_setcolreg;
802 fbops->fb_blank = fbtft_fb_blank;
803
804 fbdefio->delay = HZ/fps;
805 fbdefio->deferred_io = fbtft_deferred_io;
806 fb_deferred_io_init(info);
807
808 strncpy(info->fix.id, dev->driver->name, 16);
809 info->fix.type = FB_TYPE_PACKED_PIXELS;
810 info->fix.visual = FB_VISUAL_TRUECOLOR;
811 info->fix.xpanstep = 0;
812 info->fix.ypanstep = 0;
813 info->fix.ywrapstep = 0;
814 info->fix.line_length = width*bpp/8;
815 info->fix.accel = FB_ACCEL_NONE;
816 info->fix.smem_len = vmem_size;
817
818 info->var.rotate = pdata->rotate;
819 info->var.xres = width;
820 info->var.yres = height;
821 info->var.xres_virtual = info->var.xres;
822 info->var.yres_virtual = info->var.yres;
823 info->var.bits_per_pixel = bpp;
824 info->var.nonstd = 1;
825
826 /* RGB565 */
827 info->var.red.offset = 11;
828 info->var.red.length = 5;
829 info->var.green.offset = 5;
830 info->var.green.length = 6;
831 info->var.blue.offset = 0;
832 info->var.blue.length = 5;
833 info->var.transp.offset = 0;
834 info->var.transp.length = 0;
835
836 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
837
838 par = info->par;
839 par->info = info;
840 par->pdata = dev->platform_data;
841 par->debug = display->debug;
842 par->buf = buf;
843 spin_lock_init(&par->dirty_lock);
844 par->bgr = pdata->bgr;
845 par->startbyte = pdata->startbyte;
846 par->init_sequence = init_sequence;
847 par->gamma.curves = gamma_curves;
848 par->gamma.num_curves = display->gamma_num;
849 par->gamma.num_values = display->gamma_len;
850 mutex_init(&par->gamma.lock);
851 info->pseudo_palette = par->pseudo_palette;
852
853 if (par->gamma.curves && gamma) {
854 if (fbtft_gamma_parse_str(par,
855 par->gamma.curves, gamma, strlen(gamma)))
856 goto alloc_fail;
857 }
858
859 /* Transmit buffer */
860 if (txbuflen == -1)
861 txbuflen = vmem_size + 2; /* add in case startbyte is used */
862
863#ifdef __LITTLE_ENDIAN
864 if ((!txbuflen) && (bpp > 8))
865 txbuflen = PAGE_SIZE; /* need buffer for byteswapping */
866#endif
867
868 if (txbuflen > 0) {
869 if (dma) {
870 dev->coherent_dma_mask = ~0;
871 txbuf = dmam_alloc_coherent(dev, txbuflen, &par->txbuf.dma, GFP_DMA);
872 } else {
873 txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL);
874 }
875 if (!txbuf)
876 goto alloc_fail;
877 par->txbuf.buf = txbuf;
878 par->txbuf.len = txbuflen;
879 }
880
881 /* Initialize gpios to disabled */
882 par->gpio.reset = -1;
883 par->gpio.dc = -1;
884 par->gpio.rd = -1;
885 par->gpio.wr = -1;
886 par->gpio.cs = -1;
887 par->gpio.latch = -1;
888 for (i = 0; i < 16; i++) {
889 par->gpio.db[i] = -1;
890 par->gpio.led[i] = -1;
891 par->gpio.aux[i] = -1;
892 }
893
894 /* default fbtft operations */
895 par->fbtftops.write = fbtft_write_spi;
896 par->fbtftops.read = fbtft_read_spi;
897 par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
898 par->fbtftops.write_register = fbtft_write_reg8_bus8;
899 par->fbtftops.set_addr_win = fbtft_set_addr_win;
900 par->fbtftops.reset = fbtft_reset;
901 par->fbtftops.mkdirty = fbtft_mkdirty;
902 par->fbtftops.update_display = fbtft_update_display;
903 par->fbtftops.request_gpios = fbtft_request_gpios;
904 if (display->backlight)
905 par->fbtftops.register_backlight = fbtft_register_backlight;
906
907 /* use driver provided functions */
908 fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops);
909
910 return info;
911
912alloc_fail:
913 vfree(vmem);
914
915 return NULL;
916}
917EXPORT_SYMBOL(fbtft_framebuffer_alloc);
918
919/**
920 * fbtft_framebuffer_release - frees up all memory used by the framebuffer
921 *
922 * @info: frame buffer info structure
923 *
924 */
925void fbtft_framebuffer_release(struct fb_info *info)
926{
927 fb_deferred_io_cleanup(info);
928 vfree(info->screen_base);
929 framebuffer_release(info);
930}
931EXPORT_SYMBOL(fbtft_framebuffer_release);
932
933/**
934 * fbtft_register_framebuffer - registers a tft frame buffer device
935 * @fb_info: frame buffer info structure
936 *
937 * Sets SPI driverdata if needed
938 * Requests needed gpios.
939 * Initializes display
940 * Updates display.
941 * Registers a frame buffer device @fb_info.
942 *
943 * Returns negative errno on error, or zero for success.
944 *
945 */
946int fbtft_register_framebuffer(struct fb_info *fb_info)
947{
948 int ret;
949 char text1[50] = "";
950 char text2[50] = "";
951 struct fbtft_par *par = fb_info->par;
952 struct spi_device *spi = par->spi;
953
954 /* sanity checks */
955 if (!par->fbtftops.init_display) {
956 dev_err(fb_info->device, "missing fbtftops.init_display()\n");
957 return -EINVAL;
958 }
959
960 if (spi)
961 spi_set_drvdata(spi, fb_info);
962 if (par->pdev)
963 platform_set_drvdata(par->pdev, fb_info);
964
965 ret = par->fbtftops.request_gpios(par);
966 if (ret < 0)
967 goto reg_fail;
968
969 if (par->fbtftops.verify_gpios) {
970 ret = par->fbtftops.verify_gpios(par);
971 if (ret < 0)
972 goto reg_fail;
973 }
974
975 ret = par->fbtftops.init_display(par);
976 if (ret < 0)
977 goto reg_fail;
978 if (par->fbtftops.set_var) {
979 ret = par->fbtftops.set_var(par);
980 if (ret < 0)
981 goto reg_fail;
982 }
983
984 /* update the entire display */
985 par->fbtftops.update_display(par, 0, par->info->var.yres - 1);
986
987 if (par->fbtftops.set_gamma && par->gamma.curves) {
988 ret = par->fbtftops.set_gamma(par, par->gamma.curves);
989 if (ret)
990 goto reg_fail;
991 }
992
993 if (par->fbtftops.register_backlight)
994 par->fbtftops.register_backlight(par);
995
996 ret = register_framebuffer(fb_info);
997 if (ret < 0)
998 goto reg_fail;
999
1000 fbtft_sysfs_init(par);
1001
1002 if (par->txbuf.buf)
1003 sprintf(text1, ", %d KiB %sbuffer memory",
1004 par->txbuf.len >> 10, par->txbuf.dma ? "DMA " : "");
1005 if (spi)
1006 sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
1007 spi->chip_select, spi->max_speed_hz/1000000);
1008 dev_info(fb_info->dev,
1009 "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
1010 fb_info->fix.id, fb_info->var.xres, fb_info->var.yres,
1011 fb_info->fix.smem_len >> 10, text1,
1012 HZ/fb_info->fbdefio->delay, text2);
1013
1014#ifdef CONFIG_FB_BACKLIGHT
1015 /* Turn on backlight if available */
1016 if (fb_info->bl_dev) {
1017 fb_info->bl_dev->props.power = FB_BLANK_UNBLANK;
1018 fb_info->bl_dev->ops->update_status(fb_info->bl_dev);
1019 }
1020#endif
1021
1022 return 0;
1023
1024reg_fail:
1025 if (par->fbtftops.unregister_backlight)
1026 par->fbtftops.unregister_backlight(par);
1027 if (spi)
1028 spi_set_drvdata(spi, NULL);
1029 if (par->pdev)
1030 platform_set_drvdata(par->pdev, NULL);
1031
1032 return ret;
1033}
1034EXPORT_SYMBOL(fbtft_register_framebuffer);
1035
1036/**
1037 * fbtft_unregister_framebuffer - releases a tft frame buffer device
1038 * @fb_info: frame buffer info structure
1039 *
1040 * Frees SPI driverdata if needed
1041 * Frees gpios.
1042 * Unregisters frame buffer device.
1043 *
1044 */
1045int fbtft_unregister_framebuffer(struct fb_info *fb_info)
1046{
1047 struct fbtft_par *par = fb_info->par;
1048 struct spi_device *spi = par->spi;
1049 int ret;
1050
1051 if (spi)
1052 spi_set_drvdata(spi, NULL);
1053 if (par->pdev)
1054 platform_set_drvdata(par->pdev, NULL);
1055 if (par->fbtftops.unregister_backlight)
1056 par->fbtftops.unregister_backlight(par);
1057 fbtft_sysfs_exit(par);
1058 ret = unregister_framebuffer(fb_info);
1059 return ret;
1060}
1061EXPORT_SYMBOL(fbtft_unregister_framebuffer);
1062
1063#ifdef CONFIG_OF
1064/**
1065 * fbtft_init_display_dt() - Device Tree init_display() function
1066 * @par: Driver data
1067 *
1068 * Return: 0 if successful, negative if error
1069 */
1070static int fbtft_init_display_dt(struct fbtft_par *par)
1071{
1072 struct device_node *node = par->info->device->of_node;
1073 struct property *prop;
1074 const __be32 *p;
1075 u32 val;
1076 int buf[64], i, j;
1077 char msg[128];
1078 char str[16];
1079
1080 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
1081
1082 if (!node)
1083 return -EINVAL;
1084
1085 prop = of_find_property(node, "init", NULL);
1086 p = of_prop_next_u32(prop, NULL, &val);
1087 if (!p)
1088 return -EINVAL;
1089 while (p) {
1090 if (val & FBTFT_OF_INIT_CMD) {
1091 val &= 0xFFFF;
1092 i = 0;
1093 while (p && !(val & 0xFFFF0000)) {
1094 if (i > 63) {
1095 dev_err(par->info->device,
1096 "%s: Maximum register values exceeded\n",
1097 __func__);
1098 return -EINVAL;
1099 }
1100 buf[i++] = val;
1101 p = of_prop_next_u32(prop, p, &val);
1102 }
1103 /* make debug message */
1104 msg[0] = '\0';
1105 for (j = 0; j < i; j++) {
1106 snprintf(str, 128, " %02X", buf[j]);
1107 strcat(msg, str);
1108 }
1109 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
1110 "init: write_register:%s\n", msg);
1111
1112 par->fbtftops.write_register(par, i,
1113 buf[0], buf[1], buf[2], buf[3],
1114 buf[4], buf[5], buf[6], buf[7],
1115 buf[8], buf[9], buf[10], buf[11],
1116 buf[12], buf[13], buf[14], buf[15],
1117 buf[16], buf[17], buf[18], buf[19],
1118 buf[20], buf[21], buf[22], buf[23],
1119 buf[24], buf[25], buf[26], buf[27],
1120 buf[28], buf[29], buf[30], buf[31],
1121 buf[32], buf[33], buf[34], buf[35],
1122 buf[36], buf[37], buf[38], buf[39],
1123 buf[40], buf[41], buf[42], buf[43],
1124 buf[44], buf[45], buf[46], buf[47],
1125 buf[48], buf[49], buf[50], buf[51],
1126 buf[52], buf[53], buf[54], buf[55],
1127 buf[56], buf[57], buf[58], buf[59],
1128 buf[60], buf[61], buf[62], buf[63]);
1129 } else if (val & FBTFT_OF_INIT_DELAY) {
1130 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
1131 "init: msleep(%u)\n", val & 0xFFFF);
1132 msleep(val & 0xFFFF);
1133 p = of_prop_next_u32(prop, p, &val);
1134 } else {
1135 dev_err(par->info->device, "illegal init value 0x%X\n",
1136 val);
1137 return -EINVAL;
1138 }
1139 }
1140
1141 return 0;
1142}
1143#endif
1144
1145/**
1146 * fbtft_init_display() - Generic init_display() function
1147 * @par: Driver data
1148 *
1149 * Uses par->init_sequence to do the initialization
1150 *
1151 * Return: 0 if successful, negative if error
1152 */
1153int fbtft_init_display(struct fbtft_par *par)
1154{
1155 int buf[64];
1156 char msg[128];
1157 char str[16];
1158 int i = 0;
1159 int j;
1160
1161 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
1162
1163 /* sanity check */
1164 if (!par->init_sequence) {
1165 dev_err(par->info->device,
1166 "error: init_sequence is not set\n");
1167 return -EINVAL;
1168 }
1169
1170 /* make sure stop marker exists */
1171 for (i = 0; i < FBTFT_MAX_INIT_SEQUENCE; i++)
1172 if (par->init_sequence[i] == -3)
1173 break;
1174 if (i == FBTFT_MAX_INIT_SEQUENCE) {
1175 dev_err(par->info->device,
1176 "missing stop marker at end of init sequence\n");
1177 return -EINVAL;
1178 }
1179
1180 par->fbtftops.reset(par);
1181 if (par->gpio.cs != -1)
1182 gpio_set_value(par->gpio.cs, 0); /* Activate chip */
1183
1184 i = 0;
1185 while (i < FBTFT_MAX_INIT_SEQUENCE) {
1186 if (par->init_sequence[i] == -3) {
1187 /* done */
1188 return 0;
1189 }
1190 if (par->init_sequence[i] >= 0) {
1191 dev_err(par->info->device,
1192 "missing delimiter at position %d\n", i);
1193 return -EINVAL;
1194 }
1195 if (par->init_sequence[i+1] < 0) {
1196 dev_err(par->info->device,
1197 "missing value after delimiter %d at position %d\n",
1198 par->init_sequence[i], i);
1199 return -EINVAL;
1200 }
1201 switch (par->init_sequence[i]) {
1202 case -1:
1203 i++;
1204 /* make debug message */
1205 strcpy(msg, "");
1206 j = i + 1;
1207 while (par->init_sequence[j] >= 0) {
1208 sprintf(str, "0x%02X ", par->init_sequence[j]);
1209 strcat(msg, str);
1210 j++;
1211 }
1212 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
1213 "init: write(0x%02X) %s\n",
1214 par->init_sequence[i], msg);
1215
1216 /* Write */
1217 j = 0;
1218 while (par->init_sequence[i] >= 0) {
1219 if (j > 63) {
1220 dev_err(par->info->device,
1221 "%s: Maximum register values exceeded\n",
1222 __func__);
1223 return -EINVAL;
1224 }
1225 buf[j++] = par->init_sequence[i++];
1226 }
1227 par->fbtftops.write_register(par, j,
1228 buf[0], buf[1], buf[2], buf[3],
1229 buf[4], buf[5], buf[6], buf[7],
1230 buf[8], buf[9], buf[10], buf[11],
1231 buf[12], buf[13], buf[14], buf[15],
1232 buf[16], buf[17], buf[18], buf[19],
1233 buf[20], buf[21], buf[22], buf[23],
1234 buf[24], buf[25], buf[26], buf[27],
1235 buf[28], buf[29], buf[30], buf[31],
1236 buf[32], buf[33], buf[34], buf[35],
1237 buf[36], buf[37], buf[38], buf[39],
1238 buf[40], buf[41], buf[42], buf[43],
1239 buf[44], buf[45], buf[46], buf[47],
1240 buf[48], buf[49], buf[50], buf[51],
1241 buf[52], buf[53], buf[54], buf[55],
1242 buf[56], buf[57], buf[58], buf[59],
1243 buf[60], buf[61], buf[62], buf[63]);
1244 break;
1245 case -2:
1246 i++;
1247 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
1248 "init: mdelay(%d)\n", par->init_sequence[i]);
1249 mdelay(par->init_sequence[i++]);
1250 break;
1251 default:
1252 dev_err(par->info->device,
1253 "unknown delimiter %d at position %d\n",
1254 par->init_sequence[i], i);
1255 return -EINVAL;
1256 }
1257 }
1258
1259 dev_err(par->info->device,
1260 "%s: something is wrong. Shouldn't get here.\n", __func__);
1261 return -EINVAL;
1262}
1263EXPORT_SYMBOL(fbtft_init_display);
1264
1265/**
1266 * fbtft_verify_gpios() - Generic verify_gpios() function
1267 * @par: Driver data
1268 *
1269 * Uses @spi, @pdev and @buswidth to determine which GPIOs is needed
1270 *
1271 * Return: 0 if successful, negative if error
1272 */
1273static int fbtft_verify_gpios(struct fbtft_par *par)
1274{
1275 struct fbtft_platform_data *pdata;
1276 int i;
1277
1278 fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
1279
1280 pdata = par->info->device->platform_data;
1281 if (pdata->display.buswidth != 9 && par->startbyte == 0 && \
1282 par->gpio.dc < 0) {
1283 dev_err(par->info->device,
1284 "Missing info about 'dc' gpio. Aborting.\n");
1285 return -EINVAL;
1286 }
1287
1288 if (!par->pdev)
1289 return 0;
1290
1291 if (par->gpio.wr < 0) {
1292 dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n");
1293 return -EINVAL;
1294 }
1295 for (i = 0; i < pdata->display.buswidth; i++) {
1296 if (par->gpio.db[i] < 0) {
1297 dev_err(par->info->device,
1298 "Missing 'db%02d' gpio. Aborting.\n", i);
1299 return -EINVAL;
1300 }
1301 }
1302
1303 return 0;
1304}
1305
1306#ifdef CONFIG_OF
1307/* returns 0 if the property is not present */
1308static u32 fbtft_of_value(struct device_node *node, const char *propname)
1309{
1310 int ret;
1311 u32 val = 0;
1312
1313 ret = of_property_read_u32(node, propname, &val);
1314 if (ret == 0)
1315 pr_info("%s: %s = %u\n", __func__, propname, val);
1316
1317 return val;
1318}
1319
1320static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
1321{
1322 struct device_node *node = dev->of_node;
1323 struct fbtft_platform_data *pdata;
1324
1325 if (!node) {
1326 dev_err(dev, "Missing platform data or DT\n");
1327 return ERR_PTR(-EINVAL);
1328 }
1329
1330 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1331 if (!pdata)
1332 return ERR_PTR(-ENOMEM);
1333
1334 pdata->display.width = fbtft_of_value(node, "width");
1335 pdata->display.height = fbtft_of_value(node, "height");
1336 pdata->display.regwidth = fbtft_of_value(node, "regwidth");
1337 pdata->display.buswidth = fbtft_of_value(node, "buswidth");
1338 pdata->display.backlight = fbtft_of_value(node, "backlight");
1339 pdata->display.bpp = fbtft_of_value(node, "bpp");
1340 pdata->display.debug = fbtft_of_value(node, "debug");
1341 pdata->rotate = fbtft_of_value(node, "rotate");
1342 pdata->bgr = of_property_read_bool(node, "bgr");
1343 pdata->fps = fbtft_of_value(node, "fps");
1344 pdata->txbuflen = fbtft_of_value(node, "txbuflen");
1345 pdata->startbyte = fbtft_of_value(node, "startbyte");
1346 of_property_read_string(node, "gamma", (const char **)&pdata->gamma);
1347
1348 if (of_find_property(node, "led-gpios", NULL))
1349 pdata->display.backlight = 1;
1350 if (of_find_property(node, "init", NULL))
1351 pdata->display.fbtftops.init_display = fbtft_init_display_dt;
1352 pdata->display.fbtftops.request_gpios = fbtft_request_gpios_dt;
1353
1354 return pdata;
1355}
1356#else
1357static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
1358{
1359 dev_err(dev, "Missing platform data\n");
1360 return ERR_PTR(-EINVAL);
1361}
1362#endif
1363
1364/**
1365 * fbtft_probe_common() - Generic device probe() helper function
1366 * @display: Display properties
1367 * @sdev: SPI device
1368 * @pdev: Platform device
1369 *
1370 * Allocates, initializes and registers a framebuffer
1371 *
1372 * Either @sdev or @pdev should be NULL
1373 *
1374 * Return: 0 if successful, negative if error
1375 */
1376int fbtft_probe_common(struct fbtft_display *display,
1377 struct spi_device *sdev, struct platform_device *pdev)
1378{
1379 struct device *dev;
1380 struct fb_info *info;
1381 struct fbtft_par *par;
1382 struct fbtft_platform_data *pdata;
1383 int ret;
1384
1385 if (sdev)
1386 dev = &sdev->dev;
1387 else
1388 dev = &pdev->dev;
1389
1390 if (unlikely(display->debug & DEBUG_DRIVER_INIT_FUNCTIONS))
1391 dev_info(dev, "%s()\n", __func__);
1392
1393 pdata = dev->platform_data;
1394 if (!pdata) {
1395 pdata = fbtft_probe_dt(dev);
1396 if (IS_ERR(pdata))
1397 return PTR_ERR(pdata);
1398 dev->platform_data = pdata;
1399 }
1400
1401 info = fbtft_framebuffer_alloc(display, dev);
1402 if (!info)
1403 return -ENOMEM;
1404
1405 par = info->par;
1406 par->spi = sdev;
1407 par->pdev = pdev;
1408
1409 if (display->buswidth == 0) {
1410 dev_err(dev, "buswidth is not set\n");
1411 return -EINVAL;
1412 }
1413
1414 /* write register functions */
1415 if (display->regwidth == 8 && display->buswidth == 8) {
1416 par->fbtftops.write_register = fbtft_write_reg8_bus8;
1417 } else
1418 if (display->regwidth == 8 && display->buswidth == 9 && par->spi) {
1419 par->fbtftops.write_register = fbtft_write_reg8_bus9;
1420 } else if (display->regwidth == 16 && display->buswidth == 8) {
1421 par->fbtftops.write_register = fbtft_write_reg16_bus8;
1422 } else if (display->regwidth == 16 && display->buswidth == 16) {
1423 par->fbtftops.write_register = fbtft_write_reg16_bus16;
1424 } else {
1425 dev_warn(dev,
1426 "no default functions for regwidth=%d and buswidth=%d\n",
1427 display->regwidth, display->buswidth);
1428 }
1429
1430 /* write_vmem() functions */
1431 if (display->buswidth == 8)
1432 par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
1433 else if (display->buswidth == 9)
1434 par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
1435 else if (display->buswidth == 16)
1436 par->fbtftops.write_vmem = fbtft_write_vmem16_bus16;
1437
1438 /* GPIO write() functions */
1439 if (par->pdev) {
1440 if (display->buswidth == 8)
1441 par->fbtftops.write = fbtft_write_gpio8_wr;
1442 else if (display->buswidth == 16)
1443 par->fbtftops.write = fbtft_write_gpio16_wr;
1444 }
1445
1446 /* 9-bit SPI setup */
1447 if (par->spi && display->buswidth == 9) {
1448 par->spi->bits_per_word = 9;
1449 ret = par->spi->master->setup(par->spi);
1450 if (ret) {
1451 dev_warn(&par->spi->dev,
1452 "9-bit SPI not available, emulating using 8-bit.\n");
1453 par->spi->bits_per_word = 8;
1454 ret = par->spi->master->setup(par->spi);
1455 if (ret)
1456 goto out_release;
1457 /* allocate buffer with room for dc bits */
1458 par->extra = devm_kzalloc(par->info->device,
1459 par->txbuf.len + (par->txbuf.len / 8) + 8,
1460 GFP_KERNEL);
1461 if (!par->extra) {
1462 ret = -ENOMEM;
1463 goto out_release;
1464 }
1465 par->fbtftops.write = fbtft_write_spi_emulate_9;
1466 }
1467 }
1468
1469 if (!par->fbtftops.verify_gpios)
1470 par->fbtftops.verify_gpios = fbtft_verify_gpios;
1471
1472 /* make sure we still use the driver provided functions */
1473 fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops);
1474
1475 /* use init_sequence if provided */
1476 if (par->init_sequence)
1477 par->fbtftops.init_display = fbtft_init_display;
1478
1479 /* use platform_data provided functions above all */
1480 fbtft_merge_fbtftops(&par->fbtftops, &pdata->display.fbtftops);
1481
1482 ret = fbtft_register_framebuffer(info);
1483 if (ret < 0)
1484 goto out_release;
1485
1486 return 0;
1487
1488out_release:
1489 fbtft_framebuffer_release(info);
1490
1491 return ret;
1492}
1493EXPORT_SYMBOL(fbtft_probe_common);
1494
1495/**
1496 * fbtft_remove_common() - Generic device remove() helper function
1497 * @dev: Device
1498 * @info: Framebuffer
1499 *
1500 * Unregisters and releases the framebuffer
1501 *
1502 * Return: 0 if successful, negative if error
1503 */
1504int fbtft_remove_common(struct device *dev, struct fb_info *info)
1505{
1506 struct fbtft_par *par;
1507
1508 if (!info)
1509 return -EINVAL;
1510 par = info->par;
1511 if (par)
1512 fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par,
1513 "%s()\n", __func__);
1514 fbtft_unregister_framebuffer(info);
1515 fbtft_framebuffer_release(info);
1516
1517 return 0;
1518}
1519EXPORT_SYMBOL(fbtft_remove_common);
1520
1521MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c
new file mode 100644
index 000000000000..32155a7b2a62
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-io.c
@@ -0,0 +1,239 @@
1#include <linux/export.h>
2#include <linux/errno.h>
3#include <linux/gpio.h>
4#include <linux/spi/spi.h>
5#include "fbtft.h"
6
7int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
8{
9 struct spi_transfer t = {
10 .tx_buf = buf,
11 .len = len,
12 };
13 struct spi_message m;
14
15 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
16 "%s(len=%d): ", __func__, len);
17
18 if (!par->spi) {
19 dev_err(par->info->device,
20 "%s: par->spi is unexpectedly NULL\n", __func__);
21 return -1;
22 }
23
24 spi_message_init(&m);
25 if (par->txbuf.dma && buf == par->txbuf.buf) {
26 t.tx_dma = par->txbuf.dma;
27 m.is_dma_mapped = 1;
28 }
29 spi_message_add_tail(&t, &m);
30 return spi_sync(par->spi, &m);
31}
32EXPORT_SYMBOL(fbtft_write_spi);
33
34/**
35 * fbtft_write_spi_emulate_9() - write SPI emulating 9-bit
36 * @par: Driver data
37 * @buf: Buffer to write
38 * @len: Length of buffer (must be divisible by 8)
39 *
40 * When 9-bit SPI is not available, this function can be used to emulate that.
41 * par->extra must hold a transformation buffer used for transfer.
42 */
43int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len)
44{
45 u16 *src = buf;
46 u8 *dst = par->extra;
47 size_t size = len / 2;
48 size_t added = 0;
49 int bits, i, j;
50 u64 val, dc, tmp;
51
52 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
53 "%s(len=%d): ", __func__, len);
54
55 if (!par->extra) {
56 dev_err(par->info->device, "%s: error: par->extra is NULL\n",
57 __func__);
58 return -EINVAL;
59 }
60 if ((len % 8) != 0) {
61 dev_err(par->info->device,
62 "%s: error: len=%d must be divisible by 8\n",
63 __func__, len);
64 return -EINVAL;
65 }
66
67 for (i = 0; i < size; i += 8) {
68 tmp = 0;
69 bits = 63;
70 for (j = 0; j < 7; j++) {
71 dc = (*src & 0x0100) ? 1 : 0;
72 val = *src & 0x00FF;
73 tmp |= dc << bits;
74 bits -= 8;
75 tmp |= val << bits--;
76 src++;
77 }
78 tmp |= ((*src & 0x0100) ? 1 : 0);
79 *(u64 *)dst = cpu_to_be64(tmp);
80 dst += 8;
81 *dst++ = (u8)(*src++ & 0x00FF);
82 added++;
83 }
84
85 return spi_write(par->spi, par->extra, size + added);
86}
87EXPORT_SYMBOL(fbtft_write_spi_emulate_9);
88
89int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len)
90{
91 int ret;
92 u8 txbuf[32] = { 0, };
93 struct spi_transfer t = {
94 .speed_hz = 2000000,
95 .rx_buf = buf,
96 .len = len,
97 };
98 struct spi_message m;
99
100 if (!par->spi) {
101 dev_err(par->info->device,
102 "%s: par->spi is unexpectedly NULL\n", __func__);
103 return -ENODEV;
104 }
105
106 if (par->startbyte) {
107 if (len > 32) {
108 dev_err(par->info->device,
109 "%s: len=%d can't be larger than 32 when using 'startbyte'\n",
110 __func__, len);
111 return -EINVAL;
112 }
113 txbuf[0] = par->startbyte | 0x3;
114 t.tx_buf = txbuf;
115 fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8,
116 txbuf, len, "%s(len=%d) txbuf => ", __func__, len);
117 }
118
119 spi_message_init(&m);
120 spi_message_add_tail(&t, &m);
121 ret = spi_sync(par->spi, &m);
122 fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8, buf, len,
123 "%s(len=%d) buf <= ", __func__, len);
124
125 return ret;
126}
127EXPORT_SYMBOL(fbtft_read_spi);
128
129/*
130 * Optimized use of gpiolib is twice as fast as no optimization
131 * only one driver can use the optimized version at a time
132 */
133int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
134{
135 u8 data;
136 int i;
137#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
138 static u8 prev_data;
139#endif
140
141 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
142 "%s(len=%d): ", __func__, len);
143
144 while (len--) {
145 data = *(u8 *) buf;
146
147 /* Start writing by pulling down /WR */
148 gpio_set_value(par->gpio.wr, 0);
149
150 /* Set data */
151#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
152 if (data == prev_data) {
153 gpio_set_value(par->gpio.wr, 0); /* used as delay */
154 } else {
155 for (i = 0; i < 8; i++) {
156 if ((data & 1) != (prev_data & 1))
157 gpio_set_value(par->gpio.db[i],
158 (data & 1));
159 data >>= 1;
160 prev_data >>= 1;
161 }
162 }
163#else
164 for (i = 0; i < 8; i++) {
165 gpio_set_value(par->gpio.db[i], (data & 1));
166 data >>= 1;
167 }
168#endif
169
170 /* Pullup /WR */
171 gpio_set_value(par->gpio.wr, 1);
172
173#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
174 prev_data = *(u8 *) buf;
175#endif
176 buf++;
177 }
178
179 return 0;
180}
181EXPORT_SYMBOL(fbtft_write_gpio8_wr);
182
183int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
184{
185 u16 data;
186 int i;
187#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
188 static u16 prev_data;
189#endif
190
191 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
192 "%s(len=%d): ", __func__, len);
193
194 while (len) {
195 data = *(u16 *) buf;
196
197 /* Start writing by pulling down /WR */
198 gpio_set_value(par->gpio.wr, 0);
199
200 /* Set data */
201#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
202 if (data == prev_data) {
203 gpio_set_value(par->gpio.wr, 0); /* used as delay */
204 } else {
205 for (i = 0; i < 16; i++) {
206 if ((data & 1) != (prev_data & 1))
207 gpio_set_value(par->gpio.db[i],
208 (data & 1));
209 data >>= 1;
210 prev_data >>= 1;
211 }
212 }
213#else
214 for (i = 0; i < 16; i++) {
215 gpio_set_value(par->gpio.db[i], (data & 1));
216 data >>= 1;
217 }
218#endif
219
220 /* Pullup /WR */
221 gpio_set_value(par->gpio.wr, 1);
222
223#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
224 prev_data = *(u16 *) buf;
225#endif
226 buf += 2;
227 len -= 2;
228 }
229
230 return 0;
231}
232EXPORT_SYMBOL(fbtft_write_gpio16_wr);
233
234int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len)
235{
236 dev_err(par->info->device, "%s: function not implemented\n", __func__);
237 return -1;
238}
239EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);
diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c
new file mode 100644
index 000000000000..45f8de3d11ad
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
@@ -0,0 +1,222 @@
1#include "fbtft.h"
2
3
4static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base)
5{
6 char *p_val;
7 int ret;
8
9 if (!str_p || !(*str_p))
10 return -EINVAL;
11
12 p_val = strsep(str_p, sep);
13
14 if (!p_val)
15 return -EINVAL;
16
17 ret = kstrtoul(p_val, base, val);
18 if (ret)
19 return -EINVAL;
20
21 return 0;
22}
23
24int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves,
25 const char *str, int size)
26{
27 char *str_p, *curve_p = NULL;
28 char *tmp;
29 unsigned long val = 0;
30 int ret = 0;
31 int curve_counter, value_counter;
32
33 fbtft_par_dbg(DEBUG_SYSFS, par, "%s() str=\n", __func__);
34
35 if (!str || !curves)
36 return -EINVAL;
37
38 fbtft_par_dbg(DEBUG_SYSFS, par, "%s\n", str);
39
40 tmp = kmalloc(size+1, GFP_KERNEL);
41 if (!tmp)
42 return -ENOMEM;
43 memcpy(tmp, str, size+1);
44
45 /* replace optional separators */
46 str_p = tmp;
47 while (*str_p) {
48 if (*str_p == ',')
49 *str_p = ' ';
50 if (*str_p == ';')
51 *str_p = '\n';
52 str_p++;
53 }
54
55 str_p = strim(tmp);
56
57 curve_counter = 0;
58 while (str_p) {
59 if (curve_counter == par->gamma.num_curves) {
60 dev_err(par->info->device, "Gamma: Too many curves\n");
61 ret = -EINVAL;
62 goto out;
63 }
64 curve_p = strsep(&str_p, "\n");
65 value_counter = 0;
66 while (curve_p) {
67 if (value_counter == par->gamma.num_values) {
68 dev_err(par->info->device,
69 "Gamma: Too many values\n");
70 ret = -EINVAL;
71 goto out;
72 }
73 ret = get_next_ulong(&curve_p, &val, " ", 16);
74 if (ret)
75 goto out;
76 curves[curve_counter * par->gamma.num_values + value_counter] = val;
77 value_counter++;
78 }
79 if (value_counter != par->gamma.num_values) {
80 dev_err(par->info->device, "Gamma: Too few values\n");
81 ret = -EINVAL;
82 goto out;
83 }
84 curve_counter++;
85 }
86 if (curve_counter != par->gamma.num_curves) {
87 dev_err(par->info->device, "Gamma: Too few curves\n");
88 ret = -EINVAL;
89 goto out;
90 }
91
92out:
93 kfree(tmp);
94 return ret;
95}
96
97static ssize_t
98sprintf_gamma(struct fbtft_par *par, unsigned long *curves, char *buf)
99{
100 ssize_t len = 0;
101 unsigned int i, j;
102
103 mutex_lock(&par->gamma.lock);
104 for (i = 0; i < par->gamma.num_curves; i++) {
105 for (j = 0; j < par->gamma.num_values; j++)
106 len += scnprintf(&buf[len], PAGE_SIZE,
107 "%04lx ", curves[i*par->gamma.num_values + j]);
108 buf[len-1] = '\n';
109 }
110 mutex_unlock(&par->gamma.lock);
111
112 return len;
113}
114
115static ssize_t store_gamma_curve(struct device *device,
116 struct device_attribute *attr,
117 const char *buf, size_t count)
118{
119 struct fb_info *fb_info = dev_get_drvdata(device);
120 struct fbtft_par *par = fb_info->par;
121 unsigned long tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL];
122 int ret;
123
124 ret = fbtft_gamma_parse_str(par, tmp_curves, buf, count);
125 if (ret)
126 return ret;
127
128 ret = par->fbtftops.set_gamma(par, tmp_curves);
129 if (ret)
130 return ret;
131
132 mutex_lock(&par->gamma.lock);
133 memcpy(par->gamma.curves, tmp_curves,
134 par->gamma.num_curves * par->gamma.num_values * sizeof(tmp_curves[0]));
135 mutex_unlock(&par->gamma.lock);
136
137 return count;
138}
139
140static ssize_t show_gamma_curve(struct device *device,
141 struct device_attribute *attr, char *buf)
142{
143 struct fb_info *fb_info = dev_get_drvdata(device);
144 struct fbtft_par *par = fb_info->par;
145
146 return sprintf_gamma(par, par->gamma.curves, buf);
147}
148
149static struct device_attribute gamma_device_attrs[] = {
150 __ATTR(gamma, 0660, show_gamma_curve, store_gamma_curve),
151};
152
153
154void fbtft_expand_debug_value(unsigned long *debug)
155{
156 switch (*debug & 0b111) {
157 case 1:
158 *debug |= DEBUG_LEVEL_1;
159 break;
160 case 2:
161 *debug |= DEBUG_LEVEL_2;
162 break;
163 case 3:
164 *debug |= DEBUG_LEVEL_3;
165 break;
166 case 4:
167 *debug |= DEBUG_LEVEL_4;
168 break;
169 case 5:
170 *debug |= DEBUG_LEVEL_5;
171 break;
172 case 6:
173 *debug |= DEBUG_LEVEL_6;
174 break;
175 case 7:
176 *debug = 0xFFFFFFFF;
177 break;
178 }
179}
180
181static ssize_t store_debug(struct device *device,
182 struct device_attribute *attr,
183 const char *buf, size_t count)
184{
185 struct fb_info *fb_info = dev_get_drvdata(device);
186 struct fbtft_par *par = fb_info->par;
187 int ret;
188
189 ret = kstrtoul(buf, 10, &par->debug);
190 if (ret)
191 return ret;
192 fbtft_expand_debug_value(&par->debug);
193
194 return count;
195}
196
197static ssize_t show_debug(struct device *device,
198 struct device_attribute *attr, char *buf)
199{
200 struct fb_info *fb_info = dev_get_drvdata(device);
201 struct fbtft_par *par = fb_info->par;
202
203 return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug);
204}
205
206static struct device_attribute debug_device_attr = \
207 __ATTR(debug, 0660, show_debug, store_debug);
208
209
210void fbtft_sysfs_init(struct fbtft_par *par)
211{
212 device_create_file(par->info->dev, &debug_device_attr);
213 if (par->gamma.curves && par->fbtftops.set_gamma)
214 device_create_file(par->info->dev, &gamma_device_attrs[0]);
215}
216
217void fbtft_sysfs_exit(struct fbtft_par *par)
218{
219 device_remove_file(par->info->dev, &debug_device_attr);
220 if (par->gamma.curves && par->fbtftops.set_gamma)
221 device_remove_file(par->info->dev, &gamma_device_attrs[0]);
222}
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
new file mode 100644
index 000000000000..0dbf3f95fe78
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft.h
@@ -0,0 +1,447 @@
1/*
2 * Copyright (C) 2013 Noralf Tronnes
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#ifndef __LINUX_FBTFT_H
20#define __LINUX_FBTFT_H
21
22#include <linux/fb.h>
23#include <linux/spinlock.h>
24#include <linux/spi/spi.h>
25#include <linux/platform_device.h>
26
27
28#define FBTFT_NOP 0x00
29#define FBTFT_SWRESET 0x01
30#define FBTFT_RDDID 0x04
31#define FBTFT_RDDST 0x09
32#define FBTFT_CASET 0x2A
33#define FBTFT_RASET 0x2B
34#define FBTFT_RAMWR 0x2C
35
36#define FBTFT_ONBOARD_BACKLIGHT 2
37
38#define FBTFT_GPIO_NO_MATCH 0xFFFF
39#define FBTFT_GPIO_NAME_SIZE 32
40#define FBTFT_MAX_INIT_SEQUENCE 512
41#define FBTFT_GAMMA_MAX_VALUES_TOTAL 128
42
43#define FBTFT_OF_INIT_CMD BIT(24)
44#define FBTFT_OF_INIT_DELAY BIT(25)
45
46/**
47 * struct fbtft_gpio - Structure that holds one pinname to gpio mapping
48 * @name: pinname (reset, dc, etc.)
49 * @gpio: GPIO number
50 *
51 */
52struct fbtft_gpio {
53 char name[FBTFT_GPIO_NAME_SIZE];
54 unsigned gpio;
55};
56
57struct fbtft_par;
58
59/**
60 * struct fbtft_ops - FBTFT operations structure
61 * @write: Writes to interface bus
62 * @read: Reads from interface bus
63 * @write_vmem: Writes video memory to display
64 * @write_reg: Writes to controller register
65 * @set_addr_win: Set the GRAM update window
66 * @reset: Reset the LCD controller
67 * @mkdirty: Marks display lines for update
68 * @update_display: Updates the display
69 * @init_display: Initializes the display
70 * @blank: Blank the display (optional)
71 * @request_gpios_match: Do pinname to gpio matching
72 * @request_gpios: Request gpios from the kernel
73 * @free_gpios: Free previously requested gpios
74 * @verify_gpios: Verify that necessary gpios is present (optional)
75 * @register_backlight: Used to register backlight device (optional)
76 * @unregister_backlight: Unregister backlight device (optional)
77 * @set_var: Configure LCD with values from variables like @rotate and @bgr
78 * (optional)
79 * @set_gamma: Set Gamma curve (optional)
80 *
81 * Most of these operations have default functions assigned to them in
82 * fbtft_framebuffer_alloc()
83 */
84struct fbtft_ops {
85 int (*write)(struct fbtft_par *par, void *buf, size_t len);
86 int (*read)(struct fbtft_par *par, void *buf, size_t len);
87 int (*write_vmem)(struct fbtft_par *par, size_t offset, size_t len);
88 void (*write_register)(struct fbtft_par *par, int len, ...);
89
90 void (*set_addr_win)(struct fbtft_par *par,
91 int xs, int ys, int xe, int ye);
92 void (*reset)(struct fbtft_par *par);
93 void (*mkdirty)(struct fb_info *info, int from, int to);
94 void (*update_display)(struct fbtft_par *par,
95 unsigned start_line, unsigned end_line);
96 int (*init_display)(struct fbtft_par *par);
97 int (*blank)(struct fbtft_par *par, bool on);
98
99 unsigned long (*request_gpios_match)(struct fbtft_par *par,
100 const struct fbtft_gpio *gpio);
101 int (*request_gpios)(struct fbtft_par *par);
102 int (*verify_gpios)(struct fbtft_par *par);
103
104 void (*register_backlight)(struct fbtft_par *par);
105 void (*unregister_backlight)(struct fbtft_par *par);
106
107 int (*set_var)(struct fbtft_par *par);
108 int (*set_gamma)(struct fbtft_par *par, unsigned long *curves);
109};
110
111/**
112 * struct fbtft_display - Describes the display properties
113 * @width: Width of display in pixels
114 * @height: Height of display in pixels
115 * @regwidth: LCD Controller Register width in bits
116 * @buswidth: Display interface bus width in bits
117 * @backlight: Backlight type.
118 * @fbtftops: FBTFT operations provided by driver or device (platform_data)
119 * @bpp: Bits per pixel
120 * @fps: Frames per second
121 * @txbuflen: Size of transmit buffer
122 * @init_sequence: Pointer to LCD initialization array
123 * @gamma: String representation of Gamma curve(s)
124 * @gamma_num: Number of Gamma curves
125 * @gamma_len: Number of values per Gamma curve
126 * @debug: Initial debug value
127 *
128 * This structure is not stored by FBTFT except for init_sequence.
129 */
130struct fbtft_display {
131 unsigned width;
132 unsigned height;
133 unsigned regwidth;
134 unsigned buswidth;
135 unsigned backlight;
136 struct fbtft_ops fbtftops;
137 unsigned bpp;
138 unsigned fps;
139 int txbuflen;
140 int *init_sequence;
141 char *gamma;
142 int gamma_num;
143 int gamma_len;
144 unsigned long debug;
145};
146
147/**
148 * struct fbtft_platform_data - Passes display specific data to the driver
149 * @display: Display properties
150 * @gpios: Pointer to an array of piname to gpio mappings
151 * @rotate: Display rotation angle
152 * @bgr: LCD Controller BGR bit
153 * @fps: Frames per second (this will go away, use @fps in @fbtft_display)
154 * @txbuflen: Size of transmit buffer
155 * @startbyte: When set, enables use of Startbyte in transfers
156 * @gamma: String representation of Gamma curve(s)
157 * @extra: A way to pass extra info
158 */
159struct fbtft_platform_data {
160 struct fbtft_display display;
161 const struct fbtft_gpio *gpios;
162 unsigned rotate;
163 bool bgr;
164 unsigned fps;
165 int txbuflen;
166 u8 startbyte;
167 char *gamma;
168 void *extra;
169};
170
171/**
172 * struct fbtft_par - Main FBTFT data structure
173 *
174 * This structure holds all relevant data to operate the display
175 *
176 * See sourcefile for documentation since nested structs is not
177 * supported by kernel-doc.
178 *
179 */
180/* @spi: Set if it is a SPI device
181 * @pdev: Set if it is a platform device
182 * @info: Pointer to framebuffer fb_info structure
183 * @pdata: Pointer to platform data
184 * @ssbuf: Not used
185 * @pseudo_palette: Used by fb_set_colreg()
186 * @txbuf.buf: Transmit buffer
187 * @txbuf.len: Transmit buffer length
188 * @buf: Small buffer used when writing init data over SPI
189 * @startbyte: Used by some controllers when in SPI mode.
190 * Format: 6 bit Device id + RS bit + RW bit
191 * @fbtftops: FBTFT operations provided by driver or device (platform_data)
192 * @dirty_lock: Protects dirty_lines_start and dirty_lines_end
193 * @dirty_lines_start: Where to begin updating display
194 * @dirty_lines_end: Where to end updating display
195 * @gpio.reset: GPIO used to reset display
196 * @gpio.dc: Data/Command signal, also known as RS
197 * @gpio.rd: Read latching signal
198 * @gpio.wr: Write latching signal
199 * @gpio.latch: Bus latch signal, eg. 16->8 bit bus latch
200 * @gpio.cs: LCD Chip Select with parallel interface bus
201 * @gpio.db[16]: Parallel databus
202 * @gpio.led[16]: Led control signals
203 * @gpio.aux[16]: Auxillary signals, not used by core
204 * @init_sequence: Pointer to LCD initialization array
205 * @gamma.lock: Mutex for Gamma curve locking
206 * @gamma.curves: Pointer to Gamma curve array
207 * @gamma.num_values: Number of values per Gamma curve
208 * @gamma.num_curves: Number of Gamma curves
209 * @debug: Pointer to debug value
210 * @current_debug:
211 * @first_update_done: Used to only time the first display update
212 * @update_time: Used to calculate 'fps' in debug output
213 * @bgr: BGR mode/\n
214 * @extra: Extra info needed by driver
215 */
216struct fbtft_par {
217 struct spi_device *spi;
218 struct platform_device *pdev;
219 struct fb_info *info;
220 struct fbtft_platform_data *pdata;
221 u16 *ssbuf;
222 u32 pseudo_palette[16];
223 struct {
224 void *buf;
225 dma_addr_t dma;
226 size_t len;
227 } txbuf;
228 u8 *buf;
229 u8 startbyte;
230 struct fbtft_ops fbtftops;
231 spinlock_t dirty_lock;
232 unsigned dirty_lines_start;
233 unsigned dirty_lines_end;
234 struct {
235 int reset;
236 int dc;
237 int rd;
238 int wr;
239 int latch;
240 int cs;
241 int db[16];
242 int led[16];
243 int aux[16];
244 } gpio;
245 int *init_sequence;
246 struct {
247 struct mutex lock;
248 unsigned long *curves;
249 int num_values;
250 int num_curves;
251 } gamma;
252 unsigned long debug;
253 bool first_update_done;
254 struct timespec update_time;
255 bool bgr;
256 void *extra;
257};
258
259#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
260
261#define write_reg(par, ...) \
262do { \
263 par->fbtftops.write_register(par, NUMARGS(__VA_ARGS__), __VA_ARGS__); \
264} while (0)
265
266/* fbtft-core.c */
267extern void fbtft_dbg_hex(const struct device *dev,
268 int groupsize, void *buf, size_t len, const char *fmt, ...);
269extern struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
270 struct device *dev);
271extern void fbtft_framebuffer_release(struct fb_info *info);
272extern int fbtft_register_framebuffer(struct fb_info *fb_info);
273extern int fbtft_unregister_framebuffer(struct fb_info *fb_info);
274extern void fbtft_register_backlight(struct fbtft_par *par);
275extern void fbtft_unregister_backlight(struct fbtft_par *par);
276extern int fbtft_init_display(struct fbtft_par *par);
277extern int fbtft_probe_common(struct fbtft_display *display,
278 struct spi_device *sdev, struct platform_device *pdev);
279extern int fbtft_remove_common(struct device *dev, struct fb_info *info);
280
281/* fbtft-io.c */
282extern int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len);
283extern int fbtft_write_spi_emulate_9(struct fbtft_par *par,
284 void *buf, size_t len);
285extern int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len);
286extern int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len);
287extern int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len);
288extern int fbtft_write_gpio16_wr_latched(struct fbtft_par *par,
289 void *buf, size_t len);
290
291/* fbtft-bus.c */
292extern int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len);
293extern int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len);
294extern int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len);
295extern int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len);
296extern void fbtft_write_reg8_bus8(struct fbtft_par *par, int len, ...);
297extern void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...);
298extern void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
299extern void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
300
301
302#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
303 \
304static int fbtft_driver_probe_spi(struct spi_device *spi) \
305{ \
306 return fbtft_probe_common(_display, spi, NULL); \
307} \
308 \
309static int fbtft_driver_remove_spi(struct spi_device *spi) \
310{ \
311 struct fb_info *info = spi_get_drvdata(spi); \
312 \
313 return fbtft_remove_common(&spi->dev, info); \
314} \
315 \
316static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
317{ \
318 return fbtft_probe_common(_display, NULL, pdev); \
319} \
320 \
321static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
322{ \
323 struct fb_info *info = platform_get_drvdata(pdev); \
324 \
325 return fbtft_remove_common(&pdev->dev, info); \
326} \
327 \
328static const struct of_device_id dt_ids[] = { \
329 { .compatible = _compatible }, \
330 {}, \
331}; \
332 \
333MODULE_DEVICE_TABLE(of, dt_ids); \
334 \
335 \
336static struct spi_driver fbtft_driver_spi_driver = { \
337 .driver = { \
338 .name = _name, \
339 .owner = THIS_MODULE, \
340 .of_match_table = of_match_ptr(dt_ids), \
341 }, \
342 .probe = fbtft_driver_probe_spi, \
343 .remove = fbtft_driver_remove_spi, \
344}; \
345 \
346static struct platform_driver fbtft_driver_platform_driver = { \
347 .driver = { \
348 .name = _name, \
349 .owner = THIS_MODULE, \
350 .of_match_table = of_match_ptr(dt_ids), \
351 }, \
352 .probe = fbtft_driver_probe_pdev, \
353 .remove = fbtft_driver_remove_pdev, \
354}; \
355 \
356static int __init fbtft_driver_module_init(void) \
357{ \
358 int ret; \
359 \
360 ret = spi_register_driver(&fbtft_driver_spi_driver); \
361 if (ret < 0) \
362 return ret; \
363 return platform_driver_register(&fbtft_driver_platform_driver); \
364} \
365 \
366static void __exit fbtft_driver_module_exit(void) \
367{ \
368 spi_unregister_driver(&fbtft_driver_spi_driver); \
369 platform_driver_unregister(&fbtft_driver_platform_driver); \
370} \
371 \
372module_init(fbtft_driver_module_init); \
373module_exit(fbtft_driver_module_exit);
374
375
376/* Debug macros */
377
378/* shorthand debug levels */
379#define DEBUG_LEVEL_1 DEBUG_REQUEST_GPIOS
380#define DEBUG_LEVEL_2 (DEBUG_LEVEL_1 | DEBUG_DRIVER_INIT_FUNCTIONS | DEBUG_TIME_FIRST_UPDATE)
381#define DEBUG_LEVEL_3 (DEBUG_LEVEL_2 | DEBUG_RESET | DEBUG_INIT_DISPLAY | DEBUG_BLANK | DEBUG_REQUEST_GPIOS | DEBUG_FREE_GPIOS | DEBUG_VERIFY_GPIOS | DEBUG_BACKLIGHT | DEBUG_SYSFS)
382#define DEBUG_LEVEL_4 (DEBUG_LEVEL_2 | DEBUG_FB_READ | DEBUG_FB_WRITE | DEBUG_FB_FILLRECT | DEBUG_FB_COPYAREA | DEBUG_FB_IMAGEBLIT | DEBUG_FB_BLANK)
383#define DEBUG_LEVEL_5 (DEBUG_LEVEL_3 | DEBUG_UPDATE_DISPLAY)
384#define DEBUG_LEVEL_6 (DEBUG_LEVEL_4 | DEBUG_LEVEL_5)
385#define DEBUG_LEVEL_7 0xFFFFFFFF
386
387#define DEBUG_DRIVER_INIT_FUNCTIONS (1<<3)
388#define DEBUG_TIME_FIRST_UPDATE (1<<4)
389#define DEBUG_TIME_EACH_UPDATE (1<<5)
390#define DEBUG_DEFERRED_IO (1<<6)
391#define DEBUG_FBTFT_INIT_FUNCTIONS (1<<7)
392
393/* fbops */
394#define DEBUG_FB_READ (1<<8)
395#define DEBUG_FB_WRITE (1<<9)
396#define DEBUG_FB_FILLRECT (1<<10)
397#define DEBUG_FB_COPYAREA (1<<11)
398#define DEBUG_FB_IMAGEBLIT (1<<12)
399#define DEBUG_FB_SETCOLREG (1<<13)
400#define DEBUG_FB_BLANK (1<<14)
401
402#define DEBUG_SYSFS (1<<16)
403
404/* fbtftops */
405#define DEBUG_BACKLIGHT (1<<17)
406#define DEBUG_READ (1<<18)
407#define DEBUG_WRITE (1<<19)
408#define DEBUG_WRITE_VMEM (1<<20)
409#define DEBUG_WRITE_REGISTER (1<<21)
410#define DEBUG_SET_ADDR_WIN (1<<22)
411#define DEBUG_RESET (1<<23)
412#define DEBUG_MKDIRTY (1<<24)
413#define DEBUG_UPDATE_DISPLAY (1<<25)
414#define DEBUG_INIT_DISPLAY (1<<26)
415#define DEBUG_BLANK (1<<27)
416#define DEBUG_REQUEST_GPIOS (1<<28)
417#define DEBUG_FREE_GPIOS (1<<29)
418#define DEBUG_REQUEST_GPIOS_MATCH (1<<30)
419#define DEBUG_VERIFY_GPIOS (1<<31)
420
421
422#define fbtft_init_dbg(dev, format, arg...) \
423do { \
424 if (unlikely((dev)->platform_data && \
425 (((struct fbtft_platform_data *)(dev)->platform_data)->display.debug & DEBUG_DRIVER_INIT_FUNCTIONS))) \
426 dev_info(dev, format, ##arg); \
427} while (0)
428
429#define fbtft_par_dbg(level, par, format, arg...) \
430do { \
431 if (unlikely(par->debug & level)) \
432 dev_info(par->info->device, format, ##arg); \
433} while (0)
434
435#define fbtft_dev_dbg(level, par, dev, format, arg...) \
436do { \
437 if (unlikely(par->debug & level)) \
438 dev_info(dev, format, ##arg); \
439} while (0)
440
441#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \
442do { \
443 if (unlikely(par->debug & level)) \
444 fbtft_dbg_hex(dev, sizeof(type), buf, num * sizeof(type), format, ##arg); \
445} while (0)
446
447#endif /* __LINUX_FBTFT_H */
diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c
new file mode 100644
index 000000000000..b9f4c30e39c6
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft_device.c
@@ -0,0 +1,1444 @@
1/*
2 *
3 * Copyright (C) 2013, Noralf Tronnes
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/gpio.h>
24#include <linux/spi/spi.h>
25
26#include "fbtft.h"
27
28#define DRVNAME "fbtft_device"
29
30#define MAX_GPIOS 32
31
32struct spi_device *spi_device;
33struct platform_device *p_device;
34
35static char *name;
36module_param(name, charp, 0);
37MODULE_PARM_DESC(name, "Devicename (required). " \
38"name=list => list all supported devices.");
39
40static unsigned rotate;
41module_param(rotate, uint, 0);
42MODULE_PARM_DESC(rotate,
43"Angle to rotate display counter clockwise: 0, 90, 180, 270");
44
45static unsigned busnum;
46module_param(busnum, uint, 0);
47MODULE_PARM_DESC(busnum, "SPI bus number (default=0)");
48
49static unsigned cs;
50module_param(cs, uint, 0);
51MODULE_PARM_DESC(cs, "SPI chip select (default=0)");
52
53static unsigned speed;
54module_param(speed, uint, 0);
55MODULE_PARM_DESC(speed, "SPI speed (override device default)");
56
57static int mode = -1;
58module_param(mode, int, 0);
59MODULE_PARM_DESC(mode, "SPI mode (override device default)");
60
61static char *gpios;
62module_param(gpios, charp, 0);
63MODULE_PARM_DESC(gpios,
64"List of gpios. Comma separated with the form: reset:23,dc:24 " \
65"(when overriding the default, all gpios must be specified)");
66
67static unsigned fps;
68module_param(fps, uint, 0);
69MODULE_PARM_DESC(fps, "Frames per second (override driver default)");
70
71static char *gamma;
72module_param(gamma, charp, 0);
73MODULE_PARM_DESC(gamma,
74"String representation of Gamma Curve(s). Driver specific.");
75
76static int txbuflen;
77module_param(txbuflen, int, 0);
78MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)");
79
80static int bgr = -1;
81module_param(bgr, int, 0);
82MODULE_PARM_DESC(bgr,
83"BGR bit (supported by some drivers).");
84
85static unsigned startbyte;
86module_param(startbyte, uint, 0);
87MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
88
89static bool custom;
90module_param(custom, bool, 0);
91MODULE_PARM_DESC(custom, "Add a custom display device. " \
92"Use speed= argument to make it a SPI device, else platform_device");
93
94static unsigned width;
95module_param(width, uint, 0);
96MODULE_PARM_DESC(width, "Display width, used with the custom argument");
97
98static unsigned height;
99module_param(height, uint, 0);
100MODULE_PARM_DESC(height, "Display height, used with the custom argument");
101
102static unsigned buswidth = 8;
103module_param(buswidth, uint, 0);
104MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument");
105
106static int init[FBTFT_MAX_INIT_SEQUENCE];
107static int init_num;
108module_param_array(init, int, &init_num, 0);
109MODULE_PARM_DESC(init, "Init sequence, used with the custom argument");
110
111static unsigned long debug;
112module_param(debug, ulong , 0);
113MODULE_PARM_DESC(debug,
114"level: 0-7 (the remaining 29 bits is for advanced usage)");
115
116static unsigned verbose = 3;
117module_param(verbose, uint, 0);
118MODULE_PARM_DESC(verbose,
119"0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
120
121
122struct fbtft_device_display {
123 char *name;
124 struct spi_board_info *spi;
125 struct platform_device *pdev;
126};
127
128static void fbtft_device_pdev_release(struct device *dev);
129
130static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len);
131static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
132 int xs, int ys, int xe, int ye);
133
134#define ADAFRUIT18_GAMMA \
135 "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
136 "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
137
138static int hy28b_init_sequence[] = {
139 -1,0x00e7,0x0010,-1,0x0000,0x0001,-1,0x0001,0x0100,-1,0x0002,0x0700,
140 -1,0x0003,0x1030,-1,0x0004,0x0000,-1,0x0008,0x0207,-1,0x0009,0x0000,
141 -1,0x000a,0x0000,-1,0x000c,0x0001,-1,0x000d,0x0000,-1,0x000f,0x0000,
142 -1,0x0010,0x0000,-1,0x0011,0x0007,-1,0x0012,0x0000,-1,0x0013,0x0000,
143 -2,50,-1,0x0010,0x1590,-1,0x0011,0x0227,-2,50,-1,0x0012,0x009c,-2,50,
144 -1,0x0013,0x1900,-1,0x0029,0x0023,-1,0x002b,0x000e,-2,50,
145 -1,0x0020,0x0000,-1,0x0021,0x0000,-2,50,-1,0x0050,0x0000,
146 -1,0x0051,0x00ef,-1,0x0052,0x0000,-1,0x0053,0x013f,-1,0x0060,0xa700,
147 -1,0x0061,0x0001,-1,0x006a,0x0000,-1,0x0080,0x0000,-1,0x0081,0x0000,
148 -1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000,-1,0x0085,0x0000,
149 -1,0x0090,0x0010,-1,0x0092,0x0000,-1,0x0093,0x0003,-1,0x0095,0x0110,
150 -1,0x0097,0x0000,-1,0x0098,0x0000,-1,0x0007,0x0133,-1,0x0020,0x0000,
151 -1,0x0021,0x0000,-2,100,-3 };
152
153#define HY28B_GAMMA \
154 "04 1F 4 7 7 0 7 7 6 0\n" \
155 "0F 00 1 7 4 0 0 0 6 7"
156
157static int pitft_init_sequence[] = {
158 -1,0x01,-2,5,-1,0x28,-1,0xEF,0x03,0x80,0x02,-1,0xCF,0x00,0xC1,0x30,
159 -1,0xED,0x64,0x03,0x12,0x81,-1,0xE8,0x85,0x00,0x78,
160 -1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xF7,0x20,-1,0xEA,0x00,0x00,
161 -1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,-1,0x3A,0x55,
162 -1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,-1,0xF2,0x00,-1,0x26,0x01,
163 -1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,
164 0x0E,0x09,0x00,-1,0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,
165 0x08,0x0F,0x0C,0x31,0x36,0x0F,-1,0x11,-2,100,-1,0x29,-2,20,-3 };
166
167static int waveshare32b_init_sequence[] = {
168 -1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xCF,0x00,0xC1,0x30,
169 -1,0xE8,0x85,0x00,0x78,-1,0xEA,0x00,0x00,-1,0xED,0x64,0x03,0x12,0x81,
170 -1,0xF7,0x20,-1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,
171 -1,0x36,0x28,-1,0x3A,0x55,-1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,
172 -1,0xF2,0x00,-1,0x26,0x01,
173 -1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,0x0E,0x09,0x00,
174 -1,0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0F,0x0C,0x31,0x36,0x0F,
175 -1,0x11,-2,120,-1,0x29,-1,0x2c,-3 };
176
177/* Supported displays in alphabetical order */
178static struct fbtft_device_display displays[] = {
179 {
180 .name = "adafruit18",
181 .spi = &(struct spi_board_info) {
182 .modalias = "fb_st7735r",
183 .max_speed_hz = 32000000,
184 .mode = SPI_MODE_0,
185 .platform_data = &(struct fbtft_platform_data) {
186 .display = {
187 .buswidth = 8,
188 .backlight = 1,
189 },
190 .gpios = (const struct fbtft_gpio []) {
191 { "reset", 25 },
192 { "dc", 24 },
193 { "led", 18 },
194 {},
195 },
196 .gamma = ADAFRUIT18_GAMMA,
197 }
198 }
199 }, {
200 .name = "adafruit18_green",
201 .spi = &(struct spi_board_info) {
202 .modalias = "fb_st7735r",
203 .max_speed_hz = 4000000,
204 .mode = SPI_MODE_0,
205 .platform_data = &(struct fbtft_platform_data) {
206 .display = {
207 .buswidth = 8,
208 .backlight = 1,
209 .fbtftops.set_addr_win = \
210 adafruit18_green_tab_set_addr_win,
211 },
212 .bgr = true,
213 .gpios = (const struct fbtft_gpio []) {
214 { "reset", 25 },
215 { "dc", 24 },
216 { "led", 18 },
217 {},
218 },
219 .gamma = ADAFRUIT18_GAMMA,
220 }
221 }
222 }, {
223 .name = "adafruit22",
224 .spi = &(struct spi_board_info) {
225 .modalias = "fb_hx8340bn",
226 .max_speed_hz = 32000000,
227 .mode = SPI_MODE_0,
228 .platform_data = &(struct fbtft_platform_data) {
229 .display = {
230 .buswidth = 9,
231 .backlight = 1,
232 },
233 .bgr = true,
234 .gpios = (const struct fbtft_gpio []) {
235 { "reset", 25 },
236 { "led", 23 },
237 {},
238 },
239 }
240 }
241 }, {
242 .name = "adafruit22a",
243 .spi = &(struct spi_board_info) {
244 .modalias = "fb_ili9340",
245 .max_speed_hz = 32000000,
246 .mode = SPI_MODE_0,
247 .platform_data = &(struct fbtft_platform_data) {
248 .display = {
249 .buswidth = 8,
250 .backlight = 1,
251 },
252 .bgr = true,
253 .gpios = (const struct fbtft_gpio []) {
254 { "reset", 25 },
255 { "dc", 24 },
256 { "led", 18 },
257 {},
258 },
259 }
260 }
261 }, {
262 .name = "adafruit28",
263 .spi = &(struct spi_board_info) {
264 .modalias = "fb_ili9341",
265 .max_speed_hz = 32000000,
266 .mode = SPI_MODE_0,
267 .platform_data = &(struct fbtft_platform_data) {
268 .display = {
269 .buswidth = 8,
270 .backlight = 1,
271 },
272 .bgr = true,
273 .gpios = (const struct fbtft_gpio []) {
274 { "reset", 25 },
275 { "dc", 24 },
276 { "led", 18 },
277 {},
278 },
279 }
280 }
281 }, {
282 .name = "adafruit13m",
283 .spi = &(struct spi_board_info) {
284 .modalias = "fb_ssd1306",
285 .max_speed_hz = 16000000,
286 .mode = SPI_MODE_0,
287 .platform_data = &(struct fbtft_platform_data) {
288 .display = {
289 .buswidth = 8,
290 },
291 .gpios = (const struct fbtft_gpio []) {
292 { "reset", 25 },
293 { "dc", 24 },
294 {},
295 },
296 }
297 }
298 }, {
299 .name = "agm1264k-fl",
300 .pdev = &(struct platform_device) {
301 .name = "fb_agm1264k-fl",
302 .id = 0,
303 .dev = {
304 .release = fbtft_device_pdev_release,
305 .platform_data = &(struct fbtft_platform_data) {
306 .display = {
307 .buswidth = 8,
308 .backlight = FBTFT_ONBOARD_BACKLIGHT,
309 },
310 .gpios = (const struct fbtft_gpio []) {
311 {},
312 },
313 },
314 }
315 }
316 }, {
317 .name = "dogs102",
318 .spi = &(struct spi_board_info) {
319 .modalias = "fb_uc1701",
320 .max_speed_hz = 8000000,
321 .mode = SPI_MODE_0,
322 .platform_data = &(struct fbtft_platform_data) {
323 .display = {
324 .buswidth = 8,
325 },
326 .bgr = true,
327 .gpios = (const struct fbtft_gpio []) {
328 { "reset", 13 },
329 { "dc", 6 },
330 {},
331 },
332 }
333 }
334 }, {
335 .name = "er_tftm050_2",
336 .spi = &(struct spi_board_info) {
337 .modalias = "fb_ra8875",
338 .max_speed_hz = 5000000,
339 .mode = SPI_MODE_3,
340 .platform_data = &(struct fbtft_platform_data) {
341 .display = {
342 .buswidth = 8,
343 .backlight = 1,
344 .width = 480,
345 .height = 272,
346 },
347 .bgr = true,
348 .gpios = (const struct fbtft_gpio []) {
349 { "reset", 25 },
350 { "dc", 24 },
351 {},
352 },
353 }
354 }
355 }, {
356 .name = "er_tftm070_5",
357 .spi = &(struct spi_board_info) {
358 .modalias = "fb_ra8875",
359 .max_speed_hz = 5000000,
360 .mode = SPI_MODE_3,
361 .platform_data = &(struct fbtft_platform_data) {
362 .display = {
363 .buswidth = 8,
364 .backlight = 1,
365 .width = 800,
366 .height = 480,
367 },
368 .bgr = true,
369 .gpios = (const struct fbtft_gpio []) {
370 { "reset", 25 },
371 { "dc", 24 },
372 {},
373 },
374 }
375 }
376 }, {
377 .name = "flexfb",
378 .spi = &(struct spi_board_info) {
379 .modalias = "flexfb",
380 .max_speed_hz = 32000000,
381 .mode = SPI_MODE_0,
382 .platform_data = &(struct fbtft_platform_data) {
383 .gpios = (const struct fbtft_gpio []) {
384 { "reset", 25 },
385 { "dc", 24 },
386 {},
387 },
388 }
389 }
390 }, {
391 .name = "flexpfb",
392 .pdev = &(struct platform_device) {
393 .name = "flexpfb",
394 .id = 0,
395 .dev = {
396 .release = fbtft_device_pdev_release,
397 .platform_data = &(struct fbtft_platform_data) {
398 .gpios = (const struct fbtft_gpio []) {
399 { "reset", 17 },
400 { "dc", 1 },
401 { "wr", 0 },
402 { "cs", 21 },
403 { "db00", 9 },
404 { "db01", 11 },
405 { "db02", 18 },
406 { "db03", 23 },
407 { "db04", 24 },
408 { "db05", 25 },
409 { "db06", 8 },
410 { "db07", 7 },
411 { "led", 4 },
412 {},
413 },
414 },
415 }
416 }
417 }, {
418 .name = "freetronicsoled128",
419 .spi = &(struct spi_board_info) {
420 .modalias = "fb_ssd1351",
421 .max_speed_hz = 20000000,
422 .mode = SPI_MODE_0,
423 .platform_data = &(struct fbtft_platform_data) {
424 .display = {
425 .buswidth = 8,
426 .backlight = FBTFT_ONBOARD_BACKLIGHT,
427 },
428 .bgr = true,
429 .gpios = (const struct fbtft_gpio []) {
430 { "reset", 24 },
431 { "dc", 25 },
432 {},
433 },
434 }
435 }
436 }, {
437 .name = "hx8353d",
438 .spi = &(struct spi_board_info) {
439 .modalias = "fb_hx8353d",
440 .max_speed_hz = 16000000,
441 .mode = SPI_MODE_0,
442 .platform_data = &(struct fbtft_platform_data) {
443 .display = {
444 .buswidth = 8,
445 .backlight = 1,
446 },
447 .gpios = (const struct fbtft_gpio []) {
448 { "reset", 25 },
449 { "dc", 24 },
450 { "led", 23 },
451 {},
452 },
453 }
454 }
455 }, {
456 .name = "hy28a",
457 .spi = &(struct spi_board_info) {
458 .modalias = "fb_ili9320",
459 .max_speed_hz = 32000000,
460 .mode = SPI_MODE_3,
461 .platform_data = &(struct fbtft_platform_data) {
462 .display = {
463 .buswidth = 8,
464 .backlight = 1,
465 },
466 .startbyte = 0b01110000,
467 .bgr = true,
468 .gpios = (const struct fbtft_gpio []) {
469 { "reset", 25 },
470 { "led", 18 },
471 {},
472 },
473 }
474 }
475 }, {
476 .name = "hy28b",
477 .spi = &(struct spi_board_info) {
478 .modalias = "fb_ili9325",
479 .max_speed_hz = 48000000,
480 .mode = SPI_MODE_3,
481 .platform_data = &(struct fbtft_platform_data) {
482 .display = {
483 .buswidth = 8,
484 .backlight = 1,
485 .init_sequence = hy28b_init_sequence,
486 },
487 .startbyte = 0b01110000,
488 .bgr = true,
489 .fps= 50,
490 .gpios = (const struct fbtft_gpio []) {
491 { "reset", 25 },
492 { "led", 18 },
493 {},
494 },
495 .gamma = HY28B_GAMMA,
496 }
497 }
498 }, {
499 .name = "ili9481",
500 .spi = &(struct spi_board_info) {
501 .modalias = "fb_ili9481",
502 .max_speed_hz = 32000000,
503 .mode = SPI_MODE_0,
504 .platform_data = &(struct fbtft_platform_data) {
505 .display = {
506 .regwidth = 16,
507 .buswidth = 8,
508 .backlight = 1,
509 },
510 .bgr = true,
511 .gpios = (const struct fbtft_gpio []) {
512 { "reset", 25 },
513 { "dc", 24 },
514 { "led", 22 },
515 {},
516 },
517 }
518 }
519 }, {
520 .name = "itdb24",
521 .pdev = &(struct platform_device) {
522 .name = "fb_s6d1121",
523 .id = 0,
524 .dev = {
525 .release = fbtft_device_pdev_release,
526 .platform_data = &(struct fbtft_platform_data) {
527 .display = {
528 .buswidth = 8,
529 .backlight = 1,
530 },
531 .bgr = false,
532 .gpios = (const struct fbtft_gpio []) {
533 /* Wiring for LCD adapter kit */
534 { "reset", 7 },
535 { "dc", 0 }, /* rev 2: 2 */
536 { "wr", 1 }, /* rev 2: 3 */
537 { "cs", 8 },
538 { "db00", 17 },
539 { "db01", 18 },
540 { "db02", 21 }, /* rev 2: 27 */
541 { "db03", 22 },
542 { "db04", 23 },
543 { "db05", 24 },
544 { "db06", 25 },
545 { "db07", 4 },
546 {}
547 },
548 },
549 }
550 }
551 }, {
552 .name = "itdb28",
553 .pdev = &(struct platform_device) {
554 .name = "fb_ili9325",
555 .id = 0,
556 .dev = {
557 .release = fbtft_device_pdev_release,
558 .platform_data = &(struct fbtft_platform_data) {
559 .display = {
560 .buswidth = 8,
561 .backlight = 1,
562 },
563 .bgr = true,
564 .gpios = (const struct fbtft_gpio []) {
565 {},
566 },
567 },
568 }
569 }
570 }, {
571 .name = "itdb28_spi",
572 .spi = &(struct spi_board_info) {
573 .modalias = "fb_ili9325",
574 .max_speed_hz = 32000000,
575 .mode = SPI_MODE_0,
576 .platform_data = &(struct fbtft_platform_data) {
577 .display = {
578 .buswidth = 8,
579 .backlight = 1,
580 },
581 .bgr = true,
582 .gpios = (const struct fbtft_gpio []) {
583 { "reset", 25 },
584 { "dc", 24 },
585 {},
586 },
587 }
588 }
589 }, {
590 .name = "mi0283qt-2",
591 .spi = &(struct spi_board_info) {
592 .modalias = "fb_hx8347d",
593 .max_speed_hz = 32000000,
594 .mode = SPI_MODE_0,
595 .platform_data = &(struct fbtft_platform_data) {
596 .display = {
597 .buswidth = 8,
598 .backlight = 1,
599 },
600 .startbyte = 0b01110000,
601 .bgr = true,
602 .gpios = (const struct fbtft_gpio []) {
603 { "reset", 25 },
604 { "dc", 24 },
605 { "led", 18 },
606 {},
607 },
608 }
609 }
610 }, {
611 .name = "mi0283qt-9a",
612 .spi = &(struct spi_board_info) {
613 .modalias = "fb_ili9341",
614 .max_speed_hz = 32000000,
615 .mode = SPI_MODE_0,
616 .platform_data = &(struct fbtft_platform_data) {
617 .display = {
618 .buswidth = 9,
619 .backlight = 1,
620 },
621 .bgr = true,
622 .gpios = (const struct fbtft_gpio []) {
623 { "reset", 25 },
624 { "led", 18 },
625 {},
626 },
627 }
628 }
629 }, {
630 .name = "mi0283qt-v2",
631 .spi = &(struct spi_board_info) {
632 .modalias = "fb_watterott",
633 .max_speed_hz = 4000000,
634 .mode = SPI_MODE_3,
635 .platform_data = &(struct fbtft_platform_data) {
636 .gpios = (const struct fbtft_gpio []) {
637 { "reset", 25 },
638 {},
639 },
640 }
641 }
642 }, {
643 .name = "nokia3310",
644 .spi = &(struct spi_board_info) {
645 .modalias = "fb_pcd8544",
646 .max_speed_hz = 400000,
647 .mode = SPI_MODE_0,
648 .platform_data = &(struct fbtft_platform_data) {
649 .display = {
650 .buswidth = 8,
651 },
652 .gpios = (const struct fbtft_gpio []) {
653 { "reset", 25 },
654 { "dc", 24 },
655 { "led", 23 },
656 {},
657 },
658 }
659 }
660 }, {
661 .name = "nokia3310a",
662 .spi = &(struct spi_board_info) {
663 .modalias = "fb_tls8204",
664 .max_speed_hz = 1000000,
665 .mode = SPI_MODE_0,
666 .platform_data = &(struct fbtft_platform_data) {
667 .display = {
668 .buswidth = 8,
669 },
670 .gpios = (const struct fbtft_gpio []) {
671 { "reset", 25 },
672 { "dc", 24 },
673 { "led", 23 },
674 {},
675 },
676 }
677 }
678 }, {
679 .name = "piscreen",
680 .spi = &(struct spi_board_info) {
681 .modalias = "fb_ili9486",
682 .max_speed_hz = 32000000,
683 .mode = SPI_MODE_0,
684 .platform_data = &(struct fbtft_platform_data) {
685 .display = {
686 .regwidth = 16,
687 .buswidth = 8,
688 .backlight = 1,
689 },
690 .bgr = true,
691 .gpios = (const struct fbtft_gpio []) {
692 { "reset", 25 },
693 { "dc", 24 },
694 { "led", 22 },
695 {},
696 },
697 }
698 }
699 }, {
700 .name = "pitft",
701 .spi = &(struct spi_board_info) {
702 .modalias = "fb_ili9340",
703 .max_speed_hz = 32000000,
704 .mode = SPI_MODE_0,
705 .chip_select = 0,
706 .platform_data = &(struct fbtft_platform_data) {
707 .display = {
708 .buswidth = 8,
709 .backlight = 1,
710 .init_sequence = pitft_init_sequence,
711 },
712 .bgr = true,
713 .gpios = (const struct fbtft_gpio []) {
714 { "dc", 25 },
715 {},
716 },
717 }
718 }
719 }, {
720 .name = "pioled",
721 .spi = &(struct spi_board_info) {
722 .modalias = "fb_ssd1351",
723 .max_speed_hz = 20000000,
724 .mode = SPI_MODE_0,
725 .platform_data = &(struct fbtft_platform_data) {
726 .display = {
727 .buswidth = 8,
728 },
729 .bgr = true,
730 .gpios = (const struct fbtft_gpio []) {
731 { "reset", 24 },
732 { "dc", 25 },
733 {},
734 },
735 .gamma = "0 2 2 2 2 2 2 2 " \
736 "2 2 2 2 2 2 2 2 " \
737 "2 2 2 2 2 2 2 2 " \
738 "2 2 2 2 2 2 2 3 " \
739 "3 3 3 3 3 3 3 3 " \
740 "3 3 3 3 3 3 3 3 " \
741 "3 3 3 4 4 4 4 4 " \
742 "4 4 4 4 4 4 4"
743 }
744 }
745 }, {
746 .name = "rpi-display",
747 .spi = &(struct spi_board_info) {
748 .modalias = "fb_ili9341",
749 .max_speed_hz = 32000000,
750 .mode = SPI_MODE_0,
751 .platform_data = &(struct fbtft_platform_data) {
752 .display = {
753 .buswidth = 8,
754 .backlight = 1,
755 },
756 .bgr = true,
757 .gpios = (const struct fbtft_gpio []) {
758 { "reset", 23 },
759 { "dc", 24 },
760 { "led", 18 },
761 {},
762 },
763 }
764 }
765 }, {
766 .name = "s6d02a1",
767 .spi = &(struct spi_board_info) {
768 .modalias = "fb_s6d02a1",
769 .max_speed_hz = 32000000,
770 .mode = SPI_MODE_0,
771 .platform_data = &(struct fbtft_platform_data) {
772 .display = {
773 .buswidth = 8,
774 .backlight = 1,
775 },
776 .bgr = true,
777 .gpios = (const struct fbtft_gpio []) {
778 { "reset", 25 },
779 { "dc", 24 },
780 { "led", 23 },
781 {},
782 },
783 }
784 }
785 }, {
786 .name = "sainsmart18",
787 .spi = &(struct spi_board_info) {
788 .modalias = "fb_st7735r",
789 .max_speed_hz = 32000000,
790 .mode = SPI_MODE_0,
791 .platform_data = &(struct fbtft_platform_data) {
792 .display = {
793 .buswidth = 8,
794 },
795 .gpios = (const struct fbtft_gpio []) {
796 { "reset", 25 },
797 { "dc", 24 },
798 {},
799 },
800 }
801 }
802 }, {
803 .name = "sainsmart32",
804 .pdev = &(struct platform_device) {
805 .name = "fb_ssd1289",
806 .id = 0,
807 .dev = {
808 .release = fbtft_device_pdev_release,
809 .platform_data = &(struct fbtft_platform_data) {
810 .display = {
811 .buswidth = 16,
812 .txbuflen = -2, /* disable buffer */
813 .backlight = 1,
814 .fbtftops.write = write_gpio16_wr_slow,
815 },
816 .bgr = true,
817 .gpios = (const struct fbtft_gpio []) {
818 {},
819 },
820 },
821 },
822 }
823 }, {
824 .name = "sainsmart32_fast",
825 .pdev = &(struct platform_device) {
826 .name = "fb_ssd1289",
827 .id = 0,
828 .dev = {
829 .release = fbtft_device_pdev_release,
830 .platform_data = &(struct fbtft_platform_data) {
831 .display = {
832 .buswidth = 16,
833 .txbuflen = -2, /* disable buffer */
834 .backlight = 1,
835 },
836 .bgr = true,
837 .gpios = (const struct fbtft_gpio []) {
838 {},
839 },
840 },
841 },
842 }
843 }, {
844 .name = "sainsmart32_latched",
845 .pdev = &(struct platform_device) {
846 .name = "fb_ssd1289",
847 .id = 0,
848 .dev = {
849 .release = fbtft_device_pdev_release,
850 .platform_data = &(struct fbtft_platform_data) {
851 .display = {
852 .buswidth = 16,
853 .txbuflen = -2, /* disable buffer */
854 .backlight = 1,
855 .fbtftops.write = \
856 fbtft_write_gpio16_wr_latched,
857 },
858 .bgr = true,
859 .gpios = (const struct fbtft_gpio []) {
860 {},
861 },
862 },
863 },
864 }
865 }, {
866 .name = "sainsmart32_spi",
867 .spi = &(struct spi_board_info) {
868 .modalias = "fb_ssd1289",
869 .max_speed_hz = 16000000,
870 .mode = SPI_MODE_0,
871 .platform_data = &(struct fbtft_platform_data) {
872 .display = {
873 .buswidth = 8,
874 .backlight = 1,
875 },
876 .bgr = true,
877 .gpios = (const struct fbtft_gpio []) {
878 { "reset", 25 },
879 { "dc", 24 },
880 {},
881 },
882 }
883 }
884 }, {
885 .name = "spidev",
886 .spi = &(struct spi_board_info) {
887 .modalias = "spidev",
888 .max_speed_hz = 500000,
889 .bus_num = 0,
890 .chip_select = 0,
891 .mode = SPI_MODE_0,
892 .platform_data = &(struct fbtft_platform_data) {
893 .gpios = (const struct fbtft_gpio []) {
894 {},
895 },
896 }
897 }
898 }, {
899 .name = "ssd1331",
900 .spi = &(struct spi_board_info) {
901 .modalias = "fb_ssd1331",
902 .max_speed_hz = 20000000,
903 .mode = SPI_MODE_3,
904 .platform_data = &(struct fbtft_platform_data) {
905 .display = {
906 .buswidth = 8,
907 },
908 .gpios = (const struct fbtft_gpio []) {
909 { "reset", 24 },
910 { "dc", 25 },
911 {},
912 },
913 }
914 }
915 }, {
916 .name = "tinylcd35",
917 .spi = &(struct spi_board_info) {
918 .modalias = "fb_tinylcd",
919 .max_speed_hz = 32000000,
920 .mode = SPI_MODE_0,
921 .platform_data = &(struct fbtft_platform_data) {
922 .display = {
923 .buswidth = 8,
924 .backlight = 1,
925 },
926 .bgr = true,
927 .gpios = (const struct fbtft_gpio []) {
928 { "reset", 25 },
929 { "dc", 24 },
930 { "led", 18 },
931 {},
932 },
933 }
934 }
935 }, {
936 .name = "tm022hdh26",
937 .spi = &(struct spi_board_info) {
938 .modalias = "fb_ili9341",
939 .max_speed_hz = 32000000,
940 .mode = SPI_MODE_0,
941 .platform_data = &(struct fbtft_platform_data) {
942 .display = {
943 .buswidth = 8,
944 .backlight = 1,
945 },
946 .bgr = true,
947 .gpios = (const struct fbtft_gpio []) {
948 { "reset", 25 },
949 { "dc", 24 },
950 { "led", 18 },
951 {},
952 },
953 }
954 }
955 }, {
956 .name = "tontec35_9481", /* boards before 02 July 2014 */
957 .spi = &(struct spi_board_info) {
958 .modalias = "fb_ili9481",
959 .max_speed_hz = 128000000,
960 .mode = SPI_MODE_3,
961 .platform_data = &(struct fbtft_platform_data) {
962 .display = {
963 .buswidth = 8,
964 .backlight = 1,
965 },
966 .bgr = true,
967 .gpios = (const struct fbtft_gpio []) {
968 { "reset", 15 },
969 { "dc", 25 },
970 { "led_", 18 },
971 {},
972 },
973 }
974 }
975 }, {
976 .name = "tontec35_9486", /* boards after 02 July 2014 */
977 .spi = &(struct spi_board_info) {
978 .modalias = "fb_ili9486",
979 .max_speed_hz = 128000000,
980 .mode = SPI_MODE_3,
981 .platform_data = &(struct fbtft_platform_data) {
982 .display = {
983 .buswidth = 8,
984 .backlight = 1,
985 },
986 .bgr = true,
987 .gpios = (const struct fbtft_gpio []) {
988 { "reset", 15 },
989 { "dc", 25 },
990 { "led_", 18 },
991 {},
992 },
993 }
994 }
995 }, {
996 .name = "upd161704",
997 .spi = &(struct spi_board_info) {
998 .modalias = "fb_upd161704",
999 .max_speed_hz = 32000000,
1000 .mode = SPI_MODE_0,
1001 .platform_data = &(struct fbtft_platform_data) {
1002 .display = {
1003 .buswidth = 8,
1004 },
1005 .gpios = (const struct fbtft_gpio []) {
1006 { "reset", 24 },
1007 { "dc", 25 },
1008 {},
1009 },
1010 }
1011 }
1012 }, {
1013 .name = "waveshare32b",
1014 .spi = &(struct spi_board_info) {
1015 .modalias = "fb_ili9340",
1016 .max_speed_hz = 48000000,
1017 .mode = SPI_MODE_0,
1018 .platform_data = &(struct fbtft_platform_data) {
1019 .display = {
1020 .buswidth = 8,
1021 .backlight = 1,
1022 .init_sequence = waveshare32b_init_sequence,
1023 },
1024 .bgr = true,
1025 .gpios = (const struct fbtft_gpio []) {
1026 { "reset", 27 },
1027 { "dc", 22 },
1028 {},
1029 },
1030 }
1031 }
1032 }, {
1033 .name = "waveshare22",
1034 .spi = &(struct spi_board_info) {
1035 .modalias = "fb_bd663474",
1036 .max_speed_hz = 32000000,
1037 .mode = SPI_MODE_3,
1038 .platform_data = &(struct fbtft_platform_data) {
1039 .display = {
1040 .buswidth = 8,
1041 },
1042 .gpios = (const struct fbtft_gpio []) {
1043 { "reset", 24 },
1044 { "dc", 25 },
1045 {},
1046 },
1047 }
1048 }
1049 }, {
1050 /* This should be the last item.
1051 Used with the custom argument */
1052 .name = "",
1053 .spi = &(struct spi_board_info) {
1054 .modalias = "",
1055 .max_speed_hz = 0,
1056 .mode = SPI_MODE_0,
1057 .platform_data = &(struct fbtft_platform_data) {
1058 .gpios = (const struct fbtft_gpio []) {
1059 {},
1060 },
1061 }
1062 },
1063 .pdev = &(struct platform_device) {
1064 .name = "",
1065 .id = 0,
1066 .dev = {
1067 .release = fbtft_device_pdev_release,
1068 .platform_data = &(struct fbtft_platform_data) {
1069 .gpios = (const struct fbtft_gpio []) {
1070 {},
1071 },
1072 },
1073 },
1074 },
1075 }
1076};
1077
1078static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
1079{
1080 u16 data;
1081 int i;
1082#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1083 static u16 prev_data;
1084#endif
1085
1086 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
1087 "%s(len=%d): ", __func__, len);
1088
1089 while (len) {
1090 data = *(u16 *) buf;
1091
1092 /* Start writing by pulling down /WR */
1093 gpio_set_value(par->gpio.wr, 0);
1094
1095 /* Set data */
1096#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1097 if (data == prev_data) {
1098 gpio_set_value(par->gpio.wr, 0); /* used as delay */
1099 } else {
1100 for (i = 0; i < 16; i++) {
1101 if ((data & 1) != (prev_data & 1))
1102 gpio_set_value(par->gpio.db[i],
1103 (data & 1));
1104 data >>= 1;
1105 prev_data >>= 1;
1106 }
1107 }
1108#else
1109 for (i = 0; i < 16; i++) {
1110 gpio_set_value(par->gpio.db[i], (data & 1));
1111 data >>= 1;
1112 }
1113#endif
1114
1115 /* Pullup /WR */
1116 gpio_set_value(par->gpio.wr, 1);
1117
1118#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1119 prev_data = *(u16 *) buf;
1120#endif
1121 buf += 2;
1122 len -= 2;
1123 }
1124
1125 return 0;
1126}
1127
1128static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
1129 int xs, int ys, int xe, int ye)
1130{
1131 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
1132 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
1133 write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
1134 write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
1135 write_reg(par, 0x2C);
1136}
1137
1138/* used if gpios parameter is present */
1139static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
1140
1141static void fbtft_device_pdev_release(struct device *dev)
1142{
1143/* Needed to silence this message:
1144Device 'xxx' does not have a release() function, it is broken and must be fixed
1145*/
1146}
1147
1148static int spi_device_found(struct device *dev, void *data)
1149{
1150 struct spi_device *spi = container_of(dev, struct spi_device, dev);
1151
1152 pr_info(DRVNAME": %s %s %dkHz %d bits mode=0x%02X\n",
1153 spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
1154 spi->bits_per_word, spi->mode);
1155
1156 return 0;
1157}
1158
1159static void pr_spi_devices(void)
1160{
1161 pr_info(DRVNAME": SPI devices registered:\n");
1162 bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
1163}
1164
1165static int p_device_found(struct device *dev, void *data)
1166{
1167 struct platform_device
1168 *pdev = container_of(dev, struct platform_device, dev);
1169
1170 if (strstr(pdev->name, "fb"))
1171 pr_info(DRVNAME": %s id=%d pdata? %s\n",
1172 pdev->name, pdev->id,
1173 pdev->dev.platform_data ? "yes" : "no");
1174
1175 return 0;
1176}
1177
1178static void pr_p_devices(void)
1179{
1180 pr_info(DRVNAME": 'fb' Platform devices registered:\n");
1181 bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
1182}
1183
1184#ifdef MODULE
1185static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
1186{
1187 struct device *dev;
1188 char str[32];
1189
1190 snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs);
1191
1192 dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
1193 if (dev) {
1194 if (verbose)
1195 pr_info(DRVNAME": Deleting %s\n", str);
1196 device_del(dev);
1197 }
1198}
1199
1200static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1201{
1202 struct spi_master *master;
1203
1204 master = spi_busnum_to_master(spi->bus_num);
1205 if (!master) {
1206 pr_err(DRVNAME ": spi_busnum_to_master(%d) returned NULL\n",
1207 spi->bus_num);
1208 return -EINVAL;
1209 }
1210 /* make sure it's available */
1211 fbtft_device_spi_delete(master, spi->chip_select);
1212 spi_device = spi_new_device(master, spi);
1213 put_device(&master->dev);
1214 if (!spi_device) {
1215 pr_err(DRVNAME ": spi_new_device() returned NULL\n");
1216 return -EPERM;
1217 }
1218 return 0;
1219}
1220#else
1221static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1222{
1223 return spi_register_board_info(spi, 1);
1224}
1225#endif
1226
1227static int __init fbtft_device_init(void)
1228{
1229 struct spi_board_info *spi = NULL;
1230 struct fbtft_platform_data *pdata;
1231 const struct fbtft_gpio *gpio = NULL;
1232 char *p_gpio, *p_name, *p_num;
1233 bool found = false;
1234 int i = 0;
1235 long val;
1236 int ret = 0;
1237
1238 pr_debug("\n\n"DRVNAME": init\n");
1239
1240 if (name == NULL) {
1241#ifdef MODULE
1242 pr_err(DRVNAME": missing module parameter: 'name'\n");
1243 return -EINVAL;
1244#else
1245 return 0;
1246#endif
1247 }
1248
1249 if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
1250 pr_err(DRVNAME \
1251 ": init parameter: exceeded max array size: %d\n",
1252 FBTFT_MAX_INIT_SEQUENCE);
1253 return -EINVAL;
1254 }
1255
1256 /* parse module parameter: gpios */
1257 while ((p_gpio = strsep(&gpios, ","))) {
1258 if (strchr(p_gpio, ':') == NULL) {
1259 pr_err(DRVNAME \
1260 ": error: missing ':' in gpios parameter: %s\n",
1261 p_gpio);
1262 return -EINVAL;
1263 }
1264 p_num = p_gpio;
1265 p_name = strsep(&p_num, ":");
1266 if (p_name == NULL || p_num == NULL) {
1267 pr_err(DRVNAME \
1268 ": something bad happened parsing gpios parameter: %s\n",
1269 p_gpio);
1270 return -EINVAL;
1271 }
1272 ret = kstrtol(p_num, 10, &val);
1273 if (ret) {
1274 pr_err(DRVNAME \
1275 ": could not parse number in gpios parameter: %s:%s\n",
1276 p_name, p_num);
1277 return -EINVAL;
1278 }
1279 strcpy(fbtft_device_param_gpios[i].name, p_name);
1280 fbtft_device_param_gpios[i++].gpio = (int) val;
1281 if (i == MAX_GPIOS) {
1282 pr_err(DRVNAME \
1283 ": gpios parameter: exceeded max array size: %d\n",
1284 MAX_GPIOS);
1285 return -EINVAL;
1286 }
1287 }
1288 if (fbtft_device_param_gpios[0].name[0])
1289 gpio = fbtft_device_param_gpios;
1290
1291 if (verbose > 2)
1292 pr_spi_devices(); /* print list of registered SPI devices */
1293
1294 if (verbose > 2)
1295 pr_p_devices(); /* print list of 'fb' platform devices */
1296
1297 pr_debug(DRVNAME": name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
1298
1299 if (rotate > 0 && rotate < 4) {
1300 rotate = (4 - rotate) * 90;
1301 pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
1302 rotate);
1303 }
1304 if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
1305 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1306 rotate);
1307 rotate = 0;
1308 }
1309
1310 /* name=list lists all supported displays */
1311 if (strncmp(name, "list", 32) == 0) {
1312 pr_info(DRVNAME": Supported displays:\n");
1313
1314 for (i = 0; i < ARRAY_SIZE(displays); i++)
1315 pr_info(DRVNAME": %s\n", displays[i].name);
1316 return -ECANCELED;
1317 }
1318
1319 if (custom) {
1320 i = ARRAY_SIZE(displays) - 1;
1321 displays[i].name = name;
1322 if (speed == 0) {
1323 displays[i].pdev->name = name;
1324 displays[i].spi = NULL;
1325 } else {
1326 strncpy(displays[i].spi->modalias, name, SPI_NAME_SIZE);
1327 displays[i].pdev = NULL;
1328 }
1329 }
1330
1331 for (i = 0; i < ARRAY_SIZE(displays); i++) {
1332 if (strncmp(name, displays[i].name, 32) == 0) {
1333 if (displays[i].spi) {
1334 spi = displays[i].spi;
1335 spi->chip_select = cs;
1336 spi->bus_num = busnum;
1337 if (speed)
1338 spi->max_speed_hz = speed;
1339 if (mode != -1)
1340 spi->mode = mode;
1341 pdata = (void *)spi->platform_data;
1342 } else if (displays[i].pdev) {
1343 p_device = displays[i].pdev;
1344 pdata = p_device->dev.platform_data;
1345 } else {
1346 pr_err(DRVNAME": broken displays array\n");
1347 return -EINVAL;
1348 }
1349
1350 pdata->rotate = rotate;
1351 if (bgr == 0)
1352 pdata->bgr = false;
1353 else if (bgr == 1)
1354 pdata->bgr = true;
1355 if (startbyte)
1356 pdata->startbyte = startbyte;
1357 if (gamma)
1358 pdata->gamma = gamma;
1359 pdata->display.debug = debug;
1360 if (fps)
1361 pdata->fps = fps;
1362 if (txbuflen)
1363 pdata->txbuflen = txbuflen;
1364 if (init_num)
1365 pdata->display.init_sequence = init;
1366 if (gpio)
1367 pdata->gpios = gpio;
1368 if (custom) {
1369 pdata->display.width = width;
1370 pdata->display.height = height;
1371 pdata->display.buswidth = buswidth;
1372 pdata->display.backlight = 1;
1373 }
1374
1375 if (displays[i].spi) {
1376 ret = fbtft_device_spi_device_register(spi);
1377 if (ret) {
1378 pr_err(DRVNAME \
1379 ": failed to register SPI device\n");
1380 return ret;
1381 }
1382 found = true;
1383 break;
1384 } else {
1385 ret = platform_device_register(p_device);
1386 if (ret < 0) {
1387 pr_err(DRVNAME \
1388 ": platform_device_register() returned %d\n",
1389 ret);
1390 return ret;
1391 }
1392 found = true;
1393 break;
1394 }
1395 }
1396 }
1397
1398 if (!found) {
1399 pr_err(DRVNAME": display not supported: '%s'\n", name);
1400 return -EINVAL;
1401 }
1402
1403 if (verbose && pdata && pdata->gpios) {
1404 gpio = pdata->gpios;
1405 pr_info(DRVNAME": GPIOS used by '%s':\n", name);
1406 found = false;
1407 while (verbose && gpio->name[0]) {
1408 pr_info(DRVNAME": '%s' = GPIO%d\n",
1409 gpio->name, gpio->gpio);
1410 gpio++;
1411 found = true;
1412 }
1413 if (!found)
1414 pr_info(DRVNAME": (none)\n");
1415 }
1416
1417 if (spi_device && (verbose > 1))
1418 pr_spi_devices();
1419 if (p_device && (verbose > 1))
1420 pr_p_devices();
1421
1422 return 0;
1423}
1424
1425static void __exit fbtft_device_exit(void)
1426{
1427 pr_debug(DRVNAME" - exit\n");
1428
1429 if (spi_device) {
1430 device_del(&spi_device->dev);
1431 kfree(spi_device);
1432 }
1433
1434 if (p_device)
1435 platform_device_unregister(p_device);
1436
1437}
1438
1439arch_initcall(fbtft_device_init);
1440module_exit(fbtft_device_exit);
1441
1442MODULE_DESCRIPTION("Add a FBTFT device.");
1443MODULE_AUTHOR("Noralf Tronnes");
1444MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c
new file mode 100644
index 000000000000..90832c36e557
--- /dev/null
+++ b/drivers/staging/fbtft/flexfb.c
@@ -0,0 +1,592 @@
1/*
2 * Generic FB driver for TFT LCD displays
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/vmalloc.h>
25#include <linux/gpio.h>
26#include <linux/spi/spi.h>
27#include <linux/delay.h>
28
29#include "fbtft.h"
30
31#define DRVNAME "flexfb"
32
33
34static char *chip;
35module_param(chip, charp, 0);
36MODULE_PARM_DESC(chip, "LCD controller");
37
38static unsigned int width;
39module_param(width, uint, 0);
40MODULE_PARM_DESC(width, "Display width");
41
42static unsigned int height;
43module_param(height, uint, 0);
44MODULE_PARM_DESC(height, "Display height");
45
46static int init[512];
47static int init_num;
48module_param_array(init, int, &init_num, 0);
49MODULE_PARM_DESC(init, "Init sequence");
50
51static unsigned int setaddrwin;
52module_param(setaddrwin, uint, 0);
53MODULE_PARM_DESC(setaddrwin, "Which set_addr_win() implementation to use");
54
55static unsigned int buswidth = 8;
56module_param(buswidth, uint, 0);
57MODULE_PARM_DESC(buswidth, "Width of databus (default: 8)");
58
59static unsigned int regwidth = 8;
60module_param(regwidth, uint, 0);
61MODULE_PARM_DESC(regwidth, "Width of controller register (default: 8)");
62
63static bool nobacklight;
64module_param(nobacklight, bool, 0);
65MODULE_PARM_DESC(nobacklight, "Turn off backlight functionality.");
66
67static bool latched;
68module_param(latched, bool, 0);
69MODULE_PARM_DESC(latched, "Use with latched 16-bit databus");
70
71
72static int *initp;
73static int initp_num;
74
75/* default init sequences */
76static int st7735r_init[] = { \
77-1,0x01,-2,150,-1,0x11,-2,500,-1,0xB1,0x01,0x2C,0x2D,-1,0xB2,0x01,0x2C,0x2D,-1,0xB3,0x01,0x2C,0x2D,0x01,0x2C,0x2D, \
78-1,0xB4,0x07,-1,0xC0,0xA2,0x02,0x84,-1,0xC1,0xC5,-1,0xC2,0x0A,0x00,-1,0xC3,0x8A,0x2A,-1,0xC4,0x8A,0xEE,-1,0xC5,0x0E, \
79-1,0x20,-1,0x36,0xC0,-1,0x3A,0x05,-1,0xE0,0x0f,0x1a,0x0f,0x18,0x2f,0x28,0x20,0x22,0x1f,0x1b,0x23,0x37,0x00,0x07,0x02,0x10, \
80-1,0xE1,0x0f,0x1b,0x0f,0x17,0x33,0x2c,0x29,0x2e,0x30,0x30,0x39,0x3f,0x00,0x07,0x03,0x10,-1,0x29,-2,100,-1,0x13,-2,10,-3 };
81
82static int ssd1289_init[] = { \
83-1,0x00,0x0001,-1,0x03,0xA8A4,-1,0x0C,0x0000,-1,0x0D,0x080C,-1,0x0E,0x2B00,-1,0x1E,0x00B7,-1,0x01,0x2B3F,-1,0x02,0x0600, \
84-1,0x10,0x0000,-1,0x11,0x6070,-1,0x05,0x0000,-1,0x06,0x0000,-1,0x16,0xEF1C,-1,0x17,0x0003,-1,0x07,0x0233,-1,0x0B,0x0000, \
85-1,0x0F,0x0000,-1,0x41,0x0000,-1,0x42,0x0000,-1,0x48,0x0000,-1,0x49,0x013F,-1,0x4A,0x0000,-1,0x4B,0x0000,-1,0x44,0xEF00, \
86-1,0x45,0x0000,-1,0x46,0x013F,-1,0x30,0x0707,-1,0x31,0x0204,-1,0x32,0x0204,-1,0x33,0x0502,-1,0x34,0x0507,-1,0x35,0x0204, \
87-1,0x36,0x0204,-1,0x37,0x0502,-1,0x3A,0x0302,-1,0x3B,0x0302,-1,0x23,0x0000,-1,0x24,0x0000,-1,0x25,0x8000,-1,0x4f,0x0000, \
88-1,0x4e,0x0000,-1,0x22,-3 };
89
90static int hx8340bn_init[] = { \
91-1,0xC1,0xFF,0x83,0x40,-1,0x11,-2,150,-1,0xCA,0x70,0x00,0xD9,-1,0xB0,0x01,0x11, \
92-1,0xC9,0x90,0x49,0x10,0x28,0x28,0x10,0x00,0x06,-2,20,-1,0xC2,0x60,0x71,0x01,0x0E,0x05,0x02,0x09,0x31,0x0A, \
93-1,0xC3,0x67,0x30,0x61,0x17,0x48,0x07,0x05,0x33,-2,10,-1,0xB5,0x35,0x20,0x45,-1,0xB4,0x33,0x25,0x4C,-2,10, \
94-1,0x3A,0x05,-1,0x29,-2,10,-3 };
95
96static int ili9225_init[] = { \
97-1,0x0001,0x011C,-1,0x0002,0x0100,-1,0x0003,0x1030,-1,0x0008,0x0808,-1,0x000C,0x0000,-1,0x000F,0x0A01,-1,0x0020,0x0000, \
98-1,0x0021,0x0000,-2,50,-1,0x0010,0x0A00,-1,0x0011,0x1038,-2,50,-1,0x0012,0x1121,-1,0x0013,0x004E,-1,0x0014,0x676F, \
99-1,0x0030,0x0000,-1,0x0031,0x00DB,-1,0x0032,0x0000,-1,0x0033,0x0000,-1,0x0034,0x00DB,-1,0x0035,0x0000,-1,0x0036,0x00AF, \
100-1,0x0037,0x0000,-1,0x0038,0x00DB,-1,0x0039,0x0000,-1,0x0050,0x0000,-1,0x0051,0x060A,-1,0x0052,0x0D0A,-1,0x0053,0x0303, \
101-1,0x0054,0x0A0D,-1,0x0055,0x0A06,-1,0x0056,0x0000,-1,0x0057,0x0303,-1,0x0058,0x0000,-1,0x0059,0x0000,-2,50, \
102-1,0x0007,0x1017,-2,50,-3 };
103
104static int ili9320_init[] = { \
105-1,0x00E5,0x8000,-1,0x0000,0x0001,-1,0x0001,0x0100,-1,0x0002,0x0700,-1,0x0003,0x1030,-1,0x0004,0x0000,-1,0x0008,0x0202, \
106-1,0x0009,0x0000,-1,0x000A,0x0000,-1,0x000C,0x0000,-1,0x000D,0x0000,-1,0x000F,0x0000,-1,0x0010,0x0000,-1,0x0011,0x0007, \
107-1,0x0012,0x0000,-1,0x0013,0x0000,-2,200,-1,0x0010,0x17B0,-1,0x0011,0x0031,-2,50,-1,0x0012,0x0138,-2,50,-1,0x0013,0x1800, \
108-1,0x0029,0x0008,-2,50,-1,0x0020,0x0000,-1,0x0021,0x0000,-1,0x0030,0x0000,-1,0x0031,0x0505,-1,0x0032,0x0004, \
109-1,0x0035,0x0006,-1,0x0036,0x0707,-1,0x0037,0x0105,-1,0x0038,0x0002,-1,0x0039,0x0707,-1,0x003C,0x0704,-1,0x003D,0x0807, \
110-1,0x0050,0x0000,-1,0x0051,0x00EF,-1,0x0052,0x0000,-1,0x0053,0x013F,-1,0x0060,0x2700,-1,0x0061,0x0001,-1,0x006A,0x0000, \
111-1,0x0080,0x0000,-1,0x0081,0x0000,-1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000,-1,0x0085,0x0000,-1,0x0090,0x0010, \
112-1,0x0092,0x0000,-1,0x0093,0x0003,-1,0x0095,0x0110,-1,0x0097,0x0000,-1,0x0098,0x0000,-1,0x0007,0x0173,-3 };
113
114static int ili9325_init[] = { \
115-1,0x00E3,0x3008,-1,0x00E7,0x0012,-1,0x00EF,0x1231,-1,0x0001,0x0100,-1,0x0002,0x0700,-1,0x0003,0x1030,-1,0x0004,0x0000, \
116-1,0x0008,0x0207,-1,0x0009,0x0000,-1,0x000A,0x0000,-1,0x000C,0x0000,-1,0x000D,0x0000,-1,0x000F,0x0000,-1,0x0010,0x0000, \
117-1,0x0011,0x0007,-1,0x0012,0x0000,-1,0x0013,0x0000,-2,200,-1,0x0010,0x1690,-1,0x0011,0x0223,-2,50,-1,0x0012,0x000D,-2,50, \
118-1,0x0013,0x1200,-1,0x0029,0x000A,-1,0x002B,0x000C,-2,50,-1,0x0020,0x0000,-1,0x0021,0x0000,-1,0x0030,0x0000, \
119-1,0x0031,0x0506,-1,0x0032,0x0104,-1,0x0035,0x0207,-1,0x0036,0x000F,-1,0x0037,0x0306,-1,0x0038,0x0102,-1,0x0039,0x0707, \
120-1,0x003C,0x0702,-1,0x003D,0x1604,-1,0x0050,0x0000,-1,0x0051,0x00EF,-1,0x0052,0x0000,-1,0x0053,0x013F,-1,0x0060,0xA700, \
121-1,0x0061,0x0001,-1,0x006A,0x0000,-1,0x0080,0x0000,-1,0x0081,0x0000,-1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000, \
122-1,0x0085,0x0000,-1,0x0090,0x0010,-1,0x0092,0x0600,-1,0x0007,0x0133,-3 };
123
124static int ili9341_init[] = { \
125-1,0x28,-2,20,-1,0xCF,0x00,0x83,0x30,-1,0xED,0x64,0x03,0x12,0x81,-1,0xE8,0x85,0x01,0x79, \
126-1,0xCB,0x39,0x2c,0x00,0x34,0x02,-1,0xF7,0x20,-1,0xEA,0x00,0x00,-1,0xC0,0x26,-1,0xC1,0x11, \
127-1,0xC5,0x35,0x3E,-1,0xC7,0xBE,-1,0xB1,0x00,0x1B,-1,0xB6,0x0a,0x82,0x27,0x00,-1,0xB7,0x07, \
128-1,0x3A,0x55,-1,0x36,0x48,-1,0x11,-2,120,-1,0x29,-2,20,-3 };
129
130static int ssd1351_init[] = { -1,0xfd,0x12,-1,0xfd,0xb1,-1,0xae,-1,0xb3,0xf1,-1,0xca,0x7f,-1,0xa0,0x74, \
131 -1,0x15,0x00,0x7f,-1,0x75,0x00,0x7f,-1,0xa1,0x00,-1,0xa2,0x00,-1,0xb5,0x00, \
132 -1,0xab,0x01,-1,0xb1,0x32,-1,0xb4,0xa0,0xb5,0x55,-1,0xbb,0x17,-1,0xbe,0x05, \
133 -1,0xc1,0xc8,0x80,0xc8,-1,0xc7,0x0f,-1,0xb6,0x01,-1,0xa6,-1,0xaf,-3 };
134
135
136/* ili9320, ili9325 */
137static void flexfb_set_addr_win_1(struct fbtft_par *par, int xs, int ys, int xe, int ye)
138{
139 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
140 switch (par->info->var.rotate) {
141 /* R20h = Horizontal GRAM Start Address */
142 /* R21h = Vertical GRAM Start Address */
143 case 0:
144 write_reg(par, 0x0020, xs);
145 write_reg(par, 0x0021, ys);
146 break;
147 case 180:
148 write_reg(par, 0x0020, width - 1 - xs);
149 write_reg(par, 0x0021, height - 1 - ys);
150 break;
151 case 270:
152 write_reg(par, 0x0020, width - 1 - ys);
153 write_reg(par, 0x0021, xs);
154 break;
155 case 90:
156 write_reg(par, 0x0020, ys);
157 write_reg(par, 0x0021, height - 1 - xs);
158 break;
159 }
160 write_reg(par, 0x0022); /* Write Data to GRAM */
161}
162
163/* ssd1289 */
164static void flexfb_set_addr_win_2(struct fbtft_par *par, int xs, int ys, int xe, int ye)
165{
166 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
167
168 switch (par->info->var.rotate) {
169 /* R4Eh - Set GDDRAM X address counter */
170 /* R4Fh - Set GDDRAM Y address counter */
171 case 0:
172 write_reg(par, 0x4e, xs);
173 write_reg(par, 0x4f, ys);
174 break;
175 case 180:
176 write_reg(par, 0x4e, par->info->var.xres - 1 - xs);
177 write_reg(par, 0x4f, par->info->var.yres - 1 - ys);
178 break;
179 case 270:
180 write_reg(par, 0x4e, par->info->var.yres - 1 - ys);
181 write_reg(par, 0x4f, xs);
182 break;
183 case 90:
184 write_reg(par, 0x4e, ys);
185 write_reg(par, 0x4f, par->info->var.xres - 1 - xs);
186 break;
187 }
188
189 /* R22h - RAM data write */
190 write_reg(par, 0x22, 0);
191}
192
193/* ssd1351 */
194static void set_addr_win_3(struct fbtft_par *par, int xs, int ys, int xe, int ye)
195{
196 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
197
198 write_reg(par, 0x15, xs, xe);
199 write_reg(par, 0x75, ys, ye);
200 write_reg(par, 0x5C);
201}
202
203static int flexfb_verify_gpios_dc(struct fbtft_par *par)
204{
205 fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
206
207 if (par->gpio.dc < 0) {
208 dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
209 return -EINVAL;
210 }
211
212 return 0;
213}
214
215static int flexfb_verify_gpios_db(struct fbtft_par *par)
216{
217 int i;
218 int num_db = buswidth;
219
220 fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
221
222 if (par->gpio.dc < 0) {
223 dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
224 return -EINVAL;
225 }
226 if (par->gpio.wr < 0) {
227 dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n");
228 return -EINVAL;
229 }
230 if (latched && (par->gpio.latch < 0)) {
231 dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n");
232 return -EINVAL;
233 }
234 if (latched)
235 num_db=buswidth/2;
236 for (i=0;i < num_db;i++) {
237 if (par->gpio.db[i] < 0) {
238 dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i);
239 return -EINVAL;
240 }
241 }
242
243 return 0;
244}
245
246static struct fbtft_display flex_display = { };
247
248static int flexfb_probe_common(struct spi_device *sdev, struct platform_device *pdev)
249{
250 struct device *dev;
251 struct fb_info *info;
252 struct fbtft_par *par;
253 int ret;
254
255 initp = init;
256 initp_num = init_num;
257
258 if (sdev)
259 dev = &sdev->dev;
260 else
261 dev = &pdev->dev;
262
263 fbtft_init_dbg(dev, "%s(%s)\n", __func__, sdev ? "'SPI device'" : "'Platform device'");
264
265 if (chip) {
266
267 if (!strcmp(chip, "st7735r")) {
268 if (!width)
269 width = 128;
270 if (!height)
271 height = 160;
272 if (init_num == 0) {
273 initp = st7735r_init;
274 initp_num = ARRAY_SIZE(st7735r_init);
275 }
276
277
278 } else if (!strcmp(chip, "hx8340bn")) {
279 if (!width)
280 width = 176;
281 if (!height)
282 height = 220;
283 setaddrwin = 0;
284 if (init_num == 0) {
285 initp = hx8340bn_init;
286 initp_num = ARRAY_SIZE(hx8340bn_init);
287 }
288
289
290 } else if (!strcmp(chip, "ili9225")) {
291 if (!width)
292 width = 176;
293 if (!height)
294 height = 220;
295 setaddrwin = 0;
296 regwidth = 16;
297 if (init_num == 0) {
298 initp = ili9225_init;
299 initp_num = ARRAY_SIZE(ili9225_init);
300 }
301
302
303
304 } else if (!strcmp(chip, "ili9320")) {
305 if (!width)
306 width = 240;
307 if (!height)
308 height = 320;
309 setaddrwin = 1;
310 regwidth = 16;
311 if (init_num == 0) {
312 initp = ili9320_init;
313 initp_num = ARRAY_SIZE(ili9320_init);
314 }
315
316
317 } else if (!strcmp(chip, "ili9325")) {
318 if (!width)
319 width = 240;
320 if (!height)
321 height = 320;
322 setaddrwin = 1;
323 regwidth = 16;
324 if (init_num == 0) {
325 initp = ili9325_init;
326 initp_num = ARRAY_SIZE(ili9325_init);
327 }
328
329 } else if (!strcmp(chip, "ili9341")) {
330 if (!width)
331 width = 240;
332 if (!height)
333 height = 320;
334 setaddrwin = 0;
335 regwidth = 8;
336 if (init_num == 0) {
337 initp = ili9341_init;
338 initp_num = ARRAY_SIZE(ili9341_init);
339 }
340
341
342 } else if (!strcmp(chip, "ssd1289")) {
343 if (!width)
344 width = 240;
345 if (!height)
346 height = 320;
347 setaddrwin = 2;
348 regwidth = 16;
349 if (init_num == 0) {
350 initp = ssd1289_init;
351 initp_num = ARRAY_SIZE(ssd1289_init);
352 }
353
354
355
356 } else if (!strcmp(chip, "ssd1351")) {
357 if (!width)
358 width = 128;
359 if (!height)
360 height = 128;
361 setaddrwin = 3;
362 if (init_num == 0) {
363 initp = ssd1351_init;
364 initp_num = ARRAY_SIZE(ssd1351_init);
365 }
366 } else {
367 dev_err(dev, "chip=%s is not supported\n", chip);
368 return -EINVAL;
369 }
370 }
371
372 if (width == 0 || height == 0) {
373 dev_err(dev, "argument(s) missing: width and height has to be set.\n");
374 return -EINVAL;
375 }
376 flex_display.width = width;
377 flex_display.height = height;
378 fbtft_init_dbg(dev, "Display resolution: %dx%d\n", width, height);
379 fbtft_init_dbg(dev, "chip = %s\n", chip ? chip : "not set");
380 fbtft_init_dbg(dev, "setaddrwin = %d\n", setaddrwin);
381 fbtft_init_dbg(dev, "regwidth = %d\n", regwidth);
382 fbtft_init_dbg(dev, "buswidth = %d\n", buswidth);
383
384 info = fbtft_framebuffer_alloc(&flex_display, dev);
385 if (!info)
386 return -ENOMEM;
387
388 par = info->par;
389 if (sdev)
390 par->spi = sdev;
391 else
392 par->pdev = pdev;
393 if (!par->init_sequence)
394 par->init_sequence = initp;
395 par->fbtftops.init_display = fbtft_init_display;
396
397 /* registerwrite functions */
398 switch (regwidth) {
399 case 8:
400 par->fbtftops.write_register = fbtft_write_reg8_bus8;
401 break;
402 case 16:
403 par->fbtftops.write_register = fbtft_write_reg16_bus8;
404 break;
405 default:
406 dev_err(dev, "argument 'regwidth': %d is not supported.\n", regwidth);
407 return -EINVAL;
408 }
409
410 /* bus functions */
411 if (sdev) {
412 par->fbtftops.write = fbtft_write_spi;
413 switch (buswidth) {
414 case 8:
415 par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
416 if (!par->startbyte)
417 par->fbtftops.verify_gpios = flexfb_verify_gpios_dc;
418 break;
419 case 9:
420 if (regwidth == 16) {
421 dev_err(dev, "argument 'regwidth': %d is not supported with buswidth=%d and SPI.\n", regwidth, buswidth);
422 return -EINVAL;
423 }
424 par->fbtftops.write_register = fbtft_write_reg8_bus9;
425 par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
426 sdev->bits_per_word=9;
427 ret = sdev->master->setup(sdev);
428 if (ret) {
429 dev_warn(dev,
430 "9-bit SPI not available, emulating using 8-bit.\n");
431 sdev->bits_per_word = 8;
432 ret = sdev->master->setup(sdev);
433 if (ret)
434 goto out_release;
435 /* allocate buffer with room for dc bits */
436 par->extra = devm_kzalloc(par->info->device,
437 par->txbuf.len + (par->txbuf.len / 8) + 8,
438 GFP_KERNEL);
439 if (!par->extra) {
440 ret = -ENOMEM;
441 goto out_release;
442 }
443 par->fbtftops.write = fbtft_write_spi_emulate_9;
444 }
445 break;
446 default:
447 dev_err(dev, "argument 'buswidth': %d is not supported with SPI.\n", buswidth);
448 return -EINVAL;
449 }
450 } else {
451 par->fbtftops.verify_gpios = flexfb_verify_gpios_db;
452 switch (buswidth) {
453 case 8:
454 par->fbtftops.write = fbtft_write_gpio8_wr;
455 par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
456 break;
457 case 16:
458 par->fbtftops.write_register = fbtft_write_reg16_bus16;
459 if (latched)
460 par->fbtftops.write = fbtft_write_gpio16_wr_latched;
461 else
462 par->fbtftops.write = fbtft_write_gpio16_wr;
463 par->fbtftops.write_vmem = fbtft_write_vmem16_bus16;
464 break;
465 default:
466 dev_err(dev, "argument 'buswidth': %d is not supported with parallel.\n", buswidth);
467 return -EINVAL;
468 }
469 }
470
471 /* set_addr_win function */
472 switch (setaddrwin) {
473 case 0:
474 /* use default */
475 break;
476 case 1:
477 par->fbtftops.set_addr_win = flexfb_set_addr_win_1;
478 break;
479 case 2:
480 par->fbtftops.set_addr_win = flexfb_set_addr_win_2;
481 break;
482 case 3:
483 par->fbtftops.set_addr_win = set_addr_win_3;
484 break;
485 default:
486 dev_err(dev, "argument 'setaddrwin': unknown value %d.\n", setaddrwin);
487 return -EINVAL;
488 }
489
490 if (!nobacklight)
491 par->fbtftops.register_backlight = fbtft_register_backlight;
492
493 ret = fbtft_register_framebuffer(info);
494 if (ret < 0)
495 goto out_release;
496
497 return 0;
498
499out_release:
500 fbtft_framebuffer_release(info);
501
502 return ret;
503}
504
505static int flexfb_remove_common(struct device *dev, struct fb_info *info)
506{
507 struct fbtft_par *par;
508
509 if (!info)
510 return -EINVAL;
511 par = info->par;
512 if (par)
513 fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par,
514 "%s()\n", __func__);
515 fbtft_unregister_framebuffer(info);
516 fbtft_framebuffer_release(info);
517
518 return 0;
519}
520
521static int flexfb_probe_spi(struct spi_device *spi)
522{
523 return flexfb_probe_common(spi, NULL);
524}
525
526static int flexfb_remove_spi(struct spi_device *spi)
527{
528 struct fb_info *info = spi_get_drvdata(spi);
529
530 return flexfb_remove_common(&spi->dev, info);
531}
532
533static int flexfb_probe_pdev(struct platform_device *pdev)
534{
535 return flexfb_probe_common(NULL, pdev);
536}
537
538static int flexfb_remove_pdev(struct platform_device *pdev)
539{
540 struct fb_info *info = platform_get_drvdata(pdev);
541
542 return flexfb_remove_common(&pdev->dev, info);
543}
544
545static struct spi_driver flexfb_spi_driver = {
546 .driver = {
547 .name = DRVNAME,
548 .owner = THIS_MODULE,
549 },
550 .probe = flexfb_probe_spi,
551 .remove = flexfb_remove_spi,
552};
553
554static const struct platform_device_id flexfb_platform_ids[] = {
555 { "flexpfb", 0 },
556 { },
557};
558
559static struct platform_driver flexfb_platform_driver = {
560 .driver = {
561 .name = DRVNAME,
562 },
563 .id_table = flexfb_platform_ids,
564 .probe = flexfb_probe_pdev,
565 .remove = flexfb_remove_pdev,
566};
567
568static int __init flexfb_init(void)
569{
570 int ret, ret2;
571
572 ret = spi_register_driver(&flexfb_spi_driver);
573 ret2 = platform_driver_register(&flexfb_platform_driver);
574 if (ret < 0)
575 return ret;
576 return ret2;
577}
578
579static void __exit flexfb_exit(void)
580{
581 spi_unregister_driver(&flexfb_spi_driver);
582 platform_driver_unregister(&flexfb_platform_driver);
583}
584
585/* ------------------------------------------------------------------------- */
586
587module_init(flexfb_init);
588module_exit(flexfb_exit);
589
590MODULE_DESCRIPTION("Generic FB driver for TFT LCD displays");
591MODULE_AUTHOR("Noralf Tronnes");
592MODULE_LICENSE("GPL");
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
index d5475b7270a8..017c3b92f51b 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
@@ -172,11 +172,11 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
172 spin_lock_irqsave(&info->dpram_lock, flags); 172 spin_lock_irqsave(&info->dpram_lock, flags);
173 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); 173 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
174 /* check if we want to read upper or lower 32-bit word */ 174 /* check if we want to read upper or lower 32-bit word */
175 if (Index) { 175 if (Index)
176 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL); 176 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
177 } else { 177 else
178 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH); 178 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
179 } 179
180 spin_unlock_irqrestore(&info->dpram_lock, flags); 180 spin_unlock_irqrestore(&info->dpram_lock, flags);
181 181
182 return data; 182 return data;
@@ -204,11 +204,11 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
204 /* Provide mutual exclusive access while reading ASIC registers. */ 204 /* Provide mutual exclusive access while reading ASIC registers. */
205 spin_lock_irqsave(&info->dpram_lock, flags); 205 spin_lock_irqsave(&info->dpram_lock, flags);
206 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); 206 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
207 if (Index) { 207 if (Index)
208 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value); 208 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
209 } else { 209 else
210 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value); 210 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
211 } 211
212 spin_unlock_irqrestore(&info->dpram_lock, flags); 212 spin_unlock_irqrestore(&info->dpram_lock, flags);
213} 213}
214 214
@@ -440,9 +440,8 @@ static int ft1000_reset_card(struct net_device *dev)
440 tempword = 440 tempword =
441 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE, 441 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE,
442 FT1000_MAG_DPRAM_FEFE_INDX); 442 FT1000_MAG_DPRAM_FEFE_INDX);
443 if (tempword == 0xfefe) { 443 if (tempword == 0xfefe)
444 break; 444 break;
445 }
446 mdelay(20); 445 mdelay(20);
447 } 446 }
448 447
@@ -570,12 +569,12 @@ static void ft1000_hbchk(u_long data)
570 pr_debug("hi_ho value = 0x%x\n", tempword); 569 pr_debug("hi_ho value = 0x%x\n", tempword);
571 /* Let's perform another check if ho is not detected */ 570 /* Let's perform another check if ho is not detected */
572 if (tempword != ho) { 571 if (tempword != ho) {
573 if (info->AsicID == ELECTRABUZZ_ID) { 572 if (info->AsicID == ELECTRABUZZ_ID)
574 tempword = ft1000_read_dpram(dev, FT1000_HI_HO); 573 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
575 } 574 else
576 else { 575 tempword = ntohs(ft1000_read_dpram_mag_16(dev,
577 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX)); 576 FT1000_MAG_HI_HO,
578 } 577 FT1000_MAG_HI_HO_INDX));
579 } 578 }
580 if (tempword != ho) { 579 if (tempword != ho) {
581 pr_info("heartbeat failed - no ho detected\n"); 580 pr_info("heartbeat failed - no ho detected\n");
@@ -621,9 +620,9 @@ static void ft1000_hbchk(u_long data)
621 620
622 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); 621 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
623 /* Let's check doorbell again if fail */ 622 /* Let's check doorbell again if fail */
624 if (tempword & FT1000_DB_HB) { 623 if (tempword & FT1000_DB_HB)
625 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); 624 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
626 } 625
627 if (tempword & FT1000_DB_HB) { 626 if (tempword & FT1000_DB_HB) {
628 pr_info("heartbeat doorbell not clear by firmware\n"); 627 pr_info("heartbeat doorbell not clear by firmware\n");
629 if (info->AsicID == ELECTRABUZZ_ID) { 628 if (info->AsicID == ELECTRABUZZ_ID) {
@@ -686,19 +685,15 @@ static void ft1000_hbchk(u_long data)
686 } 685 }
687 /* Let's write hi again if fail */ 686 /* Let's write hi again if fail */
688 if (tempword != hi) { 687 if (tempword != hi) {
689 if (info->AsicID == ELECTRABUZZ_ID) { 688 if (info->AsicID == ELECTRABUZZ_ID)
690 ft1000_write_dpram(dev, FT1000_HI_HO, hi); 689 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
691 } 690 else
692 else {
693 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX); 691 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
694 }
695 692
696 if (info->AsicID == ELECTRABUZZ_ID) { 693 if (info->AsicID == ELECTRABUZZ_ID)
697 tempword = ft1000_read_dpram(dev, FT1000_HI_HO); 694 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
698 } 695 else
699 else {
700 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX)); 696 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
701 }
702 697
703 } 698 }
704 699
@@ -770,9 +765,8 @@ static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size,
770 765
771 size += sizeof(struct pseudo_hdr); 766 size += sizeof(struct pseudo_hdr);
772 /* check for odd byte and increment to 16-bit word align value */ 767 /* check for odd byte and increment to 16-bit word align value */
773 if ((size & 0x0001)) { 768 if ((size & 0x0001))
774 size++; 769 size++;
775 }
776 pr_debug("total length = %d\n", size); 770 pr_debug("total length = %d\n", size);
777 pr_debug("length = %d\n", ntohs(*ptempbuffer)); 771 pr_debug("length = %d\n", ntohs(*ptempbuffer));
778 /* 772 /*
@@ -915,9 +909,8 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
915 * Calculate pseudo header checksum 909 * Calculate pseudo header checksum
916 */ 910 */
917 tempword = *ppseudohdr++; 911 tempword = *ppseudohdr++;
918 for (i = 1; i < 7; i++) { 912 for (i = 1; i < 7; i++)
919 tempword ^= *ppseudohdr++; 913 tempword ^= *ppseudohdr++;
920 }
921 if ((tempword != *ppseudohdr)) { 914 if ((tempword != *ppseudohdr)) {
922 pr_debug("Pseudo header checksum mismatch\n"); 915 pr_debug("Pseudo header checksum mismatch\n");
923 /* Drop this message */ 916 /* Drop this message */
@@ -957,12 +950,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
957 u16 wrd; 950 u16 wrd;
958 } convert; 951 } convert;
959 952
960 if (info->AsicID == ELECTRABUZZ_ID) { 953 if (info->AsicID == ELECTRABUZZ_ID)
961 tempword = FT1000_DPRAM_RX_BASE+2; 954 tempword = FT1000_DPRAM_RX_BASE+2;
962 } 955 else
963 else {
964 tempword = FT1000_DPRAM_MAG_RX_BASE; 956 tempword = FT1000_DPRAM_MAG_RX_BASE;
965 } 957
966 if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) { 958 if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) {
967 959
968 /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ 960 /* Get the message type which is total_len + PSEUDO header + msgtype + message body */
@@ -982,9 +974,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
982 while (tempword & FT1000_DB_DPRAM_TX) { 974 while (tempword & FT1000_DB_DPRAM_TX) {
983 mdelay(5); 975 mdelay(5);
984 i++; 976 i++;
985 if (i == 10) { 977 if (i == 10)
986 break; 978 break;
987 }
988 } 979 }
989 ptr = 980 ptr =
990 list_entry(info->prov_list.next, 981 list_entry(info->prov_list.next,
@@ -1039,8 +1030,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
1039 info->ConTm = 0; 1030 info->ConTm = 0;
1040 } 1031 }
1041 } 1032 }
1042 } 1033 } else {
1043 else {
1044 pr_debug("Media is down\n"); 1034 pr_debug("Media is down\n");
1045 if (info->mediastate == 1) { 1035 if (info->mediastate == 1) {
1046 info->mediastate = 0; 1036 info->mediastate = 0;
@@ -1105,9 +1095,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
1105 mdelay(10); 1095 mdelay(10);
1106 tempword = 1096 tempword =
1107 ft1000_read_reg(dev, FT1000_REG_DOORBELL); 1097 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1108 if (tempword & FT1000_DB_DPRAM_TX) { 1098 if (tempword & FT1000_DB_DPRAM_TX)
1109 mdelay(10); 1099 mdelay(10);
1110 }
1111 } 1100 }
1112 1101
1113 if ((tempword & FT1000_DB_DPRAM_TX) == 0) { 1102 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
@@ -1134,9 +1123,9 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
1134 ppseudo_hdr->portsrc = 0; 1123 ppseudo_hdr->portsrc = 0;
1135 /* Calculate new checksum */ 1124 /* Calculate new checksum */
1136 ppseudo_hdr->checksum = *pmsg++; 1125 ppseudo_hdr->checksum = *pmsg++;
1137 for (i = 1; i < 7; i++) { 1126 for (i = 1; i < 7; i++)
1138 ppseudo_hdr->checksum ^= *pmsg++; 1127 ppseudo_hdr->checksum ^= *pmsg++;
1139 } 1128
1140 info->DSPInfoBlk[8] = 0x7200; 1129 info->DSPInfoBlk[8] = 0x7200;
1141 info->DSPInfoBlk[9] = 1130 info->DSPInfoBlk[9] =
1142 htons(info->DSPInfoBlklen); 1131 htons(info->DSPInfoBlklen);
@@ -1156,9 +1145,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
1156 mdelay(10); 1145 mdelay(10);
1157 tempword = 1146 tempword =
1158 ft1000_read_reg(dev, FT1000_REG_DOORBELL); 1147 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1159 if (tempword & FT1000_DB_DPRAM_TX) { 1148 if (tempword & FT1000_DB_DPRAM_TX)
1160 mdelay(10); 1149 mdelay(10);
1161 }
1162 } 1150 }
1163 1151
1164 if ((tempword & FT1000_DB_DPRAM_TX) == 0) { 1152 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
@@ -1184,9 +1172,9 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
1184 ppseudo_hdr->portsrc = 0; 1172 ppseudo_hdr->portsrc = 0;
1185 /* Calculate new checksum */ 1173 /* Calculate new checksum */
1186 ppseudo_hdr->checksum = *pmsg++; 1174 ppseudo_hdr->checksum = *pmsg++;
1187 for (i = 1; i < 7; i++) { 1175 for (i = 1; i < 7; i++)
1188 ppseudo_hdr->checksum ^= *pmsg++; 1176 ppseudo_hdr->checksum ^= *pmsg++;
1189 } 1177
1190 pmsg = (u16 *)&tempbuffer[16]; 1178 pmsg = (u16 *)&tempbuffer[16];
1191 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); 1179 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1192 *pmsg++ = htons(0x000e); 1180 *pmsg++ = htons(0x000e);
@@ -1508,9 +1496,8 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
1508 tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR); 1496 tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1509 pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword); 1497 pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
1510 } 1498 }
1511 if (DrvErrNum) { 1499 if (DrvErrNum)
1512 pcmcia->PktIntfErr++; 1500 pcmcia->PktIntfErr++;
1513 }
1514 } 1501 }
1515} 1502}
1516 1503
@@ -1567,9 +1554,9 @@ static int ft1000_copy_up_pkt(struct net_device *dev)
1567 if (skb == NULL) { 1554 if (skb == NULL) {
1568 pr_debug("No Network buffers available\n"); 1555 pr_debug("No Network buffers available\n");
1569 /* Read High word to complete 32 bit access */ 1556 /* Read High word to complete 32 bit access */
1570 if (info->AsicID == MAGNEMITE_ID) { 1557 if (info->AsicID == MAGNEMITE_ID)
1571 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); 1558 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1572 } 1559
1573 ft1000_flush_fifo(dev, 0); 1560 ft1000_flush_fifo(dev, 0);
1574 info->stats.rx_errors++; 1561 info->stats.rx_errors++;
1575 return FAILURE; 1562 return FAILURE;
@@ -1673,9 +1660,8 @@ static int ft1000_copy_up_pkt(struct net_device *dev)
1673 } 1660 }
1674 1661
1675 pr_debug("Data passed to Protocol layer:\n"); 1662 pr_debug("Data passed to Protocol layer:\n");
1676 for (i = 0; i < len + 12; i++) { 1663 for (i = 0; i < len + 12; i++)
1677 pr_debug("Protocol Data: 0x%x\n", *ptemp++); 1664 pr_debug("Protocol Data: 0x%x\n", *ptemp++);
1678 }
1679 1665
1680 skb->dev = dev; 1666 skb->dev = dev;
1681 skb->protocol = eth_type_trans(skb, dev); 1667 skb->protocol = eth_type_trans(skb, dev);
@@ -1729,21 +1715,16 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
1729 /* Check if there is room on the FIFO */ 1715 /* Check if there is room on the FIFO */
1730 if (len > ft1000_read_fifo_len(dev)) { 1716 if (len > ft1000_read_fifo_len(dev)) {
1731 udelay(10); 1717 udelay(10);
1732 if (len > ft1000_read_fifo_len(dev)) { 1718 if (len > ft1000_read_fifo_len(dev))
1733 udelay(20); 1719 udelay(20);
1734 } 1720 if (len > ft1000_read_fifo_len(dev))
1735 if (len > ft1000_read_fifo_len(dev)) {
1736 udelay(20); 1721 udelay(20);
1737 } 1722 if (len > ft1000_read_fifo_len(dev))
1738 if (len > ft1000_read_fifo_len(dev)) {
1739 udelay(20); 1723 udelay(20);
1740 } 1724 if (len > ft1000_read_fifo_len(dev))
1741 if (len > ft1000_read_fifo_len(dev)) {
1742 udelay(20); 1725 udelay(20);
1743 } 1726 if (len > ft1000_read_fifo_len(dev))
1744 if (len > ft1000_read_fifo_len(dev)) {
1745 udelay(20); 1727 udelay(20);
1746 }
1747 if (len > ft1000_read_fifo_len(dev)) { 1728 if (len > ft1000_read_fifo_len(dev)) {
1748 pr_debug("Transmit FIFO is full - pkt drop\n"); 1729 pr_debug("Transmit FIFO is full - pkt drop\n");
1749 info->stats.tx_errors++; 1730 info->stats.tx_errors++;
@@ -1751,11 +1732,11 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
1751 } 1732 }
1752 } 1733 }
1753 /* Create pseudo header and send pseudo/ip to hardware */ 1734 /* Create pseudo header and send pseudo/ip to hardware */
1754 if (info->AsicID == ELECTRABUZZ_ID) { 1735 if (info->AsicID == ELECTRABUZZ_ID)
1755 pseudo.blk.length = len; 1736 pseudo.blk.length = len;
1756 } else { 1737 else
1757 pseudo.blk.length = ntohs(len); 1738 pseudo.blk.length = ntohs(len);
1758 } 1739
1759 pseudo.blk.source = DSPID; /* Need to swap to get in correct order */ 1740 pseudo.blk.source = DSPID; /* Need to swap to get in correct order */
1760 pseudo.blk.destination = HOSTID; 1741 pseudo.blk.destination = HOSTID;
1761 pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */ 1742 pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */
@@ -1768,9 +1749,8 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
1768 pseudo.blk.qos_class = 0; 1749 pseudo.blk.qos_class = 0;
1769 /* Calculate pseudo header checksum */ 1750 /* Calculate pseudo header checksum */
1770 pseudo.blk.checksum = pseudo.buff[0]; 1751 pseudo.blk.checksum = pseudo.buff[0];
1771 for (i = 1; i < 7; i++) { 1752 for (i = 1; i < 7; i++)
1772 pseudo.blk.checksum ^= pseudo.buff[i]; 1753 pseudo.blk.checksum ^= pseudo.buff[i];
1773 }
1774 1754
1775 /* Production Mode */ 1755 /* Production Mode */
1776 if (info->AsicID == ELECTRABUZZ_ID) { 1756 if (info->AsicID == ELECTRABUZZ_ID) {
@@ -1835,9 +1815,8 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
1835 1815
1836 plong = (u32 *)packet; 1816 plong = (u32 *)packet;
1837 /* Write PPP type + IP Packet into Downlink FIFO */ 1817 /* Write PPP type + IP Packet into Downlink FIFO */
1838 for (i = 0; i < (len >> 2); i++) { 1818 for (i = 0; i < (len >> 2); i++)
1839 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); 1819 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1840 }
1841 1820
1842 /* Check for odd alignment */ 1821 /* Check for odd alignment */
1843 if (len & 0x0003) { 1822 if (len & 0x0003) {
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
index d12cfc9aa32a..f0ac43838461 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
@@ -332,15 +332,15 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
332 332
333 pr_debug("enter card_send_command... size=%d\n", size); 333 pr_debug("enter card_send_command... size=%d\n", size);
334 334
335 ret = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
336 if (ret)
337 return ret;
338
335 commandbuf = kmalloc(size + 2, GFP_KERNEL); 339 commandbuf = kmalloc(size + 2, GFP_KERNEL);
336 if (!commandbuf) 340 if (!commandbuf)
337 return -ENOMEM; 341 return -ENOMEM;
338 memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size); 342 memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size);
339 343
340 ret = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
341 if (ret)
342 return ret;
343
344 if (temp & 0x0100) 344 if (temp & 0x0100)
345 usleep_range(900, 1100); 345 usleep_range(900, 1100);
346 346
diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
index 73eede163820..7c4a77bb94aa 100644
--- a/drivers/staging/gdm724x/gdm_lte.c
+++ b/drivers/staging/gdm724x/gdm_lte.c
@@ -281,7 +281,8 @@ static int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type)
281 icmp6_out.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT; 281 icmp6_out.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
282 icmp6_out.icmp6_code = 0; 282 icmp6_out.icmp6_code = 0;
283 icmp6_out.icmp6_cksum = 0; 283 icmp6_out.icmp6_cksum = 0;
284 icmp6_out.icmp6_dataun.un_data32[0] = htonl(0x60000000); /* R=0, S=1, O=1 */ 284 /* R=0, S=1, O=1 */
285 icmp6_out.icmp6_dataun.un_data32[0] = htonl(0x60000000);
285 286
286 ns = (struct neighbour_solicitation *) 287 ns = (struct neighbour_solicitation *)
287 (skb_in->data + mac_header_len + 288 (skb_in->data + mac_header_len +
diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c
index b5b063a738f8..d1ab996b3305 100644
--- a/drivers/staging/gdm724x/gdm_mux.c
+++ b/drivers/staging/gdm724x/gdm_mux.c
@@ -220,7 +220,7 @@ static int up_to_host(struct mux_rx *r)
220static void do_rx(struct work_struct *work) 220static void do_rx(struct work_struct *work)
221{ 221{
222 struct mux_dev *mux_dev = 222 struct mux_dev *mux_dev =
223 container_of(work, struct mux_dev , work_rx.work); 223 container_of(work, struct mux_dev, work_rx.work);
224 struct mux_rx *r; 224 struct mux_rx *r;
225 struct rx_cxt *rx = (struct rx_cxt *)&mux_dev->rx; 225 struct rx_cxt *rx = (struct rx_cxt *)&mux_dev->rx;
226 unsigned long flags; 226 unsigned long flags;
diff --git a/drivers/staging/gs_fpgaboot/io.c b/drivers/staging/gs_fpgaboot/io.c
index b260e45c6698..819db53da64d 100644
--- a/drivers/staging/gs_fpgaboot/io.c
+++ b/drivers/staging/gs_fpgaboot/io.c
@@ -79,15 +79,6 @@ void xl_shift_bytes_out(enum wbus bus_byte, unsigned char *pdata)
79/* 79/*
80 * generic bit swap for xilinx SYSTEMMAP FPGA programming 80 * generic bit swap for xilinx SYSTEMMAP FPGA programming
81 */ 81 */
82static inline unsigned char bitswap(unsigned char s)
83{
84 unsigned char d;
85
86 d = (((s&0x80)>>7) | ((s&0x40)>>5) | ((s&0x20)>>3) | ((s&0x10)>>1) |
87 ((s&0x08)<<1) | ((s&0x04)<<3) | ((s&0x02)<<5) | ((s&0x01)<<7));
88 return d;
89}
90
91void xl_program_b(int32_t i) 82void xl_program_b(int32_t i)
92{ 83{
93} 84}
diff --git a/drivers/message/i2o/Kconfig b/drivers/staging/i2o/Kconfig
index 5afa0e393ecf..286c53f4b13d 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/staging/i2o/Kconfig
@@ -1,4 +1,3 @@
1
2menuconfig I2O 1menuconfig I2O
3 tristate "I2O device support" 2 tristate "I2O device support"
4 depends on PCI 3 depends on PCI
diff --git a/drivers/message/i2o/Makefile b/drivers/staging/i2o/Makefile
index b0982dacfd0a..b0982dacfd0a 100644
--- a/drivers/message/i2o/Makefile
+++ b/drivers/staging/i2o/Makefile
diff --git a/drivers/message/i2o/README b/drivers/staging/i2o/README
index f072a8eb3041..f072a8eb3041 100644
--- a/drivers/message/i2o/README
+++ b/drivers/staging/i2o/README
diff --git a/drivers/message/i2o/README.ioctl b/drivers/staging/i2o/README.ioctl
index 4a7d2ebdfc97..4a7d2ebdfc97 100644
--- a/drivers/message/i2o/README.ioctl
+++ b/drivers/staging/i2o/README.ioctl
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/staging/i2o/bus-osm.c
index c463dc2efc09..7aa0339aea05 100644
--- a/drivers/message/i2o/bus-osm.c
+++ b/drivers/staging/i2o/bus-osm.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/i2o.h> 17#include "i2o.h"
18 18
19#define OSM_NAME "bus-osm" 19#define OSM_NAME "bus-osm"
20#define OSM_VERSION "1.317" 20#define OSM_VERSION "1.317"
diff --git a/drivers/message/i2o/config-osm.c b/drivers/staging/i2o/config-osm.c
index 3bba7aa82e58..519f52f9f688 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/staging/i2o/config-osm.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/i2o.h> 17#include "i2o.h"
18#include <linux/dcache.h> 18#include <linux/dcache.h>
19#include <linux/namei.h> 19#include <linux/namei.h>
20#include <linux/fs.h> 20#include <linux/fs.h>
diff --git a/drivers/message/i2o/core.h b/drivers/staging/i2o/core.h
index 91614f11f89a..91614f11f89a 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/staging/i2o/core.h
diff --git a/drivers/message/i2o/debug.c b/drivers/staging/i2o/debug.c
index ce62d8bfe1c8..7a16114ed8ea 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/staging/i2o/debug.c
@@ -1,7 +1,7 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/pci.h> 3#include <linux/pci.h>
4#include <linux/i2o.h> 4#include "i2o.h"
5 5
6static void i2o_report_util_cmd(u8 cmd); 6static void i2o_report_util_cmd(u8 cmd);
7static void i2o_report_exec_cmd(u8 cmd); 7static void i2o_report_exec_cmd(u8 cmd);
diff --git a/drivers/message/i2o/device.c b/drivers/staging/i2o/device.c
index 98348f420b52..2af22553dd4e 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/staging/i2o/device.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/i2o.h> 17#include "i2o.h"
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
diff --git a/drivers/message/i2o/driver.c b/drivers/staging/i2o/driver.c
index 1b18a0d1d05b..111c3edde035 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/staging/i2o/driver.c
@@ -16,7 +16,7 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/rwsem.h> 18#include <linux/rwsem.h>
19#include <linux/i2o.h> 19#include "i2o.h"
20#include <linux/workqueue.h> 20#include <linux/workqueue.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/staging/i2o/exec-osm.c
index a3970e56ae53..16d857d5e655 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/staging/i2o/exec-osm.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/i2o.h> 31#include "i2o.h"
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/string.h> 34#include <linux/string.h>
diff --git a/include/linux/i2o.h b/drivers/staging/i2o/i2o.h
index d23c3c20b201..d23c3c20b201 100644
--- a/include/linux/i2o.h
+++ b/drivers/staging/i2o/i2o.h
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/staging/i2o/i2o_block.c
index 6fc3866965df..0a13c64ce000 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/staging/i2o/i2o_block.c
@@ -52,7 +52,7 @@
52 52
53#include <linux/module.h> 53#include <linux/module.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/i2o.h> 55#include "i2o.h"
56#include <linux/mutex.h> 56#include <linux/mutex.h>
57 57
58#include <linux/mempool.h> 58#include <linux/mempool.h>
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/staging/i2o/i2o_block.h
index cf8873cbca3f..cf8873cbca3f 100644
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/staging/i2o/i2o_block.h
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/staging/i2o/i2o_config.c
index 04bd3b6de401..04bd3b6de401 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/staging/i2o/i2o_config.c
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/staging/i2o/i2o_proc.c
index b7d87cd227a9..ad84f3304f3c 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/staging/i2o/i2o_proc.c
@@ -39,7 +39,7 @@
39#include <linux/types.h> 39#include <linux/types.h>
40#include <linux/kernel.h> 40#include <linux/kernel.h>
41#include <linux/pci.h> 41#include <linux/pci.h>
42#include <linux/i2o.h> 42#include "i2o.h"
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/seq_file.h> 45#include <linux/seq_file.h>
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/staging/i2o/i2o_scsi.c
index 8152e9fa9d95..1b11dcb3faea 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/staging/i2o/i2o_scsi.c
@@ -53,7 +53,7 @@
53#include <linux/prefetch.h> 53#include <linux/prefetch.h>
54#include <linux/pci.h> 54#include <linux/pci.h>
55#include <linux/blkdev.h> 55#include <linux/blkdev.h>
56#include <linux/i2o.h> 56#include "i2o.h"
57#include <linux/scatterlist.h> 57#include <linux/scatterlist.h>
58 58
59#include <asm/dma.h> 59#include <asm/dma.h>
diff --git a/drivers/message/i2o/iop.c b/drivers/staging/i2o/iop.c
index 92752fb5b2d3..52334fc8b547 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/staging/i2o/iop.c
@@ -26,7 +26,7 @@
26 */ 26 */
27 27
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/i2o.h> 29#include "i2o.h"
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
diff --git a/drivers/message/i2o/memory.c b/drivers/staging/i2o/memory.c
index 292b41e49fbd..8f9509d275a4 100644
--- a/drivers/message/i2o/memory.c
+++ b/drivers/staging/i2o/memory.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/i2o.h> 14#include "i2o.h"
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
diff --git a/drivers/message/i2o/pci.c b/drivers/staging/i2o/pci.c
index 0f9f3e1a2b6b..b3b8a61dd4a6 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/staging/i2o/pci.c
@@ -30,7 +30,7 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/i2o.h> 33#include "i2o.h"
34#include <linux/module.h> 34#include <linux/module.h>
35#include "core.h" 35#include "core.h"
36 36
diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
index 940ed2399e73..72c96aa6e992 100644
--- a/drivers/staging/iio/Documentation/iio_event_monitor.c
+++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
@@ -49,6 +49,8 @@ static const char * const iio_chan_type_name_spec[] = {
49 [IIO_CCT] = "cct", 49 [IIO_CCT] = "cct",
50 [IIO_PRESSURE] = "pressure", 50 [IIO_PRESSURE] = "pressure",
51 [IIO_HUMIDITYRELATIVE] = "humidityrelative", 51 [IIO_HUMIDITYRELATIVE] = "humidityrelative",
52 [IIO_ACTIVITY] = "activity",
53 [IIO_STEPS] = "steps",
52}; 54};
53 55
54static const char * const iio_ev_type_text[] = { 56static const char * const iio_ev_type_text[] = {
@@ -57,6 +59,7 @@ static const char * const iio_ev_type_text[] = {
57 [IIO_EV_TYPE_ROC] = "roc", 59 [IIO_EV_TYPE_ROC] = "roc",
58 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", 60 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
59 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", 61 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
62 [IIO_EV_TYPE_CHANGE] = "change",
60}; 63};
61 64
62static const char * const iio_ev_dir_text[] = { 65static const char * const iio_ev_dir_text[] = {
@@ -92,6 +95,10 @@ static const char * const iio_modifier_names[] = {
92 [IIO_MOD_NORTH_TRUE] = "from_north_true", 95 [IIO_MOD_NORTH_TRUE] = "from_north_true",
93 [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp", 96 [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
94 [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp", 97 [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
98 [IIO_MOD_RUNNING] = "running",
99 [IIO_MOD_JOGGING] = "jogging",
100 [IIO_MOD_WALKING] = "walking",
101 [IIO_MOD_STILL] = "still",
95}; 102};
96 103
97static bool event_is_known(struct iio_event_data *event) 104static bool event_is_known(struct iio_event_data *event)
@@ -121,6 +128,8 @@ static bool event_is_known(struct iio_event_data *event)
121 case IIO_CCT: 128 case IIO_CCT:
122 case IIO_PRESSURE: 129 case IIO_PRESSURE:
123 case IIO_HUMIDITYRELATIVE: 130 case IIO_HUMIDITYRELATIVE:
131 case IIO_ACTIVITY:
132 case IIO_STEPS:
124 break; 133 break;
125 default: 134 default:
126 return false; 135 return false;
@@ -154,6 +163,10 @@ static bool event_is_known(struct iio_event_data *event)
154 case IIO_MOD_NORTH_TRUE: 163 case IIO_MOD_NORTH_TRUE:
155 case IIO_MOD_NORTH_MAGN_TILT_COMP: 164 case IIO_MOD_NORTH_MAGN_TILT_COMP:
156 case IIO_MOD_NORTH_TRUE_TILT_COMP: 165 case IIO_MOD_NORTH_TRUE_TILT_COMP:
166 case IIO_MOD_RUNNING:
167 case IIO_MOD_JOGGING:
168 case IIO_MOD_WALKING:
169 case IIO_MOD_STILL:
157 break; 170 break;
158 default: 171 default:
159 return false; 172 return false;
@@ -165,6 +178,7 @@ static bool event_is_known(struct iio_event_data *event)
165 case IIO_EV_TYPE_ROC: 178 case IIO_EV_TYPE_ROC:
166 case IIO_EV_TYPE_THRESH_ADAPTIVE: 179 case IIO_EV_TYPE_THRESH_ADAPTIVE:
167 case IIO_EV_TYPE_MAG_ADAPTIVE: 180 case IIO_EV_TYPE_MAG_ADAPTIVE:
181 case IIO_EV_TYPE_CHANGE:
168 break; 182 break;
169 default: 183 default:
170 return false; 184 return false;
@@ -174,6 +188,7 @@ static bool event_is_known(struct iio_event_data *event)
174 case IIO_EV_DIR_EITHER: 188 case IIO_EV_DIR_EITHER:
175 case IIO_EV_DIR_RISING: 189 case IIO_EV_DIR_RISING:
176 case IIO_EV_DIR_FALLING: 190 case IIO_EV_DIR_FALLING:
191 case IIO_EV_DIR_NONE:
177 break; 192 break;
178 default: 193 default:
179 return false; 194 return false;
@@ -214,9 +229,11 @@ static void print_event(struct iio_event_data *event)
214 else if (chan >= 0) 229 else if (chan >= 0)
215 printf("channel: %d, ", chan); 230 printf("channel: %d, ", chan);
216 231
217 printf("evtype: %s, direction: %s\n", 232 printf("evtype: %s", iio_ev_type_text[ev_type]);
218 iio_ev_type_text[ev_type], 233
219 iio_ev_dir_text[dir]); 234 if (dir != IIO_EV_DIR_NONE)
235 printf(", direction: %s", iio_ev_dir_text[dir]);
236 printf("\n");
220} 237}
221 238
222int main(int argc, char **argv) 239int main(int argc, char **argv)
diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
index e1da43381d0e..18718fcaf259 100644
--- a/drivers/staging/iio/Documentation/ring.txt
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -39,9 +39,9 @@ request_update
39 If parameters have changed that require reinitialization or configuration of 39 If parameters have changed that require reinitialization or configuration of
40 the buffer this will trigger it. 40 the buffer this will trigger it.
41 41
42get_bytes_per_datum, set_bytes_per_datum 42set_bytes_per_datum
43 Get/set the number of bytes for a complete scan. (All samples + timestamp) 43 Set the number of bytes for a complete scan. (All samples + timestamp)
44 44
45get_length / set_length 45set_length
46 Get/set the number of complete scans that may be held by the buffer. 46 Set the number of complete scans that may be held by the buffer.
47 47
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index f5e145caffa9..b78c9c5d5588 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -716,14 +716,6 @@ static int lis3l02dq_probe(struct spi_device *spi)
716 if (ret) 716 if (ret)
717 return ret; 717 return ret;
718 718
719 ret = iio_buffer_register(indio_dev,
720 lis3l02dq_channels,
721 ARRAY_SIZE(lis3l02dq_channels));
722 if (ret) {
723 dev_err(&spi->dev, "failed to initialize the buffer\n");
724 goto error_unreg_buffer_funcs;
725 }
726
727 if (spi->irq) { 719 if (spi->irq) {
728 ret = request_threaded_irq(st->us->irq, 720 ret = request_threaded_irq(st->us->irq,
729 &lis3l02dq_th, 721 &lis3l02dq_th,
@@ -732,7 +724,7 @@ static int lis3l02dq_probe(struct spi_device *spi)
732 "lis3l02dq", 724 "lis3l02dq",
733 indio_dev); 725 indio_dev);
734 if (ret) 726 if (ret)
735 goto error_uninitialize_buffer; 727 goto error_unreg_buffer_funcs;
736 728
737 ret = lis3l02dq_probe_trigger(indio_dev); 729 ret = lis3l02dq_probe_trigger(indio_dev);
738 if (ret) 730 if (ret)
@@ -756,8 +748,6 @@ error_remove_trigger:
756error_free_interrupt: 748error_free_interrupt:
757 if (spi->irq) 749 if (spi->irq)
758 free_irq(st->us->irq, indio_dev); 750 free_irq(st->us->irq, indio_dev);
759error_uninitialize_buffer:
760 iio_buffer_unregister(indio_dev);
761error_unreg_buffer_funcs: 751error_unreg_buffer_funcs:
762 lis3l02dq_unconfigure_buffer(indio_dev); 752 lis3l02dq_unconfigure_buffer(indio_dev);
763 return ret; 753 return ret;
@@ -804,7 +794,6 @@ static int lis3l02dq_remove(struct spi_device *spi)
804 free_irq(st->us->irq, indio_dev); 794 free_irq(st->us->irq, indio_dev);
805 795
806 lis3l02dq_remove_trigger(indio_dev); 796 lis3l02dq_remove_trigger(indio_dev);
807 iio_buffer_unregister(indio_dev);
808 lis3l02dq_unconfigure_buffer(indio_dev); 797 lis3l02dq_unconfigure_buffer(indio_dev);
809 798
810 return 0; 799 return 0;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 9efc77b0ebdd..1fd90090a633 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -393,7 +393,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
393 int ret; 393 int ret;
394 struct iio_buffer *buffer; 394 struct iio_buffer *buffer;
395 395
396 buffer = iio_kfifo_allocate(indio_dev); 396 buffer = iio_kfifo_allocate();
397 if (!buffer) 397 if (!buffer)
398 return -ENOMEM; 398 return -ENOMEM;
399 399
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index e4e56391487a..31fb2182c198 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -223,33 +223,6 @@ error_ret:
223 return ret; 223 return ret;
224} 224}
225 225
226#ifdef SCA3000_DEBUG
227/**
228 * sca3000_check_status() check the status register
229 *
230 * Only used for debugging purposes
231 **/
232static int sca3000_check_status(struct device *dev)
233{
234 int ret;
235 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
236 struct sca3000_state *st = iio_priv(indio_dev);
237
238 mutex_lock(&st->lock);
239 ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
240 if (ret < 0)
241 goto error_ret;
242 if (st->rx[0] & SCA3000_EEPROM_CS_ERROR)
243 dev_err(dev, "eeprom error\n");
244 if (st->rx[0] & SCA3000_SPI_FRAME_ERROR)
245 dev_err(dev, "Previous SPI Frame was corrupt\n");
246
247error_ret:
248 mutex_unlock(&st->lock);
249 return ret;
250}
251#endif /* SCA3000_DEBUG */
252
253/** 226/**
254 * sca3000_show_rev() - sysfs interface to read the chip revision number 227 * sca3000_show_rev() - sysfs interface to read the chip revision number
255 **/ 228 **/
@@ -459,6 +432,8 @@ static const struct iio_chan_spec sca3000_channels_with_temp[] = {
459 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 432 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
460 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | 433 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
461 BIT(IIO_CHAN_INFO_OFFSET), 434 BIT(IIO_CHAN_INFO_OFFSET),
435 /* No buffer support */
436 .scan_index = -1,
462 }, 437 },
463}; 438};
464 439
@@ -1154,17 +1129,6 @@ static int sca3000_probe(struct spi_device *spi)
1154 if (ret < 0) 1129 if (ret < 0)
1155 return ret; 1130 return ret;
1156 1131
1157 ret = iio_buffer_register(indio_dev,
1158 sca3000_channels,
1159 ARRAY_SIZE(sca3000_channels));
1160 if (ret < 0)
1161 goto error_unregister_dev;
1162 if (indio_dev->buffer) {
1163 iio_scan_mask_set(indio_dev, indio_dev->buffer, 0);
1164 iio_scan_mask_set(indio_dev, indio_dev->buffer, 1);
1165 iio_scan_mask_set(indio_dev, indio_dev->buffer, 2);
1166 }
1167
1168 if (spi->irq) { 1132 if (spi->irq) {
1169 ret = request_threaded_irq(spi->irq, 1133 ret = request_threaded_irq(spi->irq,
1170 NULL, 1134 NULL,
@@ -1173,7 +1137,7 @@ static int sca3000_probe(struct spi_device *spi)
1173 "sca3000", 1137 "sca3000",
1174 indio_dev); 1138 indio_dev);
1175 if (ret) 1139 if (ret)
1176 goto error_unregister_ring; 1140 goto error_unregister_dev;
1177 } 1141 }
1178 sca3000_register_ring_funcs(indio_dev); 1142 sca3000_register_ring_funcs(indio_dev);
1179 ret = sca3000_clean_setup(st); 1143 ret = sca3000_clean_setup(st);
@@ -1184,8 +1148,6 @@ static int sca3000_probe(struct spi_device *spi)
1184error_free_irq: 1148error_free_irq:
1185 if (spi->irq) 1149 if (spi->irq)
1186 free_irq(spi->irq, indio_dev); 1150 free_irq(spi->irq, indio_dev);
1187error_unregister_ring:
1188 iio_buffer_unregister(indio_dev);
1189error_unregister_dev: 1151error_unregister_dev:
1190 iio_device_unregister(indio_dev); 1152 iio_device_unregister(indio_dev);
1191 return ret; 1153 return ret;
@@ -1219,7 +1181,6 @@ static int sca3000_remove(struct spi_device *spi)
1219 if (spi->irq) 1181 if (spi->irq)
1220 free_irq(spi->irq, indio_dev); 1182 free_irq(spi->irq, indio_dev);
1221 iio_device_unregister(indio_dev); 1183 iio_device_unregister(indio_dev);
1222 iio_buffer_unregister(indio_dev);
1223 sca3000_unconfigure_ring(indio_dev); 1184 sca3000_unconfigure_ring(indio_dev);
1224 1185
1225 return 0; 1186 return 0;
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 157827651bfa..f76a26885808 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -129,26 +129,11 @@ error_ret:
129 return ret ? ret : num_read; 129 return ret ? ret : num_read;
130} 130}
131 131
132/* This is only valid with all 3 elements enabled */
133static int sca3000_ring_get_length(struct iio_buffer *r)
134{
135 return 64;
136}
137
138/* only valid if resolution is kept at 11bits */
139static int sca3000_ring_get_bytes_per_datum(struct iio_buffer *r)
140{
141 return 6;
142}
143
144static bool sca3000_ring_buf_data_available(struct iio_buffer *r) 132static bool sca3000_ring_buf_data_available(struct iio_buffer *r)
145{ 133{
146 return r->stufftoread; 134 return r->stufftoread;
147} 135}
148 136
149static IIO_BUFFER_ENABLE_ATTR;
150static IIO_BUFFER_LENGTH_ATTR;
151
152/** 137/**
153 * sca3000_query_ring_int() is the hardware ring status interrupt enabled 138 * sca3000_query_ring_int() is the hardware ring status interrupt enabled
154 **/ 139 **/
@@ -238,20 +223,13 @@ static IIO_DEVICE_ATTR(in_accel_scale,
238 * only apply to the ring buffer. At all times full rate and accuracy 223 * only apply to the ring buffer. At all times full rate and accuracy
239 * is available via direct reading from registers. 224 * is available via direct reading from registers.
240 */ 225 */
241static struct attribute *sca3000_ring_attributes[] = { 226static const struct attribute *sca3000_ring_attributes[] = {
242 &dev_attr_length.attr,
243 &dev_attr_enable.attr,
244 &iio_dev_attr_50_percent.dev_attr.attr, 227 &iio_dev_attr_50_percent.dev_attr.attr,
245 &iio_dev_attr_75_percent.dev_attr.attr, 228 &iio_dev_attr_75_percent.dev_attr.attr,
246 &iio_dev_attr_in_accel_scale.dev_attr.attr, 229 &iio_dev_attr_in_accel_scale.dev_attr.attr,
247 NULL, 230 NULL,
248}; 231};
249 232
250static struct attribute_group sca3000_ring_attr = {
251 .attrs = sca3000_ring_attributes,
252 .name = "buffer",
253};
254
255static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev) 233static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
256{ 234{
257 struct iio_buffer *buf; 235 struct iio_buffer *buf;
@@ -264,7 +242,8 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
264 ring->private = indio_dev; 242 ring->private = indio_dev;
265 buf = &ring->buf; 243 buf = &ring->buf;
266 buf->stufftoread = 0; 244 buf->stufftoread = 0;
267 buf->attrs = &sca3000_ring_attr; 245 buf->length = 64;
246 buf->attrs = sca3000_ring_attributes;
268 iio_buffer_init(buf); 247 iio_buffer_init(buf);
269 248
270 return buf; 249 return buf;
@@ -277,8 +256,6 @@ static void sca3000_ring_release(struct iio_buffer *r)
277 256
278static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = { 257static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
279 .read_first_n = &sca3000_read_first_n_hw_rb, 258 .read_first_n = &sca3000_read_first_n_hw_rb,
280 .get_length = &sca3000_ring_get_length,
281 .get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
282 .data_available = sca3000_ring_buf_data_available, 259 .data_available = sca3000_ring_buf_data_available,
283 .release = sca3000_ring_release, 260 .release = sca3000_ring_release,
284}; 261};
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index f6526aa22e8a..6f8ce6c6574b 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -612,7 +612,7 @@ static int ad7192_probe(struct spi_device *spi)
612 const struct ad7192_platform_data *pdata = spi->dev.platform_data; 612 const struct ad7192_platform_data *pdata = spi->dev.platform_data;
613 struct ad7192_state *st; 613 struct ad7192_state *st;
614 struct iio_dev *indio_dev; 614 struct iio_dev *indio_dev;
615 int ret , voltage_uv = 0; 615 int ret, voltage_uv = 0;
616 616
617 if (!pdata) { 617 if (!pdata) {
618 dev_err(&spi->dev, "no platform data?\n"); 618 dev_err(&spi->dev, "no platform data?\n");
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index f053535385bf..d9d6fad7cb00 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -436,7 +436,14 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
436 */ 436 */
437 mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch)); 437 mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
438 438
439 /* prepare the delay/loop unit according to the oversampling count */ 439 /*
440 * prepare the delay/loop unit according to the oversampling count
441 *
442 * from the datasheet:
443 * "The DELAY fields in HW_LRADC_DELAY0, HW_LRADC_DELAY1,
444 * HW_LRADC_DELAY2, and HW_LRADC_DELAY3 must be non-zero; otherwise,
445 * the LRADC will not trigger the delay group."
446 */
440 mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) | 447 mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
441 LRADC_DELAY_TRIGGER_DELAYS(0) | 448 LRADC_DELAY_TRIGGER_DELAYS(0) |
442 LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) | 449 LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
@@ -1495,20 +1502,38 @@ static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
1495 return -EINVAL; 1502 return -EINVAL;
1496 } 1503 }
1497 1504
1498 lradc->over_sample_cnt = 4; 1505 if (of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt)) {
1499 ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt); 1506 lradc->over_sample_cnt = 4;
1500 if (ret == 0) 1507 } else {
1508 if (adapt < 1 || adapt > 32) {
1509 dev_err(lradc->dev, "Invalid sample count (%u)\n",
1510 adapt);
1511 return -EINVAL;
1512 }
1501 lradc->over_sample_cnt = adapt; 1513 lradc->over_sample_cnt = adapt;
1514 }
1502 1515
1503 lradc->over_sample_delay = 2; 1516 if (of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt)) {
1504 ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt); 1517 lradc->over_sample_delay = 2;
1505 if (ret == 0) 1518 } else {
1519 if (adapt < 2 || adapt > LRADC_DELAY_DELAY_MASK + 1) {
1520 dev_err(lradc->dev, "Invalid sample delay (%u)\n",
1521 adapt);
1522 return -EINVAL;
1523 }
1506 lradc->over_sample_delay = adapt; 1524 lradc->over_sample_delay = adapt;
1525 }
1507 1526
1508 lradc->settling_delay = 10; 1527 if (of_property_read_u32(lradc_node, "fsl,settling", &adapt)) {
1509 ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt); 1528 lradc->settling_delay = 10;
1510 if (ret == 0) 1529 } else {
1530 if (adapt < 1 || adapt > LRADC_DELAY_DELAY_MASK) {
1531 dev_err(lradc->dev, "Invalid settling delay (%u)\n",
1532 adapt);
1533 return -EINVAL;
1534 }
1511 lradc->settling_delay = adapt; 1535 lradc->settling_delay = adapt;
1536 }
1512 1537
1513 return 0; 1538 return 0;
1514} 1539}
diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
index 5a804f16ec2f..59ad5a3efe9c 100644
--- a/drivers/staging/iio/iio_dummy_evgen.c
+++ b/drivers/staging/iio/iio_dummy_evgen.c
@@ -33,6 +33,7 @@
33 * @base: base of irq range 33 * @base: base of irq range
34 * @enabled: mask of which irqs are enabled 34 * @enabled: mask of which irqs are enabled
35 * @inuse: mask of which irqs are connected 35 * @inuse: mask of which irqs are connected
36 * @regs: irq regs we are faking
36 * @lock: protect the evgen state 37 * @lock: protect the evgen state
37 */ 38 */
38struct iio_dummy_eventgen { 39struct iio_dummy_eventgen {
@@ -40,6 +41,7 @@ struct iio_dummy_eventgen {
40 int base; 41 int base;
41 bool enabled[IIO_EVENTGEN_NO]; 42 bool enabled[IIO_EVENTGEN_NO];
42 bool inuse[IIO_EVENTGEN_NO]; 43 bool inuse[IIO_EVENTGEN_NO];
44 struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
43 struct mutex lock; 45 struct mutex lock;
44}; 46};
45 47
@@ -136,6 +138,12 @@ int iio_dummy_evgen_release_irq(int irq)
136} 138}
137EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq); 139EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq);
138 140
141struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq)
142{
143 return &iio_evgen->regs[irq - iio_evgen->base];
144}
145EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
146
139static void iio_dummy_evgen_free(void) 147static void iio_dummy_evgen_free(void)
140{ 148{
141 irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO); 149 irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO);
@@ -153,6 +161,15 @@ static ssize_t iio_evgen_poke(struct device *dev,
153 size_t len) 161 size_t len)
154{ 162{
155 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 163 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
164 unsigned long event;
165 int ret;
166
167 ret = kstrtoul(buf, 10, &event);
168 if (ret)
169 return ret;
170
171 iio_evgen->regs[this_attr->address].reg_id = this_attr->address;
172 iio_evgen->regs[this_attr->address].reg_data = event;
156 173
157 if (iio_evgen->enabled[this_attr->address]) 174 if (iio_evgen->enabled[this_attr->address])
158 handle_nested_irq(iio_evgen->base + this_attr->address); 175 handle_nested_irq(iio_evgen->base + this_attr->address);
diff --git a/drivers/staging/iio/iio_dummy_evgen.h b/drivers/staging/iio/iio_dummy_evgen.h
index 3a180811b315..2ac293ab7c8f 100644
--- a/drivers/staging/iio/iio_dummy_evgen.h
+++ b/drivers/staging/iio/iio_dummy_evgen.h
@@ -1,6 +1,12 @@
1#ifndef _IIO_DUMMY_EVGEN_H_ 1#ifndef _IIO_DUMMY_EVGEN_H_
2#define _IIO_DUMMY_EVGEN_H_ 2#define _IIO_DUMMY_EVGEN_H_
3 3
4struct iio_dummy_regs {
5 u32 reg_id;
6 u32 reg_data;
7};
8
9struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq);
4int iio_dummy_evgen_get_irq(void); 10int iio_dummy_evgen_get_irq(void);
5int iio_dummy_evgen_release_irq(int irq); 11int iio_dummy_evgen_release_irq(int irq);
6 12
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index bf78e6f0311f..e4520213f627 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -69,6 +69,34 @@ static const struct iio_event_spec iio_dummy_event = {
69 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), 69 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
70}; 70};
71 71
72/*
73 * simple step detect event - triggered when a step is detected
74 */
75static const struct iio_event_spec step_detect_event = {
76 .type = IIO_EV_TYPE_CHANGE,
77 .dir = IIO_EV_DIR_NONE,
78 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
79};
80
81/*
82 * simple transition event - triggered when the reported running confidence
83 * value rises above a threshold value
84 */
85static const struct iio_event_spec iio_running_event = {
86 .type = IIO_EV_TYPE_THRESH,
87 .dir = IIO_EV_DIR_RISING,
88 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
89};
90
91/*
92 * simple transition event - triggered when the reported walking confidence
93 * value falls under a threshold value
94 */
95static const struct iio_event_spec iio_walking_event = {
96 .type = IIO_EV_TYPE_THRESH,
97 .dir = IIO_EV_DIR_FALLING,
98 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
99};
72#endif 100#endif
73 101
74/* 102/*
@@ -211,10 +239,44 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
211 { 239 {
212 .type = IIO_VOLTAGE, 240 .type = IIO_VOLTAGE,
213 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 241 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
242 .scan_index = -1, /* No buffer support */
214 .output = 1, 243 .output = 1,
215 .indexed = 1, 244 .indexed = 1,
216 .channel = 0, 245 .channel = 0,
217 }, 246 },
247 {
248 .type = IIO_STEPS,
249 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
250 BIT(IIO_CHAN_INFO_CALIBHEIGHT),
251 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
252 .scan_index = -1, /* No buffer support */
253#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
254 .event_spec = &step_detect_event,
255 .num_event_specs = 1,
256#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
257 },
258 {
259 .type = IIO_ACTIVITY,
260 .modified = 1,
261 .channel2 = IIO_MOD_RUNNING,
262 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
263 .scan_index = -1, /* No buffer support */
264#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
265 .event_spec = &iio_running_event,
266 .num_event_specs = 1,
267#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
268 },
269 {
270 .type = IIO_ACTIVITY,
271 .modified = 1,
272 .channel2 = IIO_MOD_WALKING,
273 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
274 .scan_index = -1, /* No buffer support */
275#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
276 .event_spec = &iio_walking_event,
277 .num_event_specs = 1,
278#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
279 },
218}; 280};
219 281
220/** 282/**
@@ -263,24 +325,55 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
263 break; 325 break;
264 } 326 }
265 break; 327 break;
328 case IIO_CHAN_INFO_PROCESSED:
329 switch (chan->type) {
330 case IIO_STEPS:
331 *val = st->steps;
332 ret = IIO_VAL_INT;
333 break;
334 case IIO_ACTIVITY:
335 switch (chan->channel2) {
336 case IIO_MOD_RUNNING:
337 *val = st->activity_running;
338 ret = IIO_VAL_INT;
339 break;
340 case IIO_MOD_WALKING:
341 *val = st->activity_walking;
342 ret = IIO_VAL_INT;
343 break;
344 default:
345 break;
346 }
347 break;
348 default:
349 break;
350 }
351 break;
266 case IIO_CHAN_INFO_OFFSET: 352 case IIO_CHAN_INFO_OFFSET:
267 /* only single ended adc -> 7 */ 353 /* only single ended adc -> 7 */
268 *val = 7; 354 *val = 7;
269 ret = IIO_VAL_INT; 355 ret = IIO_VAL_INT;
270 break; 356 break;
271 case IIO_CHAN_INFO_SCALE: 357 case IIO_CHAN_INFO_SCALE:
272 switch (chan->differential) { 358 switch (chan->type) {
273 case 0: 359 case IIO_VOLTAGE:
274 /* only single ended adc -> 0.001333 */ 360 switch (chan->differential) {
275 *val = 0; 361 case 0:
276 *val2 = 1333; 362 /* only single ended adc -> 0.001333 */
277 ret = IIO_VAL_INT_PLUS_MICRO; 363 *val = 0;
364 *val2 = 1333;
365 ret = IIO_VAL_INT_PLUS_MICRO;
366 break;
367 case 1:
368 /* all differential adc channels ->
369 * 0.000001344 */
370 *val = 0;
371 *val2 = 1344;
372 ret = IIO_VAL_INT_PLUS_NANO;
373 }
374 break;
375 default:
278 break; 376 break;
279 case 1:
280 /* all differential adc channels -> 0.000001344 */
281 *val = 0;
282 *val2 = 1344;
283 ret = IIO_VAL_INT_PLUS_NANO;
284 } 377 }
285 break; 378 break;
286 case IIO_CHAN_INFO_CALIBBIAS: 379 case IIO_CHAN_INFO_CALIBBIAS:
@@ -298,6 +391,27 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
298 *val2 = 33; 391 *val2 = 33;
299 ret = IIO_VAL_INT_PLUS_NANO; 392 ret = IIO_VAL_INT_PLUS_NANO;
300 break; 393 break;
394 case IIO_CHAN_INFO_ENABLE:
395 switch (chan->type) {
396 case IIO_STEPS:
397 *val = st->steps_enabled;
398 ret = IIO_VAL_INT;
399 break;
400 default:
401 break;
402 }
403 break;
404 case IIO_CHAN_INFO_CALIBHEIGHT:
405 switch (chan->type) {
406 case IIO_STEPS:
407 *val = st->height;
408 ret = IIO_VAL_INT;
409 break;
410 default:
411 break;
412 }
413 break;
414
301 default: 415 default:
302 break; 416 break;
303 } 417 }
@@ -330,14 +444,45 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
330 444
331 switch (mask) { 445 switch (mask) {
332 case IIO_CHAN_INFO_RAW: 446 case IIO_CHAN_INFO_RAW:
333 if (chan->output == 0) 447 switch (chan->type) {
448 case IIO_VOLTAGE:
449 if (chan->output == 0)
450 return -EINVAL;
451
452 /* Locking not required as writing single value */
453 mutex_lock(&st->lock);
454 st->dac_val = val;
455 mutex_unlock(&st->lock);
456 return 0;
457 default:
334 return -EINVAL; 458 return -EINVAL;
335 459 }
336 /* Locking not required as writing single value */ 460 case IIO_CHAN_INFO_PROCESSED:
337 mutex_lock(&st->lock); 461 switch (chan->type) {
338 st->dac_val = val; 462 case IIO_STEPS:
339 mutex_unlock(&st->lock); 463 mutex_lock(&st->lock);
340 return 0; 464 st->steps = val;
465 mutex_unlock(&st->lock);
466 return 0;
467 case IIO_ACTIVITY:
468 if (val < 0)
469 val = 0;
470 if (val > 100)
471 val = 100;
472 switch (chan->channel2) {
473 case IIO_MOD_RUNNING:
474 st->activity_running = val;
475 return 0;
476 case IIO_MOD_WALKING:
477 st->activity_walking = val;
478 return 0;
479 default:
480 return -EINVAL;
481 }
482 break;
483 default:
484 return -EINVAL;
485 }
341 case IIO_CHAN_INFO_CALIBSCALE: 486 case IIO_CHAN_INFO_CALIBSCALE:
342 mutex_lock(&st->lock); 487 mutex_lock(&st->lock);
343 /* Compare against table - hard matching here */ 488 /* Compare against table - hard matching here */
@@ -356,6 +501,24 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
356 st->accel_calibbias = val; 501 st->accel_calibbias = val;
357 mutex_unlock(&st->lock); 502 mutex_unlock(&st->lock);
358 return 0; 503 return 0;
504 case IIO_CHAN_INFO_ENABLE:
505 switch (chan->type) {
506 case IIO_STEPS:
507 mutex_lock(&st->lock);
508 st->steps_enabled = val;
509 mutex_unlock(&st->lock);
510 return 0;
511 default:
512 return -EINVAL;
513 }
514 case IIO_CHAN_INFO_CALIBHEIGHT:
515 switch (chan->type) {
516 case IIO_STEPS:
517 st->height = val;
518 return 0;
519 default:
520 return -EINVAL;
521 }
359 522
360 default: 523 default:
361 return -EINVAL; 524 return -EINVAL;
@@ -395,6 +558,9 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev)
395 st->accel_val = 34; 558 st->accel_val = 34;
396 st->accel_calibbias = -7; 559 st->accel_calibbias = -7;
397 st->accel_calibscale = &dummy_scales[0]; 560 st->accel_calibscale = &dummy_scales[0];
561 st->steps = 47;
562 st->activity_running = 98;
563 st->activity_walking = 4;
398 564
399 return 0; 565 return 0;
400} 566}
@@ -475,13 +641,7 @@ static int iio_dummy_probe(int index)
475 if (ret < 0) 641 if (ret < 0)
476 goto error_free_device; 642 goto error_free_device;
477 643
478 /* 644 ret = iio_simple_dummy_configure_buffer(indio_dev);
479 * Configure buffered capture support and register the channels with the
480 * buffer, but avoid the output channel being registered by reducing the
481 * number of channels by 1.
482 */
483 ret = iio_simple_dummy_configure_buffer(indio_dev,
484 iio_dummy_channels, 5);
485 if (ret < 0) 645 if (ret < 0)
486 goto error_unregister_events; 646 goto error_unregister_events;
487 647
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
index 3027aed79093..34989bf248a7 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -13,6 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14 14
15struct iio_dummy_accel_calibscale; 15struct iio_dummy_accel_calibscale;
16struct iio_dummy_regs;
16 17
17/** 18/**
18 * struct iio_dummy_state - device instance specific state. 19 * struct iio_dummy_state - device instance specific state.
@@ -33,8 +34,14 @@ struct iio_dummy_state {
33 int differential_adc_val[2]; 34 int differential_adc_val[2];
34 int accel_val; 35 int accel_val;
35 int accel_calibbias; 36 int accel_calibbias;
37 int activity_running;
38 int activity_walking;
36 const struct iio_dummy_accel_calibscale *accel_calibscale; 39 const struct iio_dummy_accel_calibscale *accel_calibscale;
37 struct mutex lock; 40 struct mutex lock;
41 struct iio_dummy_regs *regs;
42 int steps_enabled;
43 int steps;
44 int height;
38#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS 45#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
39 int event_irq; 46 int event_irq;
40 int event_val; 47 int event_val;
@@ -107,12 +114,10 @@ enum iio_simple_dummy_scan_elements {
107}; 114};
108 115
109#ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER 116#ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER
110int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, 117int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev);
111 const struct iio_chan_spec *channels, unsigned int num_channels);
112void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev); 118void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
113#else 119#else
114static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, 120static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
115 const struct iio_chan_spec *channels, unsigned int num_channels)
116{ 121{
117 return 0; 122 return 0;
118}; 123};
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index fd74f9166a5f..360a4c980722 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -115,14 +115,13 @@ static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
115 .predisable = &iio_triggered_buffer_predisable, 115 .predisable = &iio_triggered_buffer_predisable,
116}; 116};
117 117
118int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, 118int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
119 const struct iio_chan_spec *channels, unsigned int num_channels)
120{ 119{
121 int ret; 120 int ret;
122 struct iio_buffer *buffer; 121 struct iio_buffer *buffer;
123 122
124 /* Allocate a buffer to use - here a kfifo */ 123 /* Allocate a buffer to use - here a kfifo */
125 buffer = iio_kfifo_allocate(indio_dev); 124 buffer = iio_kfifo_allocate();
126 if (buffer == NULL) { 125 if (buffer == NULL) {
127 ret = -ENOMEM; 126 ret = -ENOMEM;
128 goto error_ret; 127 goto error_ret;
@@ -173,14 +172,8 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
173 */ 172 */
174 indio_dev->modes |= INDIO_BUFFER_TRIGGERED; 173 indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
175 174
176 ret = iio_buffer_register(indio_dev, channels, num_channels);
177 if (ret)
178 goto error_dealloc_pollfunc;
179
180 return 0; 175 return 0;
181 176
182error_dealloc_pollfunc:
183 iio_dealloc_pollfunc(indio_dev->pollfunc);
184error_free_buffer: 177error_free_buffer:
185 iio_kfifo_free(indio_dev->buffer); 178 iio_kfifo_free(indio_dev->buffer);
186error_ret: 179error_ret:
@@ -194,7 +187,6 @@ error_ret:
194 */ 187 */
195void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev) 188void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
196{ 189{
197 iio_buffer_unregister(indio_dev);
198 iio_dealloc_pollfunc(indio_dev->pollfunc); 190 iio_dealloc_pollfunc(indio_dev->pollfunc);
199 iio_kfifo_free(indio_dev->buffer); 191 iio_kfifo_free(indio_dev->buffer);
200} 192}
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c
index 64b45b077549..a5cd3bb219fe 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -72,6 +72,22 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
72 st->event_en = state; 72 st->event_en = state;
73 else 73 else
74 return -EINVAL; 74 return -EINVAL;
75 default:
76 return -EINVAL;
77 }
78 break;
79 case IIO_ACTIVITY:
80 switch (type) {
81 case IIO_EV_TYPE_THRESH:
82 st->event_en = state;
83 break;
84 default:
85 return -EINVAL;
86 }
87 case IIO_STEPS:
88 switch (type) {
89 case IIO_EV_TYPE_CHANGE:
90 st->event_en = state;
75 break; 91 break;
76 default: 92 default:
77 return -EINVAL; 93 return -EINVAL;
@@ -148,12 +164,50 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
148static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private) 164static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
149{ 165{
150 struct iio_dev *indio_dev = private; 166 struct iio_dev *indio_dev = private;
167 struct iio_dummy_state *st = iio_priv(indio_dev);
168
169 dev_dbg(&indio_dev->dev, "id %x event %x\n",
170 st->regs->reg_id, st->regs->reg_data);
171
172 switch (st->regs->reg_data) {
173 case 0:
174 iio_push_event(indio_dev,
175 IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
176 IIO_EV_DIR_RISING,
177 IIO_EV_TYPE_THRESH, 0, 0, 0),
178 iio_get_time_ns());
179 break;
180 case 1:
181 if (st->activity_running > st->event_val)
182 iio_push_event(indio_dev,
183 IIO_EVENT_CODE(IIO_ACTIVITY, 0,
184 IIO_MOD_RUNNING,
185 IIO_EV_DIR_RISING,
186 IIO_EV_TYPE_THRESH,
187 0, 0, 0),
188 iio_get_time_ns());
189 break;
190 case 2:
191 if (st->activity_walking < st->event_val)
192 iio_push_event(indio_dev,
193 IIO_EVENT_CODE(IIO_ACTIVITY, 0,
194 IIO_MOD_WALKING,
195 IIO_EV_DIR_FALLING,
196 IIO_EV_TYPE_THRESH,
197 0, 0, 0),
198 iio_get_time_ns());
199 break;
200 case 3:
201 iio_push_event(indio_dev,
202 IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
203 IIO_EV_DIR_NONE,
204 IIO_EV_TYPE_CHANGE, 0, 0, 0),
205 iio_get_time_ns());
206 break;
207 default:
208 break;
209 }
151 210
152 iio_push_event(indio_dev,
153 IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
154 IIO_EV_DIR_RISING,
155 IIO_EV_TYPE_THRESH, 0, 0, 0),
156 iio_get_time_ns());
157 return IRQ_HANDLED; 211 return IRQ_HANDLED;
158} 212}
159 213
@@ -179,6 +233,8 @@ int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
179 ret = st->event_irq; 233 ret = st->event_irq;
180 goto error_ret; 234 goto error_ret;
181 } 235 }
236 st->regs = iio_dummy_evgen_get_regs(st->event_irq);
237
182 ret = request_threaded_irq(st->event_irq, 238 ret = request_threaded_irq(st->event_irq,
183 NULL, 239 NULL,
184 &iio_simple_dummy_event_handler, 240 &iio_simple_dummy_event_handler,
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index b6bd609c3655..79194399e040 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -89,7 +89,6 @@
89struct ad5933_state { 89struct ad5933_state {
90 struct i2c_client *client; 90 struct i2c_client *client;
91 struct regulator *reg; 91 struct regulator *reg;
92 struct ad5933_platform_data *pdata;
93 struct delayed_work work; 92 struct delayed_work work;
94 unsigned long mclk_hz; 93 unsigned long mclk_hz;
95 unsigned char ctrl_hb; 94 unsigned char ctrl_hb;
@@ -113,7 +112,8 @@ static const struct iio_chan_spec ad5933_channels[] = {
113 .type = IIO_TEMP, 112 .type = IIO_TEMP,
114 .indexed = 1, 113 .indexed = 1,
115 .channel = 0, 114 .channel = 0,
116 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 115 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
116 BIT(IIO_CHAN_INFO_SCALE),
117 .address = AD5933_REG_TEMP_DATA, 117 .address = AD5933_REG_TEMP_DATA,
118 .scan_index = -1, 118 .scan_index = -1,
119 .scan_type = { 119 .scan_type = {
@@ -360,11 +360,11 @@ static ssize_t ad5933_show(struct device *dev,
360 mutex_lock(&indio_dev->mlock); 360 mutex_lock(&indio_dev->mlock);
361 switch ((u32) this_attr->address) { 361 switch ((u32) this_attr->address) {
362 case AD5933_OUT_RANGE: 362 case AD5933_OUT_RANGE:
363 len = sprintf(buf, "%d\n", 363 len = sprintf(buf, "%u\n",
364 st->range_avail[(st->ctrl_hb >> 1) & 0x3]); 364 st->range_avail[(st->ctrl_hb >> 1) & 0x3]);
365 break; 365 break;
366 case AD5933_OUT_RANGE_AVAIL: 366 case AD5933_OUT_RANGE_AVAIL:
367 len = sprintf(buf, "%d %d %d %d\n", st->range_avail[0], 367 len = sprintf(buf, "%u %u %u %u\n", st->range_avail[0],
368 st->range_avail[3], st->range_avail[2], 368 st->range_avail[3], st->range_avail[2],
369 st->range_avail[1]); 369 st->range_avail[1]);
370 break; 370 break;
@@ -520,12 +520,11 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
520{ 520{
521 struct ad5933_state *st = iio_priv(indio_dev); 521 struct ad5933_state *st = iio_priv(indio_dev);
522 __be16 dat; 522 __be16 dat;
523 int ret = -EINVAL; 523 int ret;
524 524
525 mutex_lock(&indio_dev->mlock);
526 switch (m) { 525 switch (m) {
527 case IIO_CHAN_INFO_RAW: 526 case IIO_CHAN_INFO_RAW:
528 case IIO_CHAN_INFO_PROCESSED: 527 mutex_lock(&indio_dev->mlock);
529 if (iio_buffer_enabled(indio_dev)) { 528 if (iio_buffer_enabled(indio_dev)) {
530 ret = -EBUSY; 529 ret = -EBUSY;
531 goto out; 530 goto out;
@@ -543,16 +542,16 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
543 if (ret < 0) 542 if (ret < 0)
544 goto out; 543 goto out;
545 mutex_unlock(&indio_dev->mlock); 544 mutex_unlock(&indio_dev->mlock);
546 ret = be16_to_cpu(dat); 545 *val = sign_extend32(be16_to_cpu(dat), 13);
547 /* Temp in Milli degrees Celsius */
548 if (ret < 8192)
549 *val = ret * 1000 / 32;
550 else
551 *val = (ret - 16384) * 1000 / 32;
552 546
553 return IIO_VAL_INT; 547 return IIO_VAL_INT;
548 case IIO_CHAN_INFO_SCALE:
549 *val = 1000;
550 *val2 = 5;
551 return IIO_VAL_FRACTIONAL_LOG2;
554 } 552 }
555 553
554 return -EINVAL;
556out: 555out:
557 mutex_unlock(&indio_dev->mlock); 556 mutex_unlock(&indio_dev->mlock);
558 return ret; 557 return ret;
@@ -626,7 +625,7 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
626{ 625{
627 struct iio_buffer *buffer; 626 struct iio_buffer *buffer;
628 627
629 buffer = iio_kfifo_allocate(indio_dev); 628 buffer = iio_kfifo_allocate();
630 if (!buffer) 629 if (!buffer)
631 return -ENOMEM; 630 return -ENOMEM;
632 631
@@ -712,9 +711,7 @@ static int ad5933_probe(struct i2c_client *client,
712 st->client = client; 711 st->client = client;
713 712
714 if (!pdata) 713 if (!pdata)
715 st->pdata = &ad5933_default_pdata; 714 pdata = &ad5933_default_pdata;
716 else
717 st->pdata = pdata;
718 715
719 st->reg = devm_regulator_get(&client->dev, "vcc"); 716 st->reg = devm_regulator_get(&client->dev, "vcc");
720 if (!IS_ERR(st->reg)) { 717 if (!IS_ERR(st->reg)) {
@@ -727,10 +724,10 @@ static int ad5933_probe(struct i2c_client *client,
727 if (voltage_uv) 724 if (voltage_uv)
728 st->vref_mv = voltage_uv / 1000; 725 st->vref_mv = voltage_uv / 1000;
729 else 726 else
730 st->vref_mv = st->pdata->vref_mv; 727 st->vref_mv = pdata->vref_mv;
731 728
732 if (st->pdata->ext_clk_Hz) { 729 if (pdata->ext_clk_Hz) {
733 st->mclk_hz = st->pdata->ext_clk_Hz; 730 st->mclk_hz = pdata->ext_clk_Hz;
734 st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; 731 st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK;
735 } else { 732 } else {
736 st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; 733 st->mclk_hz = AD5933_INT_OSC_FREQ_Hz;
@@ -752,27 +749,16 @@ static int ad5933_probe(struct i2c_client *client,
752 if (ret) 749 if (ret)
753 goto error_disable_reg; 750 goto error_disable_reg;
754 751
755 ret = iio_buffer_register(indio_dev, ad5933_channels,
756 ARRAY_SIZE(ad5933_channels));
757 if (ret)
758 goto error_unreg_ring;
759
760 /* enable both REAL and IMAG channels by default */
761 iio_scan_mask_set(indio_dev, indio_dev->buffer, 0);
762 iio_scan_mask_set(indio_dev, indio_dev->buffer, 1);
763
764 ret = ad5933_setup(st); 752 ret = ad5933_setup(st);
765 if (ret) 753 if (ret)
766 goto error_uninitialize_ring; 754 goto error_unreg_ring;
767 755
768 ret = iio_device_register(indio_dev); 756 ret = iio_device_register(indio_dev);
769 if (ret) 757 if (ret)
770 goto error_uninitialize_ring; 758 goto error_unreg_ring;
771 759
772 return 0; 760 return 0;
773 761
774error_uninitialize_ring:
775 iio_buffer_unregister(indio_dev);
776error_unreg_ring: 762error_unreg_ring:
777 iio_kfifo_free(indio_dev->buffer); 763 iio_kfifo_free(indio_dev->buffer);
778error_disable_reg: 764error_disable_reg:
@@ -788,7 +774,6 @@ static int ad5933_remove(struct i2c_client *client)
788 struct ad5933_state *st = iio_priv(indio_dev); 774 struct ad5933_state *st = iio_priv(indio_dev);
789 775
790 iio_device_unregister(indio_dev); 776 iio_device_unregister(indio_dev);
791 iio_buffer_unregister(indio_dev);
792 iio_kfifo_free(indio_dev->buffer); 777 iio_kfifo_free(indio_dev->buffer);
793 if (!IS_ERR(st->reg)) 778 if (!IS_ERR(st->reg))
794 regulator_disable(st->reg); 779 regulator_disable(st->reg);
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index cc4ddcce4ff9..8afae8e33d56 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -692,7 +692,7 @@ static ssize_t taos_luxtable_show(struct device *dev,
692 int offset = 0; 692 int offset = 0;
693 693
694 for (i = 0; i < ARRAY_SIZE(taos_device_lux); i++) { 694 for (i = 0; i < ARRAY_SIZE(taos_device_lux); i++) {
695 offset += sprintf(buf + offset, "%d,%d,%d,", 695 offset += sprintf(buf + offset, "%u,%u,%u,",
696 taos_device_lux[i].ratio, 696 taos_device_lux[i].ratio,
697 taos_device_lux[i].ch0, 697 taos_device_lux[i].ch0,
698 taos_device_lux[i].ch1); 698 taos_device_lux[i].ch1);
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 423f96bdf595..4a5dc26fed4c 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -1147,7 +1147,7 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev,
1147 int offset = 0; 1147 int offset = 0;
1148 1148
1149 while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) { 1149 while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) {
1150 offset += snprintf(buf + offset, PAGE_SIZE, "%d,%d,%d,", 1150 offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,%u,",
1151 chip->tsl2x7x_device_lux[i].ratio, 1151 chip->tsl2x7x_device_lux[i].ratio,
1152 chip->tsl2x7x_device_lux[i].ch0, 1152 chip->tsl2x7x_device_lux[i].ch0,
1153 chip->tsl2x7x_device_lux[i].ch1); 1153 chip->tsl2x7x_device_lux[i].ch1);
diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index e8c98cf57070..f6739e2c24b1 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -145,7 +145,6 @@ ssize_t ade7758_read_data_from_ring(struct device *dev,
145int ade7758_configure_ring(struct iio_dev *indio_dev); 145int ade7758_configure_ring(struct iio_dev *indio_dev);
146void ade7758_unconfigure_ring(struct iio_dev *indio_dev); 146void ade7758_unconfigure_ring(struct iio_dev *indio_dev);
147 147
148void ade7758_uninitialize_ring(struct iio_dev *indio_dev);
149int ade7758_set_irq(struct device *dev, bool enable); 148int ade7758_set_irq(struct device *dev, bool enable);
150 149
151int ade7758_spi_write_reg_8(struct device *dev, 150int ade7758_spi_write_reg_8(struct device *dev,
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index fb373b89dcc2..70e96b20c2eb 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -850,23 +850,15 @@ static int ade7758_probe(struct spi_device *spi)
850 if (ret) 850 if (ret)
851 goto error_free_tx; 851 goto error_free_tx;
852 852
853 ret = iio_buffer_register(indio_dev,
854 &ade7758_channels[0],
855 ARRAY_SIZE(ade7758_channels));
856 if (ret) {
857 dev_err(&spi->dev, "failed to initialize the ring\n");
858 goto error_unreg_ring_funcs;
859 }
860
861 /* Get the device into a sane initial state */ 853 /* Get the device into a sane initial state */
862 ret = ade7758_initial_setup(indio_dev); 854 ret = ade7758_initial_setup(indio_dev);
863 if (ret) 855 if (ret)
864 goto error_uninitialize_ring; 856 goto error_unreg_ring_funcs;
865 857
866 if (spi->irq) { 858 if (spi->irq) {
867 ret = ade7758_probe_trigger(indio_dev); 859 ret = ade7758_probe_trigger(indio_dev);
868 if (ret) 860 if (ret)
869 goto error_uninitialize_ring; 861 goto error_unreg_ring_funcs;
870 } 862 }
871 863
872 ret = iio_device_register(indio_dev); 864 ret = iio_device_register(indio_dev);
@@ -878,8 +870,6 @@ static int ade7758_probe(struct spi_device *spi)
878error_remove_trigger: 870error_remove_trigger:
879 if (spi->irq) 871 if (spi->irq)
880 ade7758_remove_trigger(indio_dev); 872 ade7758_remove_trigger(indio_dev);
881error_uninitialize_ring:
882 ade7758_uninitialize_ring(indio_dev);
883error_unreg_ring_funcs: 873error_unreg_ring_funcs:
884 ade7758_unconfigure_ring(indio_dev); 874 ade7758_unconfigure_ring(indio_dev);
885error_free_tx: 875error_free_tx:
@@ -897,7 +887,6 @@ static int ade7758_remove(struct spi_device *spi)
897 iio_device_unregister(indio_dev); 887 iio_device_unregister(indio_dev);
898 ade7758_stop_device(&indio_dev->dev); 888 ade7758_stop_device(&indio_dev->dev);
899 ade7758_remove_trigger(indio_dev); 889 ade7758_remove_trigger(indio_dev);
900 ade7758_uninitialize_ring(indio_dev);
901 ade7758_unconfigure_ring(indio_dev); 890 ade7758_unconfigure_ring(indio_dev);
902 kfree(st->tx); 891 kfree(st->tx);
903 kfree(st->rx); 892 kfree(st->rx);
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 6e9006490742..3792b5761645 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -118,7 +118,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
118 struct iio_buffer *buffer; 118 struct iio_buffer *buffer;
119 int ret = 0; 119 int ret = 0;
120 120
121 buffer = iio_kfifo_allocate(indio_dev); 121 buffer = iio_kfifo_allocate();
122 if (!buffer) { 122 if (!buffer) {
123 ret = -ENOMEM; 123 ret = -ENOMEM;
124 return ret; 124 return ret;
@@ -180,8 +180,3 @@ error_iio_kfifo_free:
180 iio_kfifo_free(indio_dev->buffer); 180 iio_kfifo_free(indio_dev->buffer);
181 return ret; 181 return ret;
182} 182}
183
184void ade7758_uninitialize_ring(struct iio_dev *indio_dev)
185{
186 iio_buffer_unregister(indio_dev);
187}
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 7d217430616a..b0c7dbc8a428 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -116,7 +116,7 @@ static int ade7759_spi_read_reg_40(struct device *dev,
116 116
117 mutex_lock(&st->buf_lock); 117 mutex_lock(&st->buf_lock);
118 st->tx[0] = ADE7759_READ_REG(reg_address); 118 st->tx[0] = ADE7759_READ_REG(reg_address);
119 memset(&st->tx[1], 0 , 5); 119 memset(&st->tx[1], 0, 5);
120 120
121 ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); 121 ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
122 if (ret) { 122 if (ret) {
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
index a6b2f906bb1a..4410d7fdc1b4 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
@@ -85,6 +85,9 @@ static inline int __is_po2(unsigned long long val)
85 85
86#include <linux/list.h> 86#include <linux/list.h>
87 87
88int libcfs_arch_init(void);
89void libcfs_arch_cleanup(void);
90
88/* libcfs tcpip */ 91/* libcfs tcpip */
89int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask); 92int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
90int libcfs_ipif_enumerate(char ***names); 93int libcfs_ipif_enumerate(char ***names);
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
index 375586bf7312..808e49411a30 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
@@ -454,25 +454,23 @@ cfs_hash_bkt_size(struct cfs_hash *hs)
454 hs->hs_extra_bytes; 454 hs->hs_extra_bytes;
455} 455}
456 456
457#define CFS_HOP(hs, op) (hs)->hs_ops->hs_ ## op
458
459static inline unsigned 457static inline unsigned
460cfs_hash_id(struct cfs_hash *hs, const void *key, unsigned mask) 458cfs_hash_id(struct cfs_hash *hs, const void *key, unsigned mask)
461{ 459{
462 return CFS_HOP(hs, hash)(hs, key, mask); 460 return hs->hs_ops->hs_hash(hs, key, mask);
463} 461}
464 462
465static inline void * 463static inline void *
466cfs_hash_key(struct cfs_hash *hs, struct hlist_node *hnode) 464cfs_hash_key(struct cfs_hash *hs, struct hlist_node *hnode)
467{ 465{
468 return CFS_HOP(hs, key)(hnode); 466 return hs->hs_ops->hs_key(hnode);
469} 467}
470 468
471static inline void 469static inline void
472cfs_hash_keycpy(struct cfs_hash *hs, struct hlist_node *hnode, void *key) 470cfs_hash_keycpy(struct cfs_hash *hs, struct hlist_node *hnode, void *key)
473{ 471{
474 if (CFS_HOP(hs, keycpy) != NULL) 472 if (hs->hs_ops->hs_keycpy)
475 CFS_HOP(hs, keycpy)(hnode, key); 473 hs->hs_ops->hs_keycpy(hnode, key);
476} 474}
477 475
478/** 476/**
@@ -481,42 +479,38 @@ cfs_hash_keycpy(struct cfs_hash *hs, struct hlist_node *hnode, void *key)
481static inline int 479static inline int
482cfs_hash_keycmp(struct cfs_hash *hs, const void *key, struct hlist_node *hnode) 480cfs_hash_keycmp(struct cfs_hash *hs, const void *key, struct hlist_node *hnode)
483{ 481{
484 return CFS_HOP(hs, keycmp)(key, hnode); 482 return hs->hs_ops->hs_keycmp(key, hnode);
485} 483}
486 484
487static inline void * 485static inline void *
488cfs_hash_object(struct cfs_hash *hs, struct hlist_node *hnode) 486cfs_hash_object(struct cfs_hash *hs, struct hlist_node *hnode)
489{ 487{
490 return CFS_HOP(hs, object)(hnode); 488 return hs->hs_ops->hs_object(hnode);
491} 489}
492 490
493static inline void 491static inline void
494cfs_hash_get(struct cfs_hash *hs, struct hlist_node *hnode) 492cfs_hash_get(struct cfs_hash *hs, struct hlist_node *hnode)
495{ 493{
496 return CFS_HOP(hs, get)(hs, hnode); 494 return hs->hs_ops->hs_get(hs, hnode);
497} 495}
498 496
499static inline void 497static inline void
500cfs_hash_put_locked(struct cfs_hash *hs, struct hlist_node *hnode) 498cfs_hash_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
501{ 499{
502 LASSERT(CFS_HOP(hs, put_locked) != NULL); 500 return hs->hs_ops->hs_put_locked(hs, hnode);
503
504 return CFS_HOP(hs, put_locked)(hs, hnode);
505} 501}
506 502
507static inline void 503static inline void
508cfs_hash_put(struct cfs_hash *hs, struct hlist_node *hnode) 504cfs_hash_put(struct cfs_hash *hs, struct hlist_node *hnode)
509{ 505{
510 LASSERT(CFS_HOP(hs, put) != NULL); 506 return hs->hs_ops->hs_put(hs, hnode);
511
512 return CFS_HOP(hs, put)(hs, hnode);
513} 507}
514 508
515static inline void 509static inline void
516cfs_hash_exit(struct cfs_hash *hs, struct hlist_node *hnode) 510cfs_hash_exit(struct cfs_hash *hs, struct hlist_node *hnode)
517{ 511{
518 if (CFS_HOP(hs, exit)) 512 if (hs->hs_ops->hs_exit)
519 CFS_HOP(hs, exit)(hs, hnode); 513 hs->hs_ops->hs_exit(hs, hnode);
520} 514}
521 515
522static inline void cfs_hash_lock(struct cfs_hash *hs, int excl) 516static inline void cfs_hash_lock(struct cfs_hash *hs, int excl)
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
index 2817112c0633..3d86fb5b5481 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
@@ -458,14 +458,6 @@ struct libcfs_device_userstate {
458 struct page *ldu_memhog_root_page; 458 struct page *ldu_memhog_root_page;
459}; 459};
460 460
461/* what used to be in portals_lib.h */
462#ifndef MIN
463# define MIN(a, b) (((a) < (b)) ? (a) : (b))
464#endif
465#ifndef MAX
466# define MAX(a, b) (((a) > (b)) ? (a) : (b))
467#endif
468
469#define MKSTR(ptr) ((ptr)) ? (ptr) : "" 461#define MKSTR(ptr) ((ptr)) ? (ptr) : ""
470 462
471static inline int cfs_size_round4(int val) 463static inline int cfs_size_round4(int val)
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 7e89b3be1a74..0038d29a37fe 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -636,6 +636,7 @@ lnet_net2rnethash(__u32 net)
636} 636}
637 637
638extern lnd_t the_lolnd; 638extern lnd_t the_lolnd;
639extern int avoid_asym_router_failure;
639 640
640int lnet_cpt_of_nid_locked(lnet_nid_t nid); 641int lnet_cpt_of_nid_locked(lnet_nid_t nid);
641int lnet_cpt_of_nid(lnet_nid_t nid); 642int lnet_cpt_of_nid(lnet_nid_t nid);
@@ -752,9 +753,9 @@ int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
752void lnet_counters_get(lnet_counters_t *counters); 753void lnet_counters_get(lnet_counters_t *counters);
753void lnet_counters_reset(void); 754void lnet_counters_reset(void);
754 755
755unsigned int lnet_iov_nob(unsigned int niov, struct iovec *iov); 756unsigned int lnet_iov_nob(unsigned int niov, struct kvec *iov);
756int lnet_extract_iov(int dst_niov, struct iovec *dst, 757int lnet_extract_iov(int dst_niov, struct kvec *dst,
757 int src_niov, struct iovec *src, 758 int src_niov, struct kvec *src,
758 unsigned int offset, unsigned int len); 759 unsigned int offset, unsigned int len);
759 760
760unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov); 761unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov);
@@ -762,17 +763,17 @@ int lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
762 int src_niov, lnet_kiov_t *src, 763 int src_niov, lnet_kiov_t *src,
763 unsigned int offset, unsigned int len); 764 unsigned int offset, unsigned int len);
764 765
765void lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, 766void lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov,
766 unsigned int doffset, 767 unsigned int doffset,
767 unsigned int nsiov, struct iovec *siov, 768 unsigned int nsiov, struct kvec *siov,
768 unsigned int soffset, unsigned int nob); 769 unsigned int soffset, unsigned int nob);
769void lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, 770void lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov,
770 unsigned int iovoffset, 771 unsigned int iovoffset,
771 unsigned int nkiov, lnet_kiov_t *kiov, 772 unsigned int nkiov, lnet_kiov_t *kiov,
772 unsigned int kiovoffset, unsigned int nob); 773 unsigned int kiovoffset, unsigned int nob);
773void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov, 774void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
774 unsigned int kiovoffset, 775 unsigned int kiovoffset,
775 unsigned int niov, struct iovec *iov, 776 unsigned int niov, struct kvec *iov,
776 unsigned int iovoffset, unsigned int nob); 777 unsigned int iovoffset, unsigned int nob);
777void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov, 778void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
778 unsigned int doffset, 779 unsigned int doffset,
@@ -781,10 +782,10 @@ void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
781 782
782static inline void 783static inline void
783lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset, 784lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset,
784 unsigned int nsiov, struct iovec *siov, unsigned int soffset, 785 unsigned int nsiov, struct kvec *siov, unsigned int soffset,
785 unsigned int nob) 786 unsigned int nob)
786{ 787{
787 struct iovec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen}; 788 struct kvec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
788 789
789 lnet_copy_iov2iov(1, &diov, doffset, 790 lnet_copy_iov2iov(1, &diov, doffset,
790 nsiov, siov, soffset, nob); 791 nsiov, siov, soffset, nob);
@@ -795,17 +796,17 @@ lnet_copy_kiov2flat(int dlen, void *dest, unsigned int doffset,
795 unsigned int nsiov, lnet_kiov_t *skiov, 796 unsigned int nsiov, lnet_kiov_t *skiov,
796 unsigned int soffset, unsigned int nob) 797 unsigned int soffset, unsigned int nob)
797{ 798{
798 struct iovec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen}; 799 struct kvec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
799 800
800 lnet_copy_kiov2iov(1, &diov, doffset, 801 lnet_copy_kiov2iov(1, &diov, doffset,
801 nsiov, skiov, soffset, nob); 802 nsiov, skiov, soffset, nob);
802} 803}
803 804
804static inline void 805static inline void
805lnet_copy_flat2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset, 806lnet_copy_flat2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
806 int slen, void *src, unsigned int soffset, unsigned int nob) 807 int slen, void *src, unsigned int soffset, unsigned int nob)
807{ 808{
808 struct iovec siov = {/*.iov_base = */ src, /*.iov_len = */slen}; 809 struct kvec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
809 810
810 lnet_copy_iov2iov(ndiov, diov, doffset, 811 lnet_copy_iov2iov(ndiov, diov, doffset,
811 1, &siov, soffset, nob); 812 1, &siov, soffset, nob);
@@ -816,7 +817,7 @@ lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov,
816 unsigned int doffset, int slen, void *src, 817 unsigned int doffset, int slen, void *src,
817 unsigned int soffset, unsigned int nob) 818 unsigned int soffset, unsigned int nob)
818{ 819{
819 struct iovec siov = {/* .iov_base = */ src, /* .iov_len = */ slen}; 820 struct kvec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
820 821
821 lnet_copy_iov2kiov(ndiov, dkiov, doffset, 822 lnet_copy_iov2kiov(ndiov, dkiov, doffset,
822 1, &siov, soffset, nob); 823 1, &siov, soffset, nob);
@@ -851,6 +852,7 @@ int lnet_peer_buffer_credits(lnet_ni_t *ni);
851 852
852int lnet_router_checker_start(void); 853int lnet_router_checker_start(void);
853void lnet_router_checker_stop(void); 854void lnet_router_checker_stop(void);
855void lnet_router_ni_update_locked(lnet_peer_t *gw, __u32 net);
854void lnet_swap_pinginfo(lnet_ping_info_t *info); 856void lnet_swap_pinginfo(lnet_ping_info_t *info);
855 857
856int lnet_ping_target_init(void); 858int lnet_ping_target_init(void);
@@ -870,4 +872,12 @@ void lnet_peer_tables_destroy(void);
870int lnet_peer_tables_create(void); 872int lnet_peer_tables_create(void);
871void lnet_debug_peer(lnet_nid_t nid); 873void lnet_debug_peer(lnet_nid_t nid);
872 874
875static inline void lnet_peer_set_alive(lnet_peer_t *lp)
876{
877 lp->lp_last_alive = lp->lp_last_query = get_seconds();
878 if (!lp->lp_alive)
879 lnet_notify_locked(lp, 0, 1, lp->lp_last_alive);
880}
881
882
873#endif 883#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index f16213f1771a..50537668f59d 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -217,7 +217,7 @@ typedef struct lnet_msg {
217 unsigned int msg_wanted; 217 unsigned int msg_wanted;
218 unsigned int msg_offset; 218 unsigned int msg_offset;
219 unsigned int msg_niov; 219 unsigned int msg_niov;
220 struct iovec *msg_iov; 220 struct kvec *msg_iov;
221 lnet_kiov_t *msg_kiov; 221 lnet_kiov_t *msg_kiov;
222 222
223 lnet_event_t msg_ev; 223 lnet_event_t msg_ev;
@@ -271,7 +271,7 @@ typedef struct lnet_libmd {
271 lnet_eq_t *md_eq; 271 lnet_eq_t *md_eq;
272 unsigned int md_niov; /* # frags */ 272 unsigned int md_niov; /* # frags */
273 union { 273 union {
274 struct iovec iov[LNET_MAX_IOV]; 274 struct kvec iov[LNET_MAX_IOV];
275 lnet_kiov_t kiov[LNET_MAX_IOV]; 275 lnet_kiov_t kiov[LNET_MAX_IOV];
276 } md_iov; 276 } md_iov;
277} lnet_libmd_t; 277} lnet_libmd_t;
@@ -346,7 +346,7 @@ typedef struct lnet_lnd {
346 * credit if the LND does flow control. */ 346 * credit if the LND does flow control. */
347 int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg, 347 int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
348 int delayed, unsigned int niov, 348 int delayed, unsigned int niov,
349 struct iovec *iov, lnet_kiov_t *kiov, 349 struct kvec *iov, lnet_kiov_t *kiov,
350 unsigned int offset, unsigned int mlen, unsigned int rlen); 350 unsigned int offset, unsigned int mlen, unsigned int rlen);
351 351
352 /* lnet_parse() has had to delay processing of this message 352 /* lnet_parse() has had to delay processing of this message
@@ -622,7 +622,7 @@ typedef struct lnet_portal {
622 /* Match table for each CPT */ 622 /* Match table for each CPT */
623 struct lnet_match_table **ptl_mtables; 623 struct lnet_match_table **ptl_mtables;
624 /* spread rotor of incoming "PUT" */ 624 /* spread rotor of incoming "PUT" */
625 int ptl_rotor; 625 unsigned int ptl_rotor;
626 /* # active entries for this portal */ 626 /* # active entries for this portal */
627 int ptl_mt_nmaps; 627 int ptl_mt_nmaps;
628 /* array of active entries' cpu-partition-id */ 628 /* array of active entries' cpu-partition-id */
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index 62b575deac3a..651016919669 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1538,7 +1538,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status)
1538 fmr->fmr_pfmr = NULL; 1538 fmr->fmr_pfmr = NULL;
1539 1539
1540 spin_lock(&fps->fps_lock); 1540 spin_lock(&fps->fps_lock);
1541 fpo->fpo_map_count --; /* decref the pool */ 1541 fpo->fpo_map_count--; /* decref the pool */
1542 1542
1543 list_for_each_entry_safe(fpo, tmp, &fps->fps_pool_list, fpo_list) { 1543 list_for_each_entry_safe(fpo, tmp, &fps->fps_pool_list, fpo_list) {
1544 /* the first pool is persistent */ 1544 /* the first pool is persistent */
@@ -1547,7 +1547,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status)
1547 1547
1548 if (kiblnd_fmr_pool_is_idle(fpo, now)) { 1548 if (kiblnd_fmr_pool_is_idle(fpo, now)) {
1549 list_move(&fpo->fpo_list, &zombies); 1549 list_move(&fpo->fpo_list, &zombies);
1550 fps->fps_version ++; 1550 fps->fps_version++;
1551 } 1551 }
1552 } 1552 }
1553 spin_unlock(&fps->fps_lock); 1553 spin_unlock(&fps->fps_lock);
@@ -1752,7 +1752,7 @@ kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node)
1752 1752
1753 LASSERT (pool->po_allocated > 0); 1753 LASSERT (pool->po_allocated > 0);
1754 list_add(node, &pool->po_free_list); 1754 list_add(node, &pool->po_free_list);
1755 pool->po_allocated --; 1755 pool->po_allocated--;
1756 1756
1757 list_for_each_entry_safe(pool, tmp, &ps->ps_pool_list, po_list) { 1757 list_for_each_entry_safe(pool, tmp, &ps->ps_pool_list, po_list) {
1758 /* the first pool is persistent */ 1758 /* the first pool is persistent */
@@ -1781,7 +1781,7 @@ kiblnd_pool_alloc_node(kib_poolset_t *ps)
1781 if (list_empty(&pool->po_free_list)) 1781 if (list_empty(&pool->po_free_list))
1782 continue; 1782 continue;
1783 1783
1784 pool->po_allocated ++; 1784 pool->po_allocated++;
1785 pool->po_deadline = cfs_time_shift(IBLND_POOL_DEADLINE); 1785 pool->po_deadline = cfs_time_shift(IBLND_POOL_DEADLINE);
1786 node = pool->po_free_list.next; 1786 node = pool->po_free_list.next;
1787 list_del(node); 1787 list_del(node);
@@ -1864,7 +1864,7 @@ kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev,
1864 return -EAGAIN; 1864 return -EAGAIN;
1865 } 1865 }
1866 1866
1867 for (i = 0; i < rd->rd_nfrags; i ++) { 1867 for (i = 0; i < rd->rd_nfrags; i++) {
1868 pmr->pmr_ipb[i].addr = rd->rd_frags[i].rf_addr; 1868 pmr->pmr_ipb[i].addr = rd->rd_frags[i].rf_addr;
1869 pmr->pmr_ipb[i].size = rd->rd_frags[i].rf_nob; 1869 pmr->pmr_ipb[i].size = rd->rd_frags[i].rf_nob;
1870 } 1870 }
@@ -2117,7 +2117,7 @@ kiblnd_tx_init(kib_pool_t *pool, struct list_head *node)
2117 tps_poolset); 2117 tps_poolset);
2118 kib_tx_t *tx = list_entry(node, kib_tx_t, tx_list); 2118 kib_tx_t *tx = list_entry(node, kib_tx_t, tx_list);
2119 2119
2120 tx->tx_cookie = tps->tps_next_tx_cookie ++; 2120 tx->tx_cookie = tps->tps_next_tx_cookie++;
2121} 2121}
2122 2122
2123static void 2123static void
@@ -2326,7 +2326,7 @@ kiblnd_hdev_get_attr(kib_hca_dev_t *hdev)
2326 } 2326 }
2327 2327
2328 for (hdev->ibh_mr_shift = 0; 2328 for (hdev->ibh_mr_shift = 0;
2329 hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift ++) { 2329 hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift++) {
2330 if (hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) || 2330 if (hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) ||
2331 hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) - 1) 2331 hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) - 1)
2332 return 0; 2332 return 0;
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index b02b4ec1e29d..ab128dee9483 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -1026,5 +1026,5 @@ int kiblnd_post_rx (kib_rx_t *rx, int credit);
1026 1026
1027int kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg); 1027int kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
1028int kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed, 1028int kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
1029 unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov, 1029 unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
1030 unsigned int offset, unsigned int mlen, unsigned int rlen); 1030 unsigned int offset, unsigned int mlen, unsigned int rlen);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index b48d7edf5669..48d885dc51d9 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -697,7 +697,7 @@ kiblnd_map_tx(lnet_ni_t *ni, kib_tx_t *tx,
697 697
698static int 698static int
699kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd, 699kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
700 unsigned int niov, struct iovec *iov, int offset, int nob) 700 unsigned int niov, struct kvec *iov, int offset, int nob)
701{ 701{
702 kib_net_t *net = ni->ni_data; 702 kib_net_t *net = ni->ni_data;
703 struct page *page; 703 struct page *page;
@@ -1125,8 +1125,9 @@ kiblnd_init_rdma (kib_conn_t *conn, kib_tx_t *tx, int type,
1125 break; 1125 break;
1126 } 1126 }
1127 1127
1128 wrknob = MIN(MIN(kiblnd_rd_frag_size(srcrd, srcidx), 1128 wrknob = min(min(kiblnd_rd_frag_size(srcrd, srcidx),
1129 kiblnd_rd_frag_size(dstrd, dstidx)), resid); 1129 kiblnd_rd_frag_size(dstrd, dstidx)),
1130 (__u32) resid);
1130 1131
1131 sge = &tx->tx_sge[tx->tx_nwrq]; 1132 sge = &tx->tx_sge[tx->tx_nwrq];
1132 sge->addr = kiblnd_rd_frag_addr(srcrd, srcidx); 1133 sge->addr = kiblnd_rd_frag_addr(srcrd, srcidx);
@@ -1461,7 +1462,7 @@ kiblnd_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
1461 int target_is_router = lntmsg->msg_target_is_router; 1462 int target_is_router = lntmsg->msg_target_is_router;
1462 int routing = lntmsg->msg_routing; 1463 int routing = lntmsg->msg_routing;
1463 unsigned int payload_niov = lntmsg->msg_niov; 1464 unsigned int payload_niov = lntmsg->msg_niov;
1464 struct iovec *payload_iov = lntmsg->msg_iov; 1465 struct kvec *payload_iov = lntmsg->msg_iov;
1465 lnet_kiov_t *payload_kiov = lntmsg->msg_kiov; 1466 lnet_kiov_t *payload_kiov = lntmsg->msg_kiov;
1466 unsigned int payload_offset = lntmsg->msg_offset; 1467 unsigned int payload_offset = lntmsg->msg_offset;
1467 unsigned int payload_nob = lntmsg->msg_len; 1468 unsigned int payload_nob = lntmsg->msg_len;
@@ -1628,7 +1629,7 @@ kiblnd_reply (lnet_ni_t *ni, kib_rx_t *rx, lnet_msg_t *lntmsg)
1628{ 1629{
1629 lnet_process_id_t target = lntmsg->msg_target; 1630 lnet_process_id_t target = lntmsg->msg_target;
1630 unsigned int niov = lntmsg->msg_niov; 1631 unsigned int niov = lntmsg->msg_niov;
1631 struct iovec *iov = lntmsg->msg_iov; 1632 struct kvec *iov = lntmsg->msg_iov;
1632 lnet_kiov_t *kiov = lntmsg->msg_kiov; 1633 lnet_kiov_t *kiov = lntmsg->msg_kiov;
1633 unsigned int offset = lntmsg->msg_offset; 1634 unsigned int offset = lntmsg->msg_offset;
1634 unsigned int nob = lntmsg->msg_len; 1635 unsigned int nob = lntmsg->msg_len;
@@ -1687,7 +1688,7 @@ kiblnd_reply (lnet_ni_t *ni, kib_rx_t *rx, lnet_msg_t *lntmsg)
1687 1688
1688int 1689int
1689kiblnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed, 1690kiblnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
1690 unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov, 1691 unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
1691 unsigned int offset, unsigned int mlen, unsigned int rlen) 1692 unsigned int offset, unsigned int mlen, unsigned int rlen)
1692{ 1693{
1693 kib_rx_t *rx = private; 1694 kib_rx_t *rx = private;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index 9188b34e6948..5956dbac5d04 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -773,7 +773,7 @@ ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips)
773 /* Only match interfaces for additional connections 773 /* Only match interfaces for additional connections
774 * if I have > 1 interface */ 774 * if I have > 1 interface */
775 n_ips = (net->ksnn_ninterfaces < 2) ? 0 : 775 n_ips = (net->ksnn_ninterfaces < 2) ? 0 :
776 MIN(n_peerips, net->ksnn_ninterfaces); 776 min(n_peerips, net->ksnn_ninterfaces);
777 777
778 for (i = 0; peer->ksnp_n_passive_ips < n_ips; i++) { 778 for (i = 0; peer->ksnp_n_passive_ips < n_ips; i++) {
779 /* ^ yes really... */ 779 /* ^ yes really... */
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
index a29d4da6e343..03488d289c74 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
@@ -69,7 +69,7 @@ typedef struct /* per scheduler state */
69 int kss_nconns; 69 int kss_nconns;
70 struct ksock_sched_info *kss_info; /* owner of it */ 70 struct ksock_sched_info *kss_info; /* owner of it */
71 struct page *kss_rx_scratch_pgs[LNET_MAX_IOV]; 71 struct page *kss_rx_scratch_pgs[LNET_MAX_IOV];
72 struct iovec kss_scratch_iov[LNET_MAX_IOV]; 72 struct kvec kss_scratch_iov[LNET_MAX_IOV];
73} ksock_sched_t; 73} ksock_sched_t;
74 74
75struct ksock_sched_info { 75struct ksock_sched_info {
@@ -213,7 +213,7 @@ typedef struct /* transmit packet */
213 int tx_nob; /* # packet bytes */ 213 int tx_nob; /* # packet bytes */
214 int tx_resid; /* residual bytes */ 214 int tx_resid; /* residual bytes */
215 int tx_niov; /* # packet iovec frags */ 215 int tx_niov; /* # packet iovec frags */
216 struct iovec *tx_iov; /* packet iovec frags */ 216 struct kvec *tx_iov; /* packet iovec frags */
217 int tx_nkiov; /* # packet page frags */ 217 int tx_nkiov; /* # packet page frags */
218 unsigned short tx_zc_aborted; /* aborted ZC request */ 218 unsigned short tx_zc_aborted; /* aborted ZC request */
219 unsigned short tx_zc_capable:1; /* payload is large enough for ZC */ 219 unsigned short tx_zc_capable:1; /* payload is large enough for ZC */
@@ -227,11 +227,11 @@ typedef struct /* transmit packet */
227 int tx_desc_size; /* size of this descriptor */ 227 int tx_desc_size; /* size of this descriptor */
228 union { 228 union {
229 struct { 229 struct {
230 struct iovec iov; /* virt hdr */ 230 struct kvec iov; /* virt hdr */
231 lnet_kiov_t kiov[0]; /* paged payload */ 231 lnet_kiov_t kiov[0]; /* paged payload */
232 } paged; 232 } paged;
233 struct { 233 struct {
234 struct iovec iov[1]; /* virt hdr + payload */ 234 struct kvec iov[1]; /* virt hdr + payload */
235 } virt; 235 } virt;
236 } tx_frags; 236 } tx_frags;
237} ksock_tx_t; 237} ksock_tx_t;
@@ -243,7 +243,7 @@ typedef struct /* transmit packet */
243/* space for the rx frag descriptors; we either read a single contiguous 243/* space for the rx frag descriptors; we either read a single contiguous
244 * header, or up to LNET_MAX_IOV frags of payload of either type. */ 244 * header, or up to LNET_MAX_IOV frags of payload of either type. */
245typedef union { 245typedef union {
246 struct iovec iov[LNET_MAX_IOV]; 246 struct kvec iov[LNET_MAX_IOV];
247 lnet_kiov_t kiov[LNET_MAX_IOV]; 247 lnet_kiov_t kiov[LNET_MAX_IOV];
248} ksock_rxiovspace_t; 248} ksock_rxiovspace_t;
249 249
@@ -284,7 +284,7 @@ typedef struct ksock_conn {
284 int ksnc_rx_nob_left; /* # bytes to next hdr/body */ 284 int ksnc_rx_nob_left; /* # bytes to next hdr/body */
285 int ksnc_rx_nob_wanted; /* bytes actually wanted */ 285 int ksnc_rx_nob_wanted; /* bytes actually wanted */
286 int ksnc_rx_niov; /* # iovec frags */ 286 int ksnc_rx_niov; /* # iovec frags */
287 struct iovec *ksnc_rx_iov; /* the iovec frags */ 287 struct kvec *ksnc_rx_iov; /* the iovec frags */
288 int ksnc_rx_nkiov; /* # page frags */ 288 int ksnc_rx_nkiov; /* # page frags */
289 lnet_kiov_t *ksnc_rx_kiov; /* the page frags */ 289 lnet_kiov_t *ksnc_rx_kiov; /* the page frags */
290 ksock_rxiovspace_t ksnc_rx_iov_space;/* space for frag descriptors */ 290 ksock_rxiovspace_t ksnc_rx_iov_space;/* space for frag descriptors */
@@ -517,7 +517,7 @@ int ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg);
517int ksocknal_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg); 517int ksocknal_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
518int ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, 518int ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
519 int delayed, unsigned int niov, 519 int delayed, unsigned int niov,
520 struct iovec *iov, lnet_kiov_t *kiov, 520 struct kvec *iov, lnet_kiov_t *kiov,
521 unsigned int offset, unsigned int mlen, unsigned int rlen); 521 unsigned int offset, unsigned int mlen, unsigned int rlen);
522int ksocknal_accept(lnet_ni_t *ni, struct socket *sock); 522int ksocknal_accept(lnet_ni_t *ni, struct socket *sock);
523 523
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index e6c1d3647952..92760fe94184 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -110,7 +110,7 @@ ksocknal_free_tx (ksock_tx_t *tx)
110static int 110static int
111ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx) 111ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
112{ 112{
113 struct iovec *iov = tx->tx_iov; 113 struct kvec *iov = tx->tx_iov;
114 int nob; 114 int nob;
115 int rc; 115 int rc;
116 116
@@ -251,7 +251,7 @@ ksocknal_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
251static int 251static int
252ksocknal_recv_iov (ksock_conn_t *conn) 252ksocknal_recv_iov (ksock_conn_t *conn)
253{ 253{
254 struct iovec *iov = conn->ksnc_rx_iov; 254 struct kvec *iov = conn->ksnc_rx_iov;
255 int nob; 255 int nob;
256 int rc; 256 int rc;
257 257
@@ -926,7 +926,7 @@ ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
926 int type = lntmsg->msg_type; 926 int type = lntmsg->msg_type;
927 lnet_process_id_t target = lntmsg->msg_target; 927 lnet_process_id_t target = lntmsg->msg_target;
928 unsigned int payload_niov = lntmsg->msg_niov; 928 unsigned int payload_niov = lntmsg->msg_niov;
929 struct iovec *payload_iov = lntmsg->msg_iov; 929 struct kvec *payload_iov = lntmsg->msg_iov;
930 lnet_kiov_t *payload_kiov = lntmsg->msg_kiov; 930 lnet_kiov_t *payload_kiov = lntmsg->msg_kiov;
931 unsigned int payload_offset = lntmsg->msg_offset; 931 unsigned int payload_offset = lntmsg->msg_offset;
932 unsigned int payload_nob = lntmsg->msg_len; 932 unsigned int payload_nob = lntmsg->msg_len;
@@ -1047,8 +1047,8 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
1047 case KSOCK_PROTO_V2: 1047 case KSOCK_PROTO_V2:
1048 case KSOCK_PROTO_V3: 1048 case KSOCK_PROTO_V3:
1049 conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER; 1049 conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
1050 conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space; 1050 conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
1051 conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg; 1051 conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg;
1052 1052
1053 conn->ksnc_rx_nob_wanted = offsetof(ksock_msg_t, ksm_u); 1053 conn->ksnc_rx_nob_wanted = offsetof(ksock_msg_t, ksm_u);
1054 conn->ksnc_rx_nob_left = offsetof(ksock_msg_t, ksm_u); 1054 conn->ksnc_rx_nob_left = offsetof(ksock_msg_t, ksm_u);
@@ -1061,8 +1061,8 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
1061 conn->ksnc_rx_nob_wanted = sizeof(lnet_hdr_t); 1061 conn->ksnc_rx_nob_wanted = sizeof(lnet_hdr_t);
1062 conn->ksnc_rx_nob_left = sizeof(lnet_hdr_t); 1062 conn->ksnc_rx_nob_left = sizeof(lnet_hdr_t);
1063 1063
1064 conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space; 1064 conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
1065 conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg.ksm_u.lnetmsg; 1065 conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
1066 conn->ksnc_rx_iov[0].iov_len = sizeof (lnet_hdr_t); 1066 conn->ksnc_rx_iov[0].iov_len = sizeof (lnet_hdr_t);
1067 break; 1067 break;
1068 1068
@@ -1082,12 +1082,12 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
1082 1082
1083 conn->ksnc_rx_state = SOCKNAL_RX_SLOP; 1083 conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
1084 conn->ksnc_rx_nob_left = nob_to_skip; 1084 conn->ksnc_rx_nob_left = nob_to_skip;
1085 conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space; 1085 conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
1086 skipped = 0; 1086 skipped = 0;
1087 niov = 0; 1087 niov = 0;
1088 1088
1089 do { 1089 do {
1090 nob = MIN (nob_to_skip, sizeof (ksocknal_slop_buffer)); 1090 nob = min_t(int, nob_to_skip, sizeof(ksocknal_slop_buffer));
1091 1091
1092 conn->ksnc_rx_iov[niov].iov_base = ksocknal_slop_buffer; 1092 conn->ksnc_rx_iov[niov].iov_base = ksocknal_slop_buffer;
1093 conn->ksnc_rx_iov[niov].iov_len = nob; 1093 conn->ksnc_rx_iov[niov].iov_len = nob;
@@ -1212,8 +1212,8 @@ ksocknal_process_receive (ksock_conn_t *conn)
1212 conn->ksnc_rx_nob_wanted = sizeof(ksock_lnet_msg_t); 1212 conn->ksnc_rx_nob_wanted = sizeof(ksock_lnet_msg_t);
1213 conn->ksnc_rx_nob_left = sizeof(ksock_lnet_msg_t); 1213 conn->ksnc_rx_nob_left = sizeof(ksock_lnet_msg_t);
1214 1214
1215 conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space; 1215 conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
1216 conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg.ksm_u.lnetmsg; 1216 conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
1217 conn->ksnc_rx_iov[0].iov_len = sizeof(ksock_lnet_msg_t); 1217 conn->ksnc_rx_iov[0].iov_len = sizeof(ksock_lnet_msg_t);
1218 1218
1219 conn->ksnc_rx_niov = 1; 1219 conn->ksnc_rx_niov = 1;
@@ -1311,7 +1311,7 @@ ksocknal_process_receive (ksock_conn_t *conn)
1311 1311
1312int 1312int
1313ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, 1313ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
1314 unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov, 1314 unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
1315 unsigned int offset, unsigned int mlen, unsigned int rlen) 1315 unsigned int offset, unsigned int mlen, unsigned int rlen)
1316{ 1316{
1317 ksock_conn_t *conn = (ksock_conn_t *)private; 1317 ksock_conn_t *conn = (ksock_conn_t *)private;
@@ -1950,10 +1950,10 @@ ksocknal_connect (ksock_route_t *route)
1950 /* This is a retry rather than a new connection */ 1950 /* This is a retry rather than a new connection */
1951 route->ksnr_retry_interval *= 2; 1951 route->ksnr_retry_interval *= 2;
1952 route->ksnr_retry_interval = 1952 route->ksnr_retry_interval =
1953 MAX(route->ksnr_retry_interval, 1953 max(route->ksnr_retry_interval,
1954 cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms)/1000); 1954 cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms)/1000);
1955 route->ksnr_retry_interval = 1955 route->ksnr_retry_interval =
1956 MIN(route->ksnr_retry_interval, 1956 min(route->ksnr_retry_interval,
1957 cfs_time_seconds(*ksocknal_tunables.ksnd_max_reconnectms)/1000); 1957 cfs_time_seconds(*ksocknal_tunables.ksnd_max_reconnectms)/1000);
1958 1958
1959 LASSERT (route->ksnr_retry_interval != 0); 1959 LASSERT (route->ksnr_retry_interval != 0);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
index 245c9d7560af..66cc509295e5 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
@@ -92,11 +92,11 @@ ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
92 92
93 { 93 {
94#if SOCKNAL_SINGLE_FRAG_TX 94#if SOCKNAL_SINGLE_FRAG_TX
95 struct iovec scratch; 95 struct kvec scratch;
96 struct iovec *scratchiov = &scratch; 96 struct kvec *scratchiov = &scratch;
97 unsigned int niov = 1; 97 unsigned int niov = 1;
98#else 98#else
99 struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; 99 struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
100 unsigned int niov = tx->tx_niov; 100 unsigned int niov = tx->tx_niov;
101#endif 101#endif
102 struct msghdr msg = {.msg_flags = MSG_DONTWAIT}; 102 struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
@@ -111,7 +111,7 @@ ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
111 nob < tx->tx_resid) 111 nob < tx->tx_resid)
112 msg.msg_flags |= MSG_MORE; 112 msg.msg_flags |= MSG_MORE;
113 113
114 rc = kernel_sendmsg(sock, &msg, (struct kvec *)scratchiov, niov, nob); 114 rc = kernel_sendmsg(sock, &msg, scratchiov, niov, nob);
115 } 115 }
116 return rc; 116 return rc;
117} 117}
@@ -153,14 +153,14 @@ ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
153 } 153 }
154 } else { 154 } else {
155#if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK 155#if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
156 struct iovec scratch; 156 struct kvec scratch;
157 struct iovec *scratchiov = &scratch; 157 struct kvec *scratchiov = &scratch;
158 unsigned int niov = 1; 158 unsigned int niov = 1;
159#else 159#else
160#ifdef CONFIG_HIGHMEM 160#ifdef CONFIG_HIGHMEM
161#warning "XXX risk of kmap deadlock on multiple frags..." 161#warning "XXX risk of kmap deadlock on multiple frags..."
162#endif 162#endif
163 struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; 163 struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
164 unsigned int niov = tx->tx_nkiov; 164 unsigned int niov = tx->tx_nkiov;
165#endif 165#endif
166 struct msghdr msg = {.msg_flags = MSG_DONTWAIT}; 166 struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
@@ -203,14 +203,14 @@ int
203ksocknal_lib_recv_iov (ksock_conn_t *conn) 203ksocknal_lib_recv_iov (ksock_conn_t *conn)
204{ 204{
205#if SOCKNAL_SINGLE_FRAG_RX 205#if SOCKNAL_SINGLE_FRAG_RX
206 struct iovec scratch; 206 struct kvec scratch;
207 struct iovec *scratchiov = &scratch; 207 struct kvec *scratchiov = &scratch;
208 unsigned int niov = 1; 208 unsigned int niov = 1;
209#else 209#else
210 struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; 210 struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
211 unsigned int niov = conn->ksnc_rx_niov; 211 unsigned int niov = conn->ksnc_rx_niov;
212#endif 212#endif
213 struct iovec *iov = conn->ksnc_rx_iov; 213 struct kvec *iov = conn->ksnc_rx_iov;
214 struct msghdr msg = { 214 struct msghdr msg = {
215 .msg_flags = 0 215 .msg_flags = 0
216 }; 216 };
@@ -232,7 +232,7 @@ ksocknal_lib_recv_iov (ksock_conn_t *conn)
232 LASSERT (nob <= conn->ksnc_rx_nob_wanted); 232 LASSERT (nob <= conn->ksnc_rx_nob_wanted);
233 233
234 rc = kernel_recvmsg(conn->ksnc_sock, &msg, 234 rc = kernel_recvmsg(conn->ksnc_sock, &msg,
235 (struct kvec *)scratchiov, niov, nob, MSG_DONTWAIT); 235 scratchiov, niov, nob, MSG_DONTWAIT);
236 236
237 saved_csum = 0; 237 saved_csum = 0;
238 if (conn->ksnc_proto == &ksocknal_protocol_v2x) { 238 if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
@@ -269,7 +269,7 @@ ksocknal_lib_kiov_vunmap(void *addr)
269 269
270static void * 270static void *
271ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov, 271ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
272 struct iovec *iov, struct page **pages) 272 struct kvec *iov, struct page **pages)
273{ 273{
274 void *addr; 274 void *addr;
275 int nob; 275 int nob;
@@ -307,15 +307,15 @@ int
307ksocknal_lib_recv_kiov (ksock_conn_t *conn) 307ksocknal_lib_recv_kiov (ksock_conn_t *conn)
308{ 308{
309#if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK 309#if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
310 struct iovec scratch; 310 struct kvec scratch;
311 struct iovec *scratchiov = &scratch; 311 struct kvec *scratchiov = &scratch;
312 struct page **pages = NULL; 312 struct page **pages = NULL;
313 unsigned int niov = 1; 313 unsigned int niov = 1;
314#else 314#else
315#ifdef CONFIG_HIGHMEM 315#ifdef CONFIG_HIGHMEM
316#warning "XXX risk of kmap deadlock on multiple frags..." 316#warning "XXX risk of kmap deadlock on multiple frags..."
317#endif 317#endif
318 struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov; 318 struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
319 struct page **pages = conn->ksnc_scheduler->kss_rx_scratch_pgs; 319 struct page **pages = conn->ksnc_scheduler->kss_rx_scratch_pgs;
320 unsigned int niov = conn->ksnc_rx_nkiov; 320 unsigned int niov = conn->ksnc_rx_nkiov;
321#endif 321#endif
@@ -390,13 +390,13 @@ ksocknal_lib_csum_tx(ksock_tx_t *tx)
390 __u32 csum; 390 __u32 csum;
391 void *base; 391 void *base;
392 392
393 LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg); 393 LASSERT(tx->tx_iov[0].iov_base == &tx->tx_msg);
394 LASSERT(tx->tx_conn != NULL); 394 LASSERT(tx->tx_conn != NULL);
395 LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x); 395 LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
396 396
397 tx->tx_msg.ksm_csum = 0; 397 tx->tx_msg.ksm_csum = 0;
398 398
399 csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base, 399 csum = ksocknal_csum(~0, tx->tx_iov[0].iov_base,
400 tx->tx_iov[0].iov_len); 400 tx->tx_iov[0].iov_len);
401 401
402 if (tx->tx_kiov != NULL) { 402 if (tx->tx_kiov != NULL) {
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
index ea9d80f40cab..b2f88eb47bba 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
@@ -717,7 +717,7 @@ ksocknal_pack_msg_v1(ksock_tx_t *tx)
717 LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP); 717 LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
718 LASSERT(tx->tx_lnetmsg != NULL); 718 LASSERT(tx->tx_lnetmsg != NULL);
719 719
720 tx->tx_iov[0].iov_base = (void *)&tx->tx_lnetmsg->msg_hdr; 720 tx->tx_iov[0].iov_base = &tx->tx_lnetmsg->msg_hdr;
721 tx->tx_iov[0].iov_len = sizeof(lnet_hdr_t); 721 tx->tx_iov[0].iov_len = sizeof(lnet_hdr_t);
722 722
723 tx->tx_resid = tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t); 723 tx->tx_resid = tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
@@ -726,7 +726,7 @@ ksocknal_pack_msg_v1(ksock_tx_t *tx)
726static void 726static void
727ksocknal_pack_msg_v2(ksock_tx_t *tx) 727ksocknal_pack_msg_v2(ksock_tx_t *tx)
728{ 728{
729 tx->tx_iov[0].iov_base = (void *)&tx->tx_msg; 729 tx->tx_iov[0].iov_base = &tx->tx_msg;
730 730
731 if (tx->tx_lnetmsg != NULL) { 731 if (tx->tx_lnetmsg != NULL) {
732 LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP); 732 LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index c8c1ed84fe5c..0f53c761f1a9 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -158,7 +158,7 @@ fail_peer(lnet_nid_t nid, int outgoing)
158} 158}
159 159
160unsigned int 160unsigned int
161lnet_iov_nob(unsigned int niov, struct iovec *iov) 161lnet_iov_nob(unsigned int niov, struct kvec *iov)
162{ 162{
163 unsigned int nob = 0; 163 unsigned int nob = 0;
164 164
@@ -170,8 +170,8 @@ lnet_iov_nob(unsigned int niov, struct iovec *iov)
170EXPORT_SYMBOL(lnet_iov_nob); 170EXPORT_SYMBOL(lnet_iov_nob);
171 171
172void 172void
173lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset, 173lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
174 unsigned int nsiov, struct iovec *siov, unsigned int soffset, 174 unsigned int nsiov, struct kvec *siov, unsigned int soffset,
175 unsigned int nob) 175 unsigned int nob)
176{ 176{
177 /* NB diov, siov are READ-ONLY */ 177 /* NB diov, siov are READ-ONLY */
@@ -201,9 +201,9 @@ lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
201 do { 201 do {
202 LASSERT(ndiov > 0); 202 LASSERT(ndiov > 0);
203 LASSERT(nsiov > 0); 203 LASSERT(nsiov > 0);
204 this_nob = MIN(diov->iov_len - doffset, 204 this_nob = min(diov->iov_len - doffset,
205 siov->iov_len - soffset); 205 siov->iov_len - soffset);
206 this_nob = MIN(this_nob, nob); 206 this_nob = min(this_nob, nob);
207 207
208 memcpy((char *)diov->iov_base + doffset, 208 memcpy((char *)diov->iov_base + doffset,
209 (char *)siov->iov_base + soffset, this_nob); 209 (char *)siov->iov_base + soffset, this_nob);
@@ -229,8 +229,8 @@ lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
229EXPORT_SYMBOL(lnet_copy_iov2iov); 229EXPORT_SYMBOL(lnet_copy_iov2iov);
230 230
231int 231int
232lnet_extract_iov(int dst_niov, struct iovec *dst, 232lnet_extract_iov(int dst_niov, struct kvec *dst,
233 int src_niov, struct iovec *src, 233 int src_niov, struct kvec *src,
234 unsigned int offset, unsigned int len) 234 unsigned int offset, unsigned int len)
235{ 235{
236 /* Initialise 'dst' to the subset of 'src' starting at 'offset', 236 /* Initialise 'dst' to the subset of 'src' starting at 'offset',
@@ -322,9 +322,9 @@ lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
322 do { 322 do {
323 LASSERT(ndiov > 0); 323 LASSERT(ndiov > 0);
324 LASSERT(nsiov > 0); 324 LASSERT(nsiov > 0);
325 this_nob = MIN(diov->kiov_len - doffset, 325 this_nob = min(diov->kiov_len - doffset,
326 siov->kiov_len - soffset); 326 siov->kiov_len - soffset);
327 this_nob = MIN(this_nob, nob); 327 this_nob = min(this_nob, nob);
328 328
329 if (daddr == NULL) 329 if (daddr == NULL)
330 daddr = ((char *)kmap(diov->kiov_page)) + 330 daddr = ((char *)kmap(diov->kiov_page)) +
@@ -371,7 +371,7 @@ lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
371EXPORT_SYMBOL(lnet_copy_kiov2kiov); 371EXPORT_SYMBOL(lnet_copy_kiov2kiov);
372 372
373void 373void
374lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, unsigned int iovoffset, 374lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov, unsigned int iovoffset,
375 unsigned int nkiov, lnet_kiov_t *kiov, 375 unsigned int nkiov, lnet_kiov_t *kiov,
376 unsigned int kiovoffset, unsigned int nob) 376 unsigned int kiovoffset, unsigned int nob)
377{ 377{
@@ -403,9 +403,9 @@ lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, unsigned int iovoffset,
403 do { 403 do {
404 LASSERT(niov > 0); 404 LASSERT(niov > 0);
405 LASSERT(nkiov > 0); 405 LASSERT(nkiov > 0);
406 this_nob = MIN(iov->iov_len - iovoffset, 406 this_nob = min(iov->iov_len - iovoffset,
407 kiov->kiov_len - kiovoffset); 407 (__kernel_size_t) kiov->kiov_len - kiovoffset);
408 this_nob = MIN(this_nob, nob); 408 this_nob = min(this_nob, nob);
409 409
410 if (addr == NULL) 410 if (addr == NULL)
411 addr = ((char *)kmap(kiov->kiov_page)) + 411 addr = ((char *)kmap(kiov->kiov_page)) +
@@ -443,7 +443,7 @@ EXPORT_SYMBOL(lnet_copy_kiov2iov);
443void 443void
444lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov, 444lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
445 unsigned int kiovoffset, unsigned int niov, 445 unsigned int kiovoffset, unsigned int niov,
446 struct iovec *iov, unsigned int iovoffset, 446 struct kvec *iov, unsigned int iovoffset,
447 unsigned int nob) 447 unsigned int nob)
448{ 448{
449 /* NB kiov, iov are READ-ONLY */ 449 /* NB kiov, iov are READ-ONLY */
@@ -474,9 +474,9 @@ lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
474 do { 474 do {
475 LASSERT(nkiov > 0); 475 LASSERT(nkiov > 0);
476 LASSERT(niov > 0); 476 LASSERT(niov > 0);
477 this_nob = MIN(kiov->kiov_len - kiovoffset, 477 this_nob = min((__kernel_size_t) kiov->kiov_len - kiovoffset,
478 iov->iov_len - iovoffset); 478 iov->iov_len - iovoffset);
479 this_nob = MIN(this_nob, nob); 479 this_nob = min(this_nob, nob);
480 480
481 if (addr == NULL) 481 if (addr == NULL)
482 addr = ((char *)kmap(kiov->kiov_page)) + 482 addr = ((char *)kmap(kiov->kiov_page)) +
@@ -566,7 +566,7 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
566 unsigned int offset, unsigned int mlen, unsigned int rlen) 566 unsigned int offset, unsigned int mlen, unsigned int rlen)
567{ 567{
568 unsigned int niov = 0; 568 unsigned int niov = 0;
569 struct iovec *iov = NULL; 569 struct kvec *iov = NULL;
570 lnet_kiov_t *kiov = NULL; 570 lnet_kiov_t *kiov = NULL;
571 int rc; 571 int rc;
572 572
@@ -1530,7 +1530,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
1530 LASSERT(md->md_offset == 0); 1530 LASSERT(md->md_offset == 0);
1531 1531
1532 rlength = hdr->payload_length; 1532 rlength = hdr->payload_length;
1533 mlength = MIN(rlength, (int)md->md_length); 1533 mlength = min_t(int, rlength, md->md_length);
1534 1534
1535 if (mlength < rlength && 1535 if (mlength < rlength &&
1536 (md->md_options & LNET_MD_TRUNCATE) == 0) { 1536 (md->md_options & LNET_MD_TRUNCATE) == 0) {
@@ -1877,6 +1877,19 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
1877 goto drop; 1877 goto drop;
1878 } 1878 }
1879 1879
1880 if (lnet_isrouter(msg->msg_rxpeer)) {
1881 lnet_peer_set_alive(msg->msg_rxpeer);
1882 if (avoid_asym_router_failure &&
1883 LNET_NIDNET(src_nid) != LNET_NIDNET(from_nid)) {
1884 /* received a remote message from router, update
1885 * remote NI status on this router.
1886 * NB: multi-hop routed message will be ignored.
1887 */
1888 lnet_router_ni_update_locked(msg->msg_rxpeer,
1889 LNET_NIDNET(src_nid));
1890 }
1891 }
1892
1880 lnet_msg_commit(msg, cpt); 1893 lnet_msg_commit(msg, cpt);
1881 1894
1882 if (!for_me) { 1895 if (!for_me) {
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index 19ed696344fe..3ba0da919b41 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -262,10 +262,10 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg)
262{ 262{
263 struct lnet_match_table *mtable; 263 struct lnet_match_table *mtable;
264 struct lnet_portal *ptl; 264 struct lnet_portal *ptl;
265 int nmaps; 265 unsigned int nmaps;
266 int rotor; 266 unsigned int rotor;
267 int routed; 267 unsigned int cpt;
268 int cpt; 268 bool routed;
269 269
270 /* NB: called w/o lock */ 270 /* NB: called w/o lock */
271 LASSERT(info->mi_portal < the_lnet.ln_nportals); 271 LASSERT(info->mi_portal < the_lnet.ln_nportals);
diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c
index 17e1643fd675..f708c2e649d7 100644
--- a/drivers/staging/lustre/lnet/lnet/lo.c
+++ b/drivers/staging/lustre/lnet/lnet/lo.c
@@ -47,7 +47,7 @@ lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
47static int 47static int
48lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, 48lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
49 int delayed, unsigned int niov, 49 int delayed, unsigned int niov,
50 struct iovec *iov, lnet_kiov_t *kiov, 50 struct kvec *iov, lnet_kiov_t *kiov,
51 unsigned int offset, unsigned int mlen, unsigned int rlen) 51 unsigned int offset, unsigned int mlen, unsigned int rlen)
52{ 52{
53 lnet_msg_t *sendmsg = private; 53 lnet_msg_t *sendmsg = private;
diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c
index 3c23677bc280..72b7fbc83718 100644
--- a/drivers/staging/lustre/lnet/lnet/module.c
+++ b/drivers/staging/lustre/lnet/lnet/module.c
@@ -108,7 +108,7 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
108 } 108 }
109} 109}
110 110
111DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl); 111static DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
112 112
113static int __init 113static int __init
114init_lnet(void) 114init_lnet(void)
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index c667b5b76761..52ec0ab7e3c3 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(small_router_buffers, "# of small (1 page) messages to buffer i
46static int large_router_buffers; 46static int large_router_buffers;
47module_param(large_router_buffers, int, 0444); 47module_param(large_router_buffers, int, 0444);
48MODULE_PARM_DESC(large_router_buffers, "# of large messages to buffer in the router"); 48MODULE_PARM_DESC(large_router_buffers, "# of large messages to buffer in the router");
49static int peer_buffer_credits = 0; 49static int peer_buffer_credits;
50module_param(peer_buffer_credits, int, 0444); 50module_param(peer_buffer_credits, int, 0444);
51MODULE_PARM_DESC(peer_buffer_credits, "# router buffer credits per peer"); 51MODULE_PARM_DESC(peer_buffer_credits, "# router buffer credits per peer");
52 52
@@ -80,11 +80,11 @@ lnet_peer_buffer_credits(lnet_ni_t *ni)
80 80
81#endif 81#endif
82 82
83static int check_routers_before_use = 0; 83static int check_routers_before_use;
84module_param(check_routers_before_use, int, 0444); 84module_param(check_routers_before_use, int, 0444);
85MODULE_PARM_DESC(check_routers_before_use, "Assume routers are down and ping them before use"); 85MODULE_PARM_DESC(check_routers_before_use, "Assume routers are down and ping them before use");
86 86
87static int avoid_asym_router_failure = 1; 87int avoid_asym_router_failure = 1;
88module_param(avoid_asym_router_failure, int, 0644); 88module_param(avoid_asym_router_failure, int, 0644);
89MODULE_PARM_DESC(avoid_asym_router_failure, "Avoid asymmetrical router failures (0 to disable)"); 89MODULE_PARM_DESC(avoid_asym_router_failure, "Avoid asymmetrical router failures (0 to disable)");
90 90
@@ -245,7 +245,7 @@ lnet_find_net_locked (__u32 net)
245 245
246static void lnet_shuffle_seed(void) 246static void lnet_shuffle_seed(void)
247{ 247{
248 static int seeded = 0; 248 static int seeded;
249 int lnd_type, seed[2]; 249 int lnd_type, seed[2];
250 struct timeval tv; 250 struct timeval tv;
251 lnet_ni_t *ni; 251 lnet_ni_t *ni;
@@ -783,6 +783,21 @@ lnet_wait_known_routerstate(void)
783 } 783 }
784} 784}
785 785
786void
787lnet_router_ni_update_locked(lnet_peer_t *gw, __u32 net)
788{
789 lnet_route_t *rte;
790
791 if ((gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS) != 0) {
792 list_for_each_entry(rte, &gw->lp_routes, lr_gwlist) {
793 if (rte->lr_net == net) {
794 rte->lr_downis = 0;
795 break;
796 }
797 }
798 }
799}
800
786static void 801static void
787lnet_update_ni_status_locked(void) 802lnet_update_ni_status_locked(void)
788{ 803{
@@ -793,7 +808,7 @@ lnet_update_ni_status_locked(void)
793 LASSERT(the_lnet.ln_routing); 808 LASSERT(the_lnet.ln_routing);
794 809
795 timeout = router_ping_timeout + 810 timeout = router_ping_timeout +
796 MAX(live_router_check_interval, dead_router_check_interval); 811 max(live_router_check_interval, dead_router_check_interval);
797 812
798 now = get_seconds(); 813 now = get_seconds();
799 list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { 814 list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
@@ -1578,8 +1593,8 @@ lnet_notify (lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when)
1578void 1593void
1579lnet_router_checker (void) 1594lnet_router_checker (void)
1580{ 1595{
1581 static time_t last = 0; 1596 static time_t last;
1582 static int running = 0; 1597 static int running;
1583 1598
1584 time_t now = get_seconds(); 1599 time_t now = get_seconds();
1585 int interval = now - last; 1600 int interval = now - last;
@@ -1593,7 +1608,7 @@ lnet_router_checker (void)
1593 return; 1608 return;
1594 1609
1595 if (last != 0 && 1610 if (last != 0 &&
1596 interval > MAX(live_router_check_interval, 1611 interval > max(live_router_check_interval,
1597 dead_router_check_interval)) 1612 dead_router_check_interval))
1598 CNETERR("Checker(%d/%d) not called for %d seconds\n", 1613 CNETERR("Checker(%d/%d) not called for %d seconds\n",
1599 live_router_check_interval, dead_router_check_interval, 1614 live_router_check_interval, dead_router_check_interval,
@@ -1664,13 +1679,16 @@ lnet_get_tunables (void)
1664 char *s; 1679 char *s;
1665 1680
1666 s = getenv("LNET_ROUTER_PING_TIMEOUT"); 1681 s = getenv("LNET_ROUTER_PING_TIMEOUT");
1667 if (s != NULL) router_ping_timeout = atoi(s); 1682 if (s != NULL)
1683 router_ping_timeout = atoi(s);
1668 1684
1669 s = getenv("LNET_LIVE_ROUTER_CHECK_INTERVAL"); 1685 s = getenv("LNET_LIVE_ROUTER_CHECK_INTERVAL");
1670 if (s != NULL) live_router_check_interval = atoi(s); 1686 if (s != NULL)
1687 live_router_check_interval = atoi(s);
1671 1688
1672 s = getenv("LNET_DEAD_ROUTER_CHECK_INTERVAL"); 1689 s = getenv("LNET_DEAD_ROUTER_CHECK_INTERVAL");
1673 if (s != NULL) dead_router_check_interval = atoi(s); 1690 if (s != NULL)
1691 dead_router_check_interval = atoi(s);
1674 1692
1675 /* This replaces old lnd_notify mechanism */ 1693 /* This replaces old lnd_notify mechanism */
1676 check_routers_before_use = 1; 1694 check_routers_before_use = 1;
diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c
index 46cde7036f1d..c055afc86eb4 100644
--- a/drivers/staging/lustre/lnet/lnet/router_proc.c
+++ b/drivers/staging/lustre/lnet/lnet/router_proc.c
@@ -49,7 +49,7 @@ enum {
49 */ 49 */
50#define LNET_PROC_CPT_BITS (LNET_CPT_BITS + 1) 50#define LNET_PROC_CPT_BITS (LNET_CPT_BITS + 1)
51/* change version, 16 bits or 8 bits */ 51/* change version, 16 bits or 8 bits */
52#define LNET_PROC_VER_BITS MAX(((MIN(LNET_LOFFT_BITS, 64)) / 4), 8) 52#define LNET_PROC_VER_BITS max_t(size_t, min_t(size_t, LNET_LOFFT_BITS, 64) / 4, 8)
53 53
54#define LNET_PROC_HASH_BITS LNET_PEER_HASH_BITS 54#define LNET_PROC_HASH_BITS LNET_PEER_HASH_BITS
55/* 55/*
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c
index 5bc615309e72..fbff84cea52f 100644
--- a/drivers/staging/lustre/lnet/selftest/conctl.c
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c
@@ -721,7 +721,7 @@ lst_stat_query_ioctl(lstio_stat_args_t *args)
721 return rc; 721 return rc;
722} 722}
723 723
724int lst_test_add_ioctl(lstio_test_args_t *args) 724static int lst_test_add_ioctl(lstio_test_args_t *args)
725{ 725{
726 char *batch_name; 726 char *batch_name;
727 char *src_name = NULL; 727 char *src_name = NULL;
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 9999b0dc03e4..77f02b76128e 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -703,7 +703,7 @@ lstcon_statrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
703 return 0; 703 return 0;
704} 704}
705 705
706lnet_process_id_packed_t * 706static lnet_process_id_packed_t *
707lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov) 707lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
708{ 708{
709 lnet_process_id_packed_t *pid; 709 lnet_process_id_packed_t *pid;
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h
index fc1cb56cbab2..2353889c6eac 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.h
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.h
@@ -54,7 +54,7 @@
54#define LST_TRANS_TIMEOUT 30 54#define LST_TRANS_TIMEOUT 30
55#define LST_TRANS_MIN_TIMEOUT 3 55#define LST_TRANS_MIN_TIMEOUT 3
56 56
57#define LST_VALIDATE_TIMEOUT(t) MIN(MAX(t, LST_TRANS_MIN_TIMEOUT), LST_TRANS_TIMEOUT) 57#define LST_VALIDATE_TIMEOUT(t) min(max(t, LST_TRANS_MIN_TIMEOUT), LST_TRANS_TIMEOUT)
58 58
59#define LST_PING_INTERVAL 8 59#define LST_PING_INTERVAL 8
60 60
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 49cb6543d538..1e0afc286847 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -46,17 +46,17 @@
46#include "console.h" 46#include "console.h"
47#include "conrpc.h" 47#include "conrpc.h"
48 48
49#define LST_NODE_STATE_COUNTER(nd, p) \ 49#define LST_NODE_STATE_COUNTER(nd, p) \
50do { \ 50do { \
51 if ((nd)->nd_state == LST_NODE_ACTIVE) \ 51 if ((nd)->nd_state == LST_NODE_ACTIVE) \
52 (p)->nle_nactive ++; \ 52 (p)->nle_nactive++; \
53 else if ((nd)->nd_state == LST_NODE_BUSY) \ 53 else if ((nd)->nd_state == LST_NODE_BUSY) \
54 (p)->nle_nbusy ++; \ 54 (p)->nle_nbusy++; \
55 else if ((nd)->nd_state == LST_NODE_DOWN) \ 55 else if ((nd)->nd_state == LST_NODE_DOWN) \
56 (p)->nle_ndown ++; \ 56 (p)->nle_ndown++; \
57 else \ 57 else \
58 (p)->nle_nunknown ++; \ 58 (p)->nle_nunknown++; \
59 (p)->nle_nnode ++; \ 59 (p)->nle_nnode++; \
60} while (0) 60} while (0)
61 61
62lstcon_session_t console_session; 62lstcon_session_t console_session;
@@ -223,7 +223,7 @@ lstcon_group_alloc(char *name, lstcon_group_t **grpp)
223static void 223static void
224lstcon_group_addref(lstcon_group_t *grp) 224lstcon_group_addref(lstcon_group_t *grp)
225{ 225{
226 grp->grp_ref ++; 226 grp->grp_ref++;
227} 227}
228 228
229static void lstcon_group_ndlink_release(lstcon_group_t *, lstcon_ndlink_t *); 229static void lstcon_group_ndlink_release(lstcon_group_t *, lstcon_ndlink_t *);
@@ -298,7 +298,7 @@ lstcon_group_ndlink_find(lstcon_group_t *grp, lnet_process_id_t id,
298 return 0; 298 return 0;
299 299
300 list_add_tail(&(*ndlpp)->ndl_link, &grp->grp_ndl_list); 300 list_add_tail(&(*ndlpp)->ndl_link, &grp->grp_ndl_list);
301 grp->grp_nnode ++; 301 grp->grp_nnode++;
302 302
303 return 0; 303 return 0;
304} 304}
@@ -324,7 +324,7 @@ lstcon_group_ndlink_move(lstcon_group_t *old,
324 324
325 list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]); 325 list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]);
326 list_add_tail(&ndl->ndl_link, &new->grp_ndl_list); 326 list_add_tail(&ndl->ndl_link, &new->grp_ndl_list);
327 new->grp_nnode ++; 327 new->grp_nnode++;
328 328
329 return; 329 return;
330} 330}
@@ -767,7 +767,7 @@ lstcon_nodes_getent(struct list_head *head, int *index_p,
767 &nd->nd_state, sizeof(nd->nd_state))) 767 &nd->nd_state, sizeof(nd->nd_state)))
768 return -EFAULT; 768 return -EFAULT;
769 769
770 count ++; 770 count++;
771 } 771 }
772 772
773 if (index <= *index_p) 773 if (index <= *index_p)
@@ -1343,7 +1343,7 @@ lstcon_test_add(char *batch_name, int type, int loop,
1343 /* add to test list anyway, so user can check what's going on */ 1343 /* add to test list anyway, so user can check what's going on */
1344 list_add_tail(&test->tes_link, &batch->bat_test_list); 1344 list_add_tail(&test->tes_link, &batch->bat_test_list);
1345 1345
1346 batch->bat_ntest ++; 1346 batch->bat_ntest++;
1347 test->tes_hdr.tsb_index = batch->bat_ntest; 1347 test->tes_hdr.tsb_index = batch->bat_ntest;
1348 1348
1349 /* hold groups so nobody can change them */ 1349 /* hold groups so nobody can change them */
@@ -1986,7 +1986,7 @@ static void lstcon_init_acceptor_service(void)
1986 1986
1987extern int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data); 1987extern int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data);
1988 1988
1989DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry); 1989static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
1990 1990
1991/* initialize console */ 1991/* initialize console */
1992int 1992int
diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
index cc9d1826ae66..570914828b8c 100644
--- a/drivers/staging/lustre/lnet/selftest/framework.c
+++ b/drivers/staging/lustre/lnet/selftest/framework.c
@@ -103,7 +103,7 @@ do { \
103#define sfw_test_active(t) (atomic_read(&(t)->tsi_nactive) != 0) 103#define sfw_test_active(t) (atomic_read(&(t)->tsi_nactive) != 0)
104#define sfw_batch_active(b) (atomic_read(&(b)->bat_nactive) != 0) 104#define sfw_batch_active(b) (atomic_read(&(b)->bat_nactive) != 0)
105 105
106struct smoketest_framework { 106static struct smoketest_framework {
107 struct list_head fw_zombie_rpcs; /* RPCs to be recycled */ 107 struct list_head fw_zombie_rpcs; /* RPCs to be recycled */
108 struct list_head fw_zombie_sessions; /* stopping sessions */ 108 struct list_head fw_zombie_sessions; /* stopping sessions */
109 struct list_head fw_tests; /* registered test cases */ 109 struct list_head fw_tests; /* registered test cases */
@@ -194,9 +194,9 @@ sfw_del_session_timer (void)
194 return EBUSY; /* racing with sfw_session_expired() */ 194 return EBUSY; /* racing with sfw_session_expired() */
195} 195}
196 196
197/* called with sfw_data.fw_lock held */
198static void 197static void
199sfw_deactivate_session (void) 198sfw_deactivate_session (void)
199 __must_hold(&sfw_data.fw_lock)
200{ 200{
201 sfw_session_t *sn = sfw_data.fw_session; 201 sfw_session_t *sn = sfw_data.fw_session;
202 int nactive = 0; 202 int nactive = 0;
diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c
index c6ef5b0d8de1..faf409802372 100644
--- a/drivers/staging/lustre/lnet/selftest/module.c
+++ b/drivers/staging/lustre/lnet/selftest/module.c
@@ -61,31 +61,31 @@ lnet_selftest_fini(void)
61 int i; 61 int i;
62 62
63 switch (lst_init_step) { 63 switch (lst_init_step) {
64 case LST_INIT_CONSOLE: 64 case LST_INIT_CONSOLE:
65 lstcon_console_fini(); 65 lstcon_console_fini();
66 case LST_INIT_FW: 66 case LST_INIT_FW:
67 sfw_shutdown(); 67 sfw_shutdown();
68 case LST_INIT_RPC: 68 case LST_INIT_RPC:
69 srpc_shutdown(); 69 srpc_shutdown();
70 case LST_INIT_WI_TEST: 70 case LST_INIT_WI_TEST:
71 for (i = 0; 71 for (i = 0;
72 i < cfs_cpt_number(lnet_cpt_table()); i++) { 72 i < cfs_cpt_number(lnet_cpt_table()); i++) {
73 if (lst_sched_test[i] == NULL) 73 if (lst_sched_test[i] == NULL)
74 continue; 74 continue;
75 cfs_wi_sched_destroy(lst_sched_test[i]); 75 cfs_wi_sched_destroy(lst_sched_test[i]);
76 } 76 }
77 LIBCFS_FREE(lst_sched_test, 77 LIBCFS_FREE(lst_sched_test,
78 sizeof(lst_sched_test[0]) * 78 sizeof(lst_sched_test[0]) *
79 cfs_cpt_number(lnet_cpt_table())); 79 cfs_cpt_number(lnet_cpt_table()));
80 lst_sched_test = NULL; 80 lst_sched_test = NULL;
81 81
82 case LST_INIT_WI_SERIAL: 82 case LST_INIT_WI_SERIAL:
83 cfs_wi_sched_destroy(lst_sched_serial); 83 cfs_wi_sched_destroy(lst_sched_serial);
84 lst_sched_serial = NULL; 84 lst_sched_serial = NULL;
85 case LST_INIT_NONE: 85 case LST_INIT_NONE:
86 break; 86 break;
87 default: 87 default:
88 LBUG(); 88 LBUG();
89 } 89 }
90 return; 90 return;
91} 91}
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index f753add7bfb3..1f7d9a6248db 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -54,7 +54,7 @@ typedef enum {
54 SRPC_STATE_STOPPING, 54 SRPC_STATE_STOPPING,
55} srpc_state_t; 55} srpc_state_t;
56 56
57struct smoketest_rpc { 57static struct smoketest_rpc {
58 spinlock_t rpc_glock; /* global lock */ 58 spinlock_t rpc_glock; /* global lock */
59 srpc_service_t *rpc_services[SRPC_SERVICE_MAX_ID + 1]; 59 srpc_service_t *rpc_services[SRPC_SERVICE_MAX_ID + 1];
60 lnet_handle_eq_t rpc_lnet_eq; /* _the_ LNet event queue */ 60 lnet_handle_eq_t rpc_lnet_eq; /* _the_ LNet event queue */
@@ -468,6 +468,7 @@ srpc_post_passive_rqtbuf(int service, int local, void *buf, int len,
468 468
469static int 469static int
470srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf) 470srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf)
471 __must_hold(&scd->scd_lock)
471{ 472{
472 struct srpc_service *sv = scd->scd_svc; 473 struct srpc_service *sv = scd->scd_svc;
473 struct srpc_msg *msg = &buf->buf_msg; 474 struct srpc_msg *msg = &buf->buf_msg;
@@ -559,7 +560,7 @@ srpc_add_buffer(struct swi_workitem *wi)
559 LASSERT(scd->scd_buf_posting > 0); 560 LASSERT(scd->scd_buf_posting > 0);
560 scd->scd_buf_posting--; 561 scd->scd_buf_posting--;
561 scd->scd_buf_total++; 562 scd->scd_buf_total++;
562 scd->scd_buf_low = MAX(2, scd->scd_buf_total / 4); 563 scd->scd_buf_low = max(2, scd->scd_buf_total / 4);
563 } 564 }
564 565
565 if (rc != 0) { 566 if (rc != 0) {
@@ -697,6 +698,7 @@ srpc_finish_service(struct srpc_service *sv)
697/* called with sv->sv_lock held */ 698/* called with sv->sv_lock held */
698static void 699static void
699srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf) 700srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf)
701 __must_hold(&scd->scd_lock)
700{ 702{
701 if (!scd->scd_svc->sv_shuttingdown && scd->scd_buf_adjust >= 0) { 703 if (!scd->scd_svc->sv_shuttingdown && scd->scd_buf_adjust >= 0) {
702 if (srpc_service_post_buffer(scd, buf) != 0) { 704 if (srpc_service_post_buffer(scd, buf) != 0) {
@@ -1486,7 +1488,7 @@ srpc_lnet_ev_handler(lnet_event_t *ev)
1486 if (scd->scd_buf_err == 0 && /* adding buffer is enabled */ 1488 if (scd->scd_buf_err == 0 && /* adding buffer is enabled */
1487 scd->scd_buf_adjust == 0 && 1489 scd->scd_buf_adjust == 0 &&
1488 scd->scd_buf_nposted < scd->scd_buf_low) { 1490 scd->scd_buf_nposted < scd->scd_buf_low) {
1489 scd->scd_buf_adjust = MAX(scd->scd_buf_total / 2, 1491 scd->scd_buf_adjust = max(scd->scd_buf_total / 2,
1490 SFW_TEST_WI_MIN); 1492 SFW_TEST_WI_MIN);
1491 swi_schedule_workitem(&scd->scd_buf_wi); 1493 swi_schedule_workitem(&scd->scd_buf_wi);
1492 } 1494 }
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index 9b5c5df6eb2c..d48701834b18 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -609,4 +609,16 @@ srpc_wait_service_shutdown(srpc_service_t *sv)
609 } 609 }
610} 610}
611 611
612extern sfw_test_client_ops_t brw_test_client;
613void brw_init_test_client(void);
614
615extern srpc_service_t brw_test_service;
616void brw_init_test_service(void);
617
618extern sfw_test_client_ops_t ping_test_client;
619void ping_init_test_client(void);
620
621extern srpc_service_t ping_test_service;
622void ping_init_test_service(void);
623
612#endif /* __SELFTEST_SELFTEST_H__ */ 624#endif /* __SELFTEST_SELFTEST_H__ */
diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
index f8352c2a7d37..441f9472a834 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.c
+++ b/drivers/staging/lustre/lnet/selftest/timer.c
@@ -57,7 +57,7 @@
57#define STTIMER_SLOT(t) (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \ 57#define STTIMER_SLOT(t) (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
58 (STTIMER_NSLOTS - 1))]) 58 (STTIMER_NSLOTS - 1))])
59 59
60struct st_timer_data { 60static struct st_timer_data {
61 spinlock_t stt_lock; 61 spinlock_t stt_lock;
62 /* start time of the slot processed previously */ 62 /* start time of the slot processed previously */
63 unsigned long stt_prev_slot; 63 unsigned long stt_prev_slot;
diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h
index eb607c52ef3b..b5e8da8956f2 100644
--- a/drivers/staging/lustre/lustre/fid/fid_internal.h
+++ b/drivers/staging/lustre/lustre/fid/fid_internal.h
@@ -47,7 +47,7 @@
47int seq_client_alloc_super(struct lu_client_seq *seq, 47int seq_client_alloc_super(struct lu_client_seq *seq,
48 const struct lu_env *env); 48 const struct lu_env *env);
49 49
50#if defined (CONFIG_PROC_FS) 50#if defined(CONFIG_PROC_FS)
51extern struct lprocfs_vars seq_client_proc_list[]; 51extern struct lprocfs_vars seq_client_proc_list[];
52#endif 52#endif
53 53
diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c
index 64b1d80c64b0..063441abfcfc 100644
--- a/drivers/staging/lustre/lustre/fid/fid_request.c
+++ b/drivers/staging/lustre/lustre/fid/fid_request.c
@@ -402,7 +402,7 @@ EXPORT_SYMBOL(seq_client_flush);
402 402
403static void seq_client_proc_fini(struct lu_client_seq *seq) 403static void seq_client_proc_fini(struct lu_client_seq *seq)
404{ 404{
405#if defined (CONFIG_PROC_FS) 405#if defined(CONFIG_PROC_FS)
406 if (seq->lcs_proc_dir) { 406 if (seq->lcs_proc_dir) {
407 if (!IS_ERR(seq->lcs_proc_dir)) 407 if (!IS_ERR(seq->lcs_proc_dir))
408 lprocfs_remove(&seq->lcs_proc_dir); 408 lprocfs_remove(&seq->lcs_proc_dir);
@@ -413,7 +413,7 @@ static void seq_client_proc_fini(struct lu_client_seq *seq)
413 413
414static int seq_client_proc_init(struct lu_client_seq *seq) 414static int seq_client_proc_init(struct lu_client_seq *seq)
415{ 415{
416#if defined (CONFIG_PROC_FS) 416#if defined(CONFIG_PROC_FS)
417 int rc; 417 int rc;
418 418
419 seq->lcs_proc_dir = lprocfs_register(seq->lcs_name, 419 seq->lcs_proc_dir = lprocfs_register(seq->lcs_name,
diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c
index 5d95d0b358b8..0d0a73745065 100644
--- a/drivers/staging/lustre/lustre/fld/fld_cache.c
+++ b/drivers/staging/lustre/lustre/fld/fld_cache.c
@@ -257,9 +257,9 @@ void fld_cache_flush(struct fld_cache *cache)
257 * entry accordingly. 257 * entry accordingly.
258 */ 258 */
259 259
260void fld_cache_punch_hole(struct fld_cache *cache, 260static void fld_cache_punch_hole(struct fld_cache *cache,
261 struct fld_cache_entry *f_curr, 261 struct fld_cache_entry *f_curr,
262 struct fld_cache_entry *f_new) 262 struct fld_cache_entry *f_new)
263{ 263{
264 const struct lu_seq_range *range = &f_new->fce_range; 264 const struct lu_seq_range *range = &f_new->fce_range;
265 const u64 new_start = range->lsr_start; 265 const u64 new_start = range->lsr_start;
diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h
index 8806b6096953..6125bbe822b5 100644
--- a/drivers/staging/lustre/lustre/fld/fld_internal.h
+++ b/drivers/staging/lustre/lustre/fld/fld_internal.h
@@ -111,7 +111,7 @@ struct fld_cache {
111 111
112 /** 112 /**
113 * Cache name used for debug and messages. */ 113 * Cache name used for debug and messages. */
114 char fci_name[80]; 114 char fci_name[LUSTRE_MDT_MAXNAMELEN];
115 unsigned int fci_no_shrink:1; 115 unsigned int fci_no_shrink:1;
116}; 116};
117 117
diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c
index 0d361ff43212..b8d17e109a96 100644
--- a/drivers/staging/lustre/lustre/fld/fld_request.c
+++ b/drivers/staging/lustre/lustre/fld/fld_request.c
@@ -131,11 +131,20 @@ fld_rrb_scan(struct lu_client_fld *fld, u64 seq)
131 else 131 else
132 hash = 0; 132 hash = 0;
133 133
134again:
134 list_for_each_entry(target, &fld->lcf_targets, ft_chain) { 135 list_for_each_entry(target, &fld->lcf_targets, ft_chain) {
135 if (target->ft_idx == hash) 136 if (target->ft_idx == hash)
136 return target; 137 return target;
137 } 138 }
138 139
140 if (hash != 0) {
141 /* It is possible the remote target(MDT) are not connected to
142 * with client yet, so we will refer this to MDT0, which should
143 * be connected during mount */
144 hash = 0;
145 goto again;
146 }
147
139 CERROR("%s: Can't find target by hash %d (seq %#llx). Targets (%d):\n", 148 CERROR("%s: Can't find target by hash %d (seq %#llx). Targets (%d):\n",
140 fld->lcf_name, hash, seq, fld->lcf_count); 149 fld->lcf_name, hash, seq, fld->lcf_count);
141 150
@@ -269,7 +278,7 @@ int fld_client_del_target(struct lu_client_fld *fld, __u64 idx)
269} 278}
270EXPORT_SYMBOL(fld_client_del_target); 279EXPORT_SYMBOL(fld_client_del_target);
271 280
272struct proc_dir_entry *fld_type_proc_dir = NULL; 281static struct proc_dir_entry *fld_type_proc_dir;
273 282
274#if defined (CONFIG_PROC_FS) 283#if defined (CONFIG_PROC_FS)
275static int fld_client_proc_init(struct lu_client_fld *fld) 284static int fld_client_proc_init(struct lu_client_fld *fld)
diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c
index 95e7de18d2f1..8c5a65704a37 100644
--- a/drivers/staging/lustre/lustre/fld/lproc_fld.c
+++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c
@@ -87,13 +87,21 @@ fld_proc_hash_seq_show(struct seq_file *m, void *unused)
87} 87}
88 88
89static ssize_t 89static ssize_t
90fld_proc_hash_seq_write(struct file *file, const char *buffer, 90fld_proc_hash_seq_write(struct file *file,
91 size_t count, loff_t *off) 91 const char __user *buffer,
92 size_t count, loff_t *off)
92{ 93{
93 struct lu_client_fld *fld; 94 struct lu_client_fld *fld;
94 struct lu_fld_hash *hash = NULL; 95 struct lu_fld_hash *hash = NULL;
96 char fh_name[8];
95 int i; 97 int i;
96 98
99 if (count > sizeof(fh_name))
100 return -ENAMETOOLONG;
101
102 if (copy_from_user(fh_name, buffer, count) != 0)
103 return -EFAULT;
104
97 fld = ((struct seq_file *)file->private_data)->private; 105 fld = ((struct seq_file *)file->private_data)->private;
98 LASSERT(fld != NULL); 106 LASSERT(fld != NULL);
99 107
@@ -101,7 +109,7 @@ fld_proc_hash_seq_write(struct file *file, const char *buffer,
101 if (count != strlen(fld_hash[i].fh_name)) 109 if (count != strlen(fld_hash[i].fh_name))
102 continue; 110 continue;
103 111
104 if (!strncmp(fld_hash[i].fh_name, buffer, count)) { 112 if (!strncmp(fld_hash[i].fh_name, fh_name, count)) {
105 hash = &fld_hash[i]; 113 hash = &fld_hash[i];
106 break; 114 break;
107 } 115 }
@@ -146,7 +154,7 @@ static int fld_proc_cache_flush_release(struct inode *inode, struct file *file)
146 return 0; 154 return 0;
147} 155}
148 156
149struct file_operations fld_proc_cache_flush_fops = { 157static struct file_operations fld_proc_cache_flush_fops = {
150 .owner = THIS_MODULE, 158 .owner = THIS_MODULE,
151 .open = fld_proc_cache_flush_open, 159 .open = fld_proc_cache_flush_open,
152 .write = fld_proc_cache_flush_write, 160 .write = fld_proc_cache_flush_write,
diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h
index b3b841f4d6e6..c5c3a8d9eaa4 100644
--- a/drivers/staging/lustre/lustre/include/lclient.h
+++ b/drivers/staging/lustre/lustre/include/lclient.h
@@ -135,6 +135,7 @@ static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env)
135static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env) 135static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env)
136{ 136{
137 struct cl_attr *attr = &ccc_env_info(env)->cti_attr; 137 struct cl_attr *attr = &ccc_env_info(env)->cti_attr;
138
138 memset(attr, 0, sizeof(*attr)); 139 memset(attr, 0, sizeof(*attr));
139 return attr; 140 return attr;
140} 141}
@@ -142,6 +143,7 @@ static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env)
142static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env) 143static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env)
143{ 144{
144 struct cl_io *io = &ccc_env_info(env)->cti_io; 145 struct cl_io *io = &ccc_env_info(env)->cti_io;
146
145 memset(io, 0, sizeof(*io)); 147 memset(io, 0, sizeof(*io));
146 return io; 148 return io;
147} 149}
@@ -323,6 +325,7 @@ void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice);
323int ccc_lock_enqueue(const struct lu_env *env, 325int ccc_lock_enqueue(const struct lu_env *env,
324 const struct cl_lock_slice *slice, 326 const struct cl_lock_slice *slice,
325 struct cl_io *io, __u32 enqflags); 327 struct cl_io *io, __u32 enqflags);
328int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice);
326int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice); 329int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice);
327int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice); 330int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice);
328int ccc_lock_fits_into(const struct lu_env *env, 331int ccc_lock_fits_into(const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index cfe503b7df62..8a25cf6f6825 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -627,16 +627,16 @@ struct adaptive_timeout;
627extern int lprocfs_at_hist_helper(struct seq_file *m, 627extern int lprocfs_at_hist_helper(struct seq_file *m,
628 struct adaptive_timeout *at); 628 struct adaptive_timeout *at);
629extern int lprocfs_rd_timeouts(struct seq_file *m, void *data); 629extern int lprocfs_rd_timeouts(struct seq_file *m, void *data);
630extern int lprocfs_wr_timeouts(struct file *file, const char *buffer, 630extern int lprocfs_wr_timeouts(struct file *file, const char __user *buffer,
631 unsigned long count, void *data); 631 unsigned long count, void *data);
632extern int lprocfs_wr_evict_client(struct file *file, const char *buffer, 632extern int lprocfs_wr_evict_client(struct file *file, const char __user *buffer,
633 size_t count, loff_t *off); 633 size_t count, loff_t *off);
634extern int lprocfs_wr_ping(struct file *file, const char *buffer, 634extern int lprocfs_wr_ping(struct file *file, const char __user *buffer,
635 size_t count, loff_t *off); 635 size_t count, loff_t *off);
636extern int lprocfs_wr_import(struct file *file, const char *buffer, 636extern int lprocfs_wr_import(struct file *file, const char __user *buffer,
637 size_t count, loff_t *off); 637 size_t count, loff_t *off);
638extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n); 638extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n);
639extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer, 639extern int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
640 size_t count, loff_t *off); 640 size_t count, loff_t *off);
641 641
642/* Statfs helpers */ 642/* Statfs helpers */
@@ -650,8 +650,8 @@ extern int lprocfs_rd_filesfree(struct seq_file *m, void *data);
650extern int lprocfs_write_helper(const char __user *buffer, unsigned long count, 650extern int lprocfs_write_helper(const char __user *buffer, unsigned long count,
651 int *val); 651 int *val);
652extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult); 652extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
653extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count, 653extern int lprocfs_write_u64_helper(const char __user *buffer,
654 __u64 *val); 654 unsigned long count, __u64 *val);
655extern int lprocfs_write_frac_u64_helper(const char *buffer, 655extern int lprocfs_write_frac_u64_helper(const char *buffer,
656 unsigned long count, 656 unsigned long count,
657 __u64 *val, int mult); 657 __u64 *val, int mult);
@@ -716,7 +716,8 @@ static struct file_operations name##_fops = { \
716 return lprocfs_rd_##type(m, m->private); \ 716 return lprocfs_rd_##type(m, m->private); \
717 } \ 717 } \
718 static ssize_t name##_##type##_seq_write(struct file *file, \ 718 static ssize_t name##_##type##_seq_write(struct file *file, \
719 const char *buffer, size_t count, loff_t *off) \ 719 const char __user *buffer, size_t count, \
720 loff_t *off) \
720 { \ 721 { \
721 struct seq_file *seq = file->private_data; \ 722 struct seq_file *seq = file->private_data; \
722 return lprocfs_wr_##type(file, buffer, \ 723 return lprocfs_wr_##type(file, buffer, \
@@ -726,7 +727,8 @@ static struct file_operations name##_fops = { \
726 727
727#define LPROC_SEQ_FOPS_WR_ONLY(name, type) \ 728#define LPROC_SEQ_FOPS_WR_ONLY(name, type) \
728 static ssize_t name##_##type##_write(struct file *file, \ 729 static ssize_t name##_##type##_write(struct file *file, \
729 const char *buffer, size_t count, loff_t *off) \ 730 const char __user *buffer, size_t count, \
731 loff_t *off) \
730 { \ 732 { \
731 return lprocfs_wr_##type(file, buffer, count, off); \ 733 return lprocfs_wr_##type(file, buffer, count, off); \
732 } \ 734 } \
@@ -939,20 +941,24 @@ static inline int lprocfs_at_hist_helper(struct seq_file *m,
939static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data) 941static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data)
940{ return 0; } 942{ return 0; }
941static inline int lprocfs_wr_timeouts(struct file *file, 943static inline int lprocfs_wr_timeouts(struct file *file,
942 const char *buffer, 944 const char __user *buffer,
943 unsigned long count, void *data) 945 unsigned long count, void *data)
944{ return 0; } 946{ return 0; }
945static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer, 947static inline int lprocfs_wr_evict_client(struct file *file,
946 size_t count, loff_t *off) 948 const char __user *buffer,
949 size_t count, loff_t *off)
947{ return 0; } 950{ return 0; }
948static inline int lprocfs_wr_ping(struct file *file, const char *buffer, 951static inline int lprocfs_wr_ping(struct file *file,
949 size_t count, loff_t *off) 952 const char __user *buffer,
953 size_t count, loff_t *off)
950{ return 0; } 954{ return 0; }
951static inline int lprocfs_wr_import(struct file *file, const char *buffer, 955static inline int lprocfs_wr_import(struct file *file,
952 size_t count, loff_t *off) 956 const char __user *buffer,
957 size_t count, loff_t *off)
953{ return 0; } 958{ return 0; }
954static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer, 959static inline int lprocfs_wr_pinger_recov(struct file *file,
955 size_t count, loff_t *off) 960 const char __user *buffer,
961 size_t count, loff_t *off)
956{ return 0; } 962{ return 0; }
957 963
958/* Statfs helpers */ 964/* Statfs helpers */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index 7b7457cf70e3..305ecbee9b78 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -105,6 +105,11 @@
105 * FOO_BULK_PORTAL is for incoming bulk on the FOO 105 * FOO_BULK_PORTAL is for incoming bulk on the FOO
106 */ 106 */
107 107
108/* Lustre service names are following the format
109 * service name + MDT + seq name
110 */
111#define LUSTRE_MDT_MAXNAMELEN 80
112
108#define CONNMGR_REQUEST_PORTAL 1 113#define CONNMGR_REQUEST_PORTAL 1
109#define CONNMGR_REPLY_PORTAL 2 114#define CONNMGR_REPLY_PORTAL 2
110//#define OSC_REQUEST_PORTAL 3 115//#define OSC_REQUEST_PORTAL 3
diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h
index 2d6fbb4b1b39..0a0929fd9023 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fid.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fid.h
@@ -358,7 +358,7 @@ struct lu_client_seq {
358 * Service uuid, passed from MDT + seq name to form unique seq name to 358 * Service uuid, passed from MDT + seq name to form unique seq name to
359 * use it with procfs. 359 * use it with procfs.
360 */ 360 */
361 char lcs_name[80]; 361 char lcs_name[LUSTRE_MDT_MAXNAMELEN];
362 362
363 /* 363 /*
364 * Sequence width, that is how many objects may be allocated in one 364 * Sequence width, that is how many objects may be allocated in one
@@ -408,7 +408,7 @@ struct lu_server_seq {
408 * Service uuid, passed from MDT + seq name to form unique seq name to 408 * Service uuid, passed from MDT + seq name to form unique seq name to
409 * use it with procfs. 409 * use it with procfs.
410 */ 410 */
411 char lss_name[80]; 411 char lss_name[LUSTRE_MDT_MAXNAMELEN];
412 412
413 /* 413 /*
414 * Allocation chunks for super and meta sequences. Default values are 414 * Allocation chunks for super and meta sequences. Default values are
diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h
index 64c504849a22..5ee4b1ed0995 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fld.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fld.h
@@ -93,7 +93,7 @@ struct lu_server_fld {
93 93
94 /** 94 /**
95 * Fld service name in form "fld-srv-lustre-MDTXXX" */ 95 * Fld service name in form "fld-srv-lustre-MDTXXX" */
96 char lsf_name[80]; 96 char lsf_name[LUSTRE_MDT_MAXNAMELEN];
97 97
98}; 98};
99 99
@@ -124,7 +124,7 @@ struct lu_client_fld {
124 124
125 /** 125 /**
126 * Client fld proc entry name. */ 126 * Client fld proc entry name. */
127 char lcf_name[80]; 127 char lcf_name[LUSTRE_MDT_MAXNAMELEN];
128 128
129 int lcf_flags; 129 int lcf_flags;
130}; 130};
diff --git a/drivers/staging/lustre/lustre/include/lustre_update.h b/drivers/staging/lustre/lustre/include/lustre_update.h
deleted file mode 100644
index 84defce0f623..000000000000
--- a/drivers/staging/lustre/lustre/include/lustre_update.h
+++ /dev/null
@@ -1,189 +0,0 @@
1/*
2 * GPL HEADER START
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.htm
19 *
20 * GPL HEADER END
21 */
22/*
23 * Copyright (c) 2013, Intel Corporation.
24 */
25/*
26 * lustre/include/lustre_update.h
27 *
28 * Author: Di Wang <di.wang@intel.com>
29 */
30
31#ifndef _LUSTRE_UPDATE_H
32#define _LUSTRE_UPDATE_H
33
34#define UPDATE_BUFFER_SIZE 8192
35struct update_request {
36 struct dt_device *ur_dt;
37 struct list_head ur_list; /* attached itself to thandle */
38 int ur_flags;
39 int ur_rc; /* request result */
40 int ur_batchid; /* Current batch(trans) id */
41 struct update_buf *ur_buf; /* Holding the update req */
42};
43
44static inline unsigned long update_size(struct update *update)
45{
46 unsigned long size;
47 int i;
48
49 size = cfs_size_round(offsetof(struct update, u_bufs[0]));
50 for (i = 0; i < UPDATE_BUF_COUNT; i++)
51 size += cfs_size_round(update->u_lens[i]);
52
53 return size;
54}
55
56static inline void *update_param_buf(struct update *update, int index,
57 int *size)
58{
59 int i;
60 void *ptr;
61
62 if (index >= UPDATE_BUF_COUNT)
63 return NULL;
64
65 ptr = (char *)update + cfs_size_round(offsetof(struct update,
66 u_bufs[0]));
67 for (i = 0; i < index; i++) {
68 LASSERT(update->u_lens[i] > 0);
69 ptr += cfs_size_round(update->u_lens[i]);
70 }
71
72 if (size != NULL)
73 *size = update->u_lens[index];
74
75 return ptr;
76}
77
78static inline unsigned long update_buf_size(struct update_buf *buf)
79{
80 unsigned long size;
81 int i = 0;
82
83 size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
84 for (i = 0; i < buf->ub_count; i++) {
85 struct update *update;
86
87 update = (struct update *)((char *)buf + size);
88 size += update_size(update);
89 }
90 LASSERT(size <= UPDATE_BUFFER_SIZE);
91 return size;
92}
93
94static inline void *update_buf_get(struct update_buf *buf, int index, int *size)
95{
96 int count = buf->ub_count;
97 void *ptr;
98 int i = 0;
99
100 if (index >= count)
101 return NULL;
102
103 ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf,
104 ub_bufs[0]));
105 for (i = 0; i < index; i++)
106 ptr += update_size((struct update *)ptr);
107
108 if (size != NULL)
109 *size = update_size((struct update *)ptr);
110
111 return ptr;
112}
113
114static inline void update_init_reply_buf(struct update_reply *reply, int count)
115{
116 reply->ur_version = UPDATE_REPLY_V1;
117 reply->ur_count = count;
118}
119
120static inline void *update_get_buf_internal(struct update_reply *reply,
121 int index, int *size)
122{
123 char *ptr;
124 int count = reply->ur_count;
125 int i;
126
127 if (index >= count)
128 return NULL;
129
130 ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply,
131 ur_lens[count]));
132 for (i = 0; i < index; i++) {
133 LASSERT(reply->ur_lens[i] > 0);
134 ptr += cfs_size_round(reply->ur_lens[i]);
135 }
136
137 if (size != NULL)
138 *size = reply->ur_lens[index];
139
140 return ptr;
141}
142
143static inline void update_insert_reply(struct update_reply *reply, void *data,
144 int data_len, int index, int rc)
145{
146 char *ptr;
147
148 ptr = update_get_buf_internal(reply, index, NULL);
149 LASSERT(ptr != NULL);
150
151 *(int *)ptr = cpu_to_le32(rc);
152 ptr += sizeof(int);
153 if (data_len > 0) {
154 LASSERT(data != NULL);
155 memcpy(ptr, data, data_len);
156 }
157 reply->ur_lens[index] = data_len + sizeof(int);
158}
159
160static inline int update_get_reply_buf(struct update_reply *reply, void **buf,
161 int index)
162{
163 char *ptr;
164 int size = 0;
165 int result;
166
167 ptr = update_get_buf_internal(reply, index, &size);
168 result = *(int *)ptr;
169
170 if (result < 0)
171 return result;
172
173 LASSERT((ptr != NULL && size >= sizeof(int)));
174 *buf = ptr + sizeof(int);
175 return size - sizeof(int);
176}
177
178static inline int update_get_reply_result(struct update_reply *reply,
179 void **buf, int index)
180{
181 void *ptr;
182 int size;
183
184 ptr = update_get_buf_internal(reply, index, &size);
185 LASSERT(ptr != NULL && size > sizeof(int));
186 return *(int *)ptr;
187}
188
189#endif
diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
index 24d26ab35346..23095bb75226 100644
--- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
@@ -586,6 +586,12 @@ int ccc_lock_enqueue(const struct lu_env *env,
586 return 0; 586 return 0;
587} 587}
588 588
589int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice)
590{
591 CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
592 return 0;
593}
594
589int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice) 595int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice)
590{ 596{
591 CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj)); 597 CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
index 6c6c57ca91de..20e64cddb1f4 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
@@ -249,8 +249,9 @@ typedef enum ldlm_policy_res ldlm_policy_res_t;
249 struct __##var##__dummy_read {; } /* semicolon catcher */ 249 struct __##var##__dummy_read {; } /* semicolon catcher */
250 250
251#define LDLM_POOL_PROC_WRITER(var, type) \ 251#define LDLM_POOL_PROC_WRITER(var, type) \
252 static int lprocfs_wr_##var(struct file *file, const char *buffer, \ 252 static int lprocfs_wr_##var(struct file *file, \
253 unsigned long count, void *data) \ 253 const char __user *buffer, \
254 unsigned long count, void *data) \
254 { \ 255 { \
255 struct ldlm_pool *pl = data; \ 256 struct ldlm_pool *pl = data; \
256 type tmp; \ 257 type tmp; \
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 4c838f615a64..d20d277dc2f7 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -470,6 +470,7 @@ static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl)
470static int ldlm_cli_pool_recalc(struct ldlm_pool *pl) 470static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
471{ 471{
472 time_t recalc_interval_sec; 472 time_t recalc_interval_sec;
473 int ret;
473 474
474 recalc_interval_sec = get_seconds() - pl->pl_recalc_time; 475 recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
475 if (recalc_interval_sec < pl->pl_recalc_period) 476 if (recalc_interval_sec < pl->pl_recalc_period)
@@ -490,16 +491,15 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
490 */ 491 */
491 ldlm_cli_pool_pop_slv(pl); 492 ldlm_cli_pool_pop_slv(pl);
492 493
493 pl->pl_recalc_time = get_seconds();
494 lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
495 recalc_interval_sec);
496 spin_unlock(&pl->pl_lock); 494 spin_unlock(&pl->pl_lock);
497 495
498 /* 496 /*
499 * Do not cancel locks in case lru resize is disabled for this ns. 497 * Do not cancel locks in case lru resize is disabled for this ns.
500 */ 498 */
501 if (!ns_connect_lru_resize(ldlm_pl2ns(pl))) 499 if (!ns_connect_lru_resize(ldlm_pl2ns(pl))) {
502 return 0; 500 ret = 0;
501 goto out;
502 }
503 503
504 /* 504 /*
505 * In the time of canceling locks on client we do not need to maintain 505 * In the time of canceling locks on client we do not need to maintain
@@ -507,7 +507,19 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
507 * It may be called when SLV has changed much, this is why we do not 507 * It may be called when SLV has changed much, this is why we do not
508 * take into account pl->pl_recalc_time here. 508 * take into account pl->pl_recalc_time here.
509 */ 509 */
510 return ldlm_cancel_lru(ldlm_pl2ns(pl), 0, LCF_ASYNC, LDLM_CANCEL_LRUR); 510 ret = ldlm_cancel_lru(ldlm_pl2ns(pl), 0, LCF_ASYNC, LDLM_CANCEL_LRUR);
511
512out:
513 spin_lock(&pl->pl_lock);
514 /*
515 * Time of LRU resizing might be longer than period,
516 * so update after LRU resizing rather than before it.
517 */
518 pl->pl_recalc_time = get_seconds();
519 lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
520 recalc_interval_sec);
521 spin_unlock(&pl->pl_lock);
522 return ret;
511} 523}
512 524
513/** 525/**
@@ -591,6 +603,14 @@ int ldlm_pool_recalc(struct ldlm_pool *pl)
591 } 603 }
592 recalc_interval_sec = pl->pl_recalc_time - get_seconds() + 604 recalc_interval_sec = pl->pl_recalc_time - get_seconds() +
593 pl->pl_recalc_period; 605 pl->pl_recalc_period;
606 if (recalc_interval_sec <= 0) {
607 /* Prevent too frequent recalculation. */
608 CDEBUG(D_DLMTRACE, "Negative interval(%ld), "
609 "too short period(%ld)",
610 recalc_interval_sec,
611 pl->pl_recalc_period);
612 recalc_interval_sec = 1;
613 }
594 614
595 return recalc_interval_sec; 615 return recalc_interval_sec;
596} 616}
@@ -697,8 +717,8 @@ LPROC_SEQ_FOPS_RO(lprocfs_grant_plan);
697LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int); 717LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int);
698LDLM_POOL_PROC_WRITER(recalc_period, int); 718LDLM_POOL_PROC_WRITER(recalc_period, int);
699static ssize_t lprocfs_recalc_period_seq_write(struct file *file, 719static ssize_t lprocfs_recalc_period_seq_write(struct file *file,
700 const char *buf, size_t len, 720 const char __user *buf,
701 loff_t *off) 721 size_t len, loff_t *off)
702{ 722{
703 struct seq_file *seq = file->private_data; 723 struct seq_file *seq = file->private_data;
704 724
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 1f150e46f50e..c6f62a91b233 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -72,7 +72,7 @@ extern unsigned int ldlm_cancel_unused_locks_before_replay;
72unsigned int ldlm_dump_granted_max = 256; 72unsigned int ldlm_dump_granted_max = 256;
73 73
74#if defined(CONFIG_PROC_FS) 74#if defined(CONFIG_PROC_FS)
75static ssize_t lprocfs_wr_dump_ns(struct file *file, const char *buffer, 75static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer,
76 size_t count, loff_t *off) 76 size_t count, loff_t *off)
77{ 77{
78 ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE); 78 ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);
@@ -287,8 +287,9 @@ static int lprocfs_elc_seq_show(struct seq_file *m, void *v)
287 return lprocfs_rd_uint(m, &supp); 287 return lprocfs_rd_uint(m, &supp);
288} 288}
289 289
290static ssize_t lprocfs_elc_seq_write(struct file *file, const char *buffer, 290static ssize_t lprocfs_elc_seq_write(struct file *file,
291 size_t count, loff_t *off) 291 const char __user *buffer,
292 size_t count, loff_t *off)
292{ 293{
293 struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private; 294 struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private;
294 unsigned int supp = -1; 295 unsigned int supp = -1;
diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c
index a7a7ac626aaf..76c62e87a415 100644
--- a/drivers/staging/lustre/lustre/libcfs/debug.c
+++ b/drivers/staging/lustre/lustre/libcfs/debug.c
@@ -57,7 +57,7 @@ module_param(libcfs_debug, int, 0644);
57MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask"); 57MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
58EXPORT_SYMBOL(libcfs_debug); 58EXPORT_SYMBOL(libcfs_debug);
59 59
60unsigned int libcfs_debug_mb = 0; 60static unsigned int libcfs_debug_mb;
61module_param(libcfs_debug_mb, uint, 0644); 61module_param(libcfs_debug_mb, uint, 0644);
62MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size."); 62MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size.");
63EXPORT_SYMBOL(libcfs_debug_mb); 63EXPORT_SYMBOL(libcfs_debug_mb);
@@ -93,7 +93,7 @@ EXPORT_SYMBOL(libcfs_debug_binary);
93unsigned int libcfs_stack = 3 * THREAD_SIZE / 4; 93unsigned int libcfs_stack = 3 * THREAD_SIZE / 4;
94EXPORT_SYMBOL(libcfs_stack); 94EXPORT_SYMBOL(libcfs_stack);
95 95
96unsigned int portal_enter_debugger; 96static unsigned int portal_enter_debugger;
97EXPORT_SYMBOL(portal_enter_debugger); 97EXPORT_SYMBOL(portal_enter_debugger);
98 98
99unsigned int libcfs_catastrophe; 99unsigned int libcfs_catastrophe;
@@ -115,7 +115,7 @@ static wait_queue_head_t debug_ctlwq;
115char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT; 115char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
116 116
117/* We need to pass a pointer here, but elsewhere this must be a const */ 117/* We need to pass a pointer here, but elsewhere this must be a const */
118char *libcfs_debug_file_path; 118static char *libcfs_debug_file_path;
119module_param(libcfs_debug_file_path, charp, 0644); 119module_param(libcfs_debug_file_path, charp, 0644);
120MODULE_PARM_DESC(libcfs_debug_file_path, 120MODULE_PARM_DESC(libcfs_debug_file_path,
121 "Path for dumping debug logs, set 'NONE' to prevent log dumping"); 121 "Path for dumping debug logs, set 'NONE' to prevent log dumping");
@@ -124,7 +124,7 @@ int libcfs_panic_in_progress;
124 124
125/* libcfs_debug_token2mask() expects the returned 125/* libcfs_debug_token2mask() expects the returned
126 * string in lower-case */ 126 * string in lower-case */
127const char * 127static const char *
128libcfs_debug_subsys2str(int subsys) 128libcfs_debug_subsys2str(int subsys)
129{ 129{
130 switch (1 << subsys) { 130 switch (1 << subsys) {
@@ -185,7 +185,7 @@ libcfs_debug_subsys2str(int subsys)
185 185
186/* libcfs_debug_token2mask() expects the returned 186/* libcfs_debug_token2mask() expects the returned
187 * string in lower-case */ 187 * string in lower-case */
188const char * 188static const char *
189libcfs_debug_dbg2str(int debug) 189libcfs_debug_dbg2str(int debug)
190{ 190{
191 switch (1 << debug) { 191 switch (1 << debug) {
@@ -350,7 +350,7 @@ void libcfs_debug_dumplog_internal(void *arg)
350 current->journal_info = journal_info; 350 current->journal_info = journal_info;
351} 351}
352 352
353int libcfs_debug_dumplog_thread(void *arg) 353static int libcfs_debug_dumplog_thread(void *arg)
354{ 354{
355 libcfs_debug_dumplog_internal(arg); 355 libcfs_debug_dumplog_internal(arg);
356 wake_up(&debug_ctlwq); 356 wake_up(&debug_ctlwq);
diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c
index 2d1e6729e996..ec3a2a8b8b2c 100644
--- a/drivers/staging/lustre/lustre/libcfs/hash.c
+++ b/drivers/staging/lustre/lustre/libcfs/hash.c
@@ -126,18 +126,21 @@ cfs_hash_nl_unlock(union cfs_hash_lock *lock, int exclusive) {}
126 126
127static inline void 127static inline void
128cfs_hash_spin_lock(union cfs_hash_lock *lock, int exclusive) 128cfs_hash_spin_lock(union cfs_hash_lock *lock, int exclusive)
129 __acquires(&lock->spin)
129{ 130{
130 spin_lock(&lock->spin); 131 spin_lock(&lock->spin);
131} 132}
132 133
133static inline void 134static inline void
134cfs_hash_spin_unlock(union cfs_hash_lock *lock, int exclusive) 135cfs_hash_spin_unlock(union cfs_hash_lock *lock, int exclusive)
136 __releases(&lock->spin)
135{ 137{
136 spin_unlock(&lock->spin); 138 spin_unlock(&lock->spin);
137} 139}
138 140
139static inline void 141static inline void
140cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive) 142cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive)
143 __acquires(&lock->rw)
141{ 144{
142 if (!exclusive) 145 if (!exclusive)
143 read_lock(&lock->rw); 146 read_lock(&lock->rw);
@@ -147,6 +150,7 @@ cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive)
147 150
148static inline void 151static inline void
149cfs_hash_rw_unlock(union cfs_hash_lock *lock, int exclusive) 152cfs_hash_rw_unlock(union cfs_hash_lock *lock, int exclusive)
153 __releases(&lock->rw)
150{ 154{
151 if (!exclusive) 155 if (!exclusive)
152 read_unlock(&lock->rw); 156 read_unlock(&lock->rw);
@@ -1580,7 +1584,7 @@ cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func,
1580 1584
1581 stop_on_change = cfs_hash_with_rehash_key(hs) || 1585 stop_on_change = cfs_hash_with_rehash_key(hs) ||
1582 !cfs_hash_with_no_itemref(hs) || 1586 !cfs_hash_with_no_itemref(hs) ||
1583 CFS_HOP(hs, put_locked) == NULL; 1587 hs->hs_ops->hs_put_locked == NULL;
1584 cfs_hash_lock(hs, 0); 1588 cfs_hash_lock(hs, 0);
1585 LASSERT(!cfs_hash_is_rehashing(hs)); 1589 LASSERT(!cfs_hash_is_rehashing(hs));
1586 1590
@@ -1635,9 +1639,9 @@ cfs_hash_for_each_nolock(struct cfs_hash *hs,
1635 !cfs_hash_with_no_itemref(hs)) 1639 !cfs_hash_with_no_itemref(hs))
1636 return -EOPNOTSUPP; 1640 return -EOPNOTSUPP;
1637 1641
1638 if (CFS_HOP(hs, get) == NULL || 1642 if (hs->hs_ops->hs_get == NULL ||
1639 (CFS_HOP(hs, put) == NULL && 1643 (hs->hs_ops->hs_put == NULL &&
1640 CFS_HOP(hs, put_locked) == NULL)) 1644 hs->hs_ops->hs_put_locked == NULL))
1641 return -EOPNOTSUPP; 1645 return -EOPNOTSUPP;
1642 1646
1643 cfs_hash_for_each_enter(hs); 1647 cfs_hash_for_each_enter(hs);
@@ -1667,9 +1671,9 @@ cfs_hash_for_each_empty(struct cfs_hash *hs,
1667 if (cfs_hash_with_no_lock(hs)) 1671 if (cfs_hash_with_no_lock(hs))
1668 return -EOPNOTSUPP; 1672 return -EOPNOTSUPP;
1669 1673
1670 if (CFS_HOP(hs, get) == NULL || 1674 if (hs->hs_ops->hs_get == NULL ||
1671 (CFS_HOP(hs, put) == NULL && 1675 (hs->hs_ops->hs_put == NULL &&
1672 CFS_HOP(hs, put_locked) == NULL)) 1676 hs->hs_ops->hs_put_locked == NULL))
1673 return -EOPNOTSUPP; 1677 return -EOPNOTSUPP;
1674 1678
1675 cfs_hash_for_each_enter(hs); 1679 cfs_hash_for_each_enter(hs);
diff --git a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
index e2aa637abcf9..d9b7c6b69db4 100644
--- a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
+++ b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
@@ -228,12 +228,12 @@ int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
228 if (kkuc_groups[group].next == NULL) 228 if (kkuc_groups[group].next == NULL)
229 return 0; 229 return 0;
230 230
231 down_read(&kg_sem); 231 down_write(&kg_sem);
232 list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { 232 list_for_each_entry(reg, &kkuc_groups[group], kr_chain) {
233 if (reg->kr_fp != NULL) 233 if (reg->kr_fp != NULL)
234 rc = cb_func(reg->kr_data, cb_arg); 234 rc = cb_func(reg->kr_data, cb_arg);
235 } 235 }
236 up_read(&kg_sem); 236 up_write(&kg_sem);
237 237
238 return rc; 238 return rc;
239} 239}
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
index fb88733607a9..76d4392bd282 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
@@ -47,7 +47,7 @@ int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
47 int *oldmask, int minmask, int allmask) 47 int *oldmask, int minmask, int allmask)
48{ 48{
49 const char *debugstr; 49 const char *debugstr;
50 char op = 0; 50 char op = '\0';
51 int newmask = minmask, i, len, found = 0; 51 int newmask = minmask, i, len, found = 0;
52 52
53 /* <str> must be a list of tokens separated by whitespace 53 /* <str> must be a list of tokens separated by whitespace
@@ -55,10 +55,10 @@ int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
55 * appears first in <str>, '*oldmask' is used as the starting point 55 * appears first in <str>, '*oldmask' is used as the starting point
56 * (relative), otherwise minmask is used (absolute). An operator 56 * (relative), otherwise minmask is used (absolute). An operator
57 * applies to all following tokens up to the next operator. */ 57 * applies to all following tokens up to the next operator. */
58 while (*str != 0) { 58 while (*str != '\0') {
59 while (isspace(*str)) 59 while (isspace(*str))
60 str++; 60 str++;
61 if (*str == 0) 61 if (*str == '\0')
62 break; 62 break;
63 if (*str == '+' || *str == '-') { 63 if (*str == '+' || *str == '-') {
64 op = *str++; 64 op = *str++;
@@ -67,13 +67,15 @@ int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
67 newmask = *oldmask; 67 newmask = *oldmask;
68 while (isspace(*str)) 68 while (isspace(*str))
69 str++; 69 str++;
70 if (*str == 0) /* trailing op */ 70 if (*str == '\0') /* trailing op */
71 return -EINVAL; 71 return -EINVAL;
72 } 72 }
73 73
74 /* find token length */ 74 /* find token length */
75 for (len = 0; str[len] != 0 && !isspace(str[len]) && 75 len = 0;
76 str[len] != '+' && str[len] != '-'; len++); 76 while (str[len] != '\0' && !isspace(str[len]) &&
77 str[len] != '+' && str[len] != '-')
78 len++;
77 79
78 /* match token */ 80 /* match token */
79 found = 0; 81 found = 0;
@@ -132,7 +134,7 @@ char *cfs_firststr(char *str, size_t size)
132 ++end; 134 ++end;
133 } 135 }
134 136
135 *end= '\0'; 137 *end = '\0';
136out: 138out:
137 return str; 139 return str;
138} 140}
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
index d71ad5ed1f6d..277f6b890e09 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
@@ -82,17 +82,12 @@ int cfs_cap_raised(cfs_cap_t cap)
82 return cap_raised(current_cap(), cap); 82 return cap_raised(current_cap(), cap);
83} 83}
84 84
85void cfs_kernel_cap_pack(kernel_cap_t kcap, cfs_cap_t *cap) 85static void cfs_kernel_cap_pack(kernel_cap_t kcap, cfs_cap_t *cap)
86{ 86{
87 /* XXX lost high byte */ 87 /* XXX lost high byte */
88 *cap = kcap.cap[0]; 88 *cap = kcap.cap[0];
89} 89}
90 90
91void cfs_kernel_cap_unpack(kernel_cap_t *kcap, cfs_cap_t cap)
92{
93 kcap->cap[0] = cap;
94}
95
96cfs_cap_t cfs_curproc_cap_pack(void) 91cfs_cap_t cfs_curproc_cap_pack(void)
97{ 92{
98 cfs_cap_t cap; 93 cfs_cap_t cap;
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
index 83d3f08a37b2..c539e3741583 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
@@ -232,8 +232,9 @@ static int proc_debug_mb(struct ctl_table *table, int write,
232 __proc_debug_mb); 232 __proc_debug_mb);
233} 233}
234 234
235int proc_console_max_delay_cs(struct ctl_table *table, int write, 235static int proc_console_max_delay_cs(struct ctl_table *table, int write,
236 void __user *buffer, size_t *lenp, loff_t *ppos) 236 void __user *buffer, size_t *lenp,
237 loff_t *ppos)
237{ 238{
238 int rc, max_delay_cs; 239 int rc, max_delay_cs;
239 struct ctl_table dummy = *table; 240 struct ctl_table dummy = *table;
@@ -264,8 +265,9 @@ int proc_console_max_delay_cs(struct ctl_table *table, int write,
264 return rc; 265 return rc;
265} 266}
266 267
267int proc_console_min_delay_cs(struct ctl_table *table, int write, 268static int proc_console_min_delay_cs(struct ctl_table *table, int write,
268 void __user *buffer, size_t *lenp, loff_t *ppos) 269 void __user *buffer, size_t *lenp,
270 loff_t *ppos)
269{ 271{
270 int rc, min_delay_cs; 272 int rc, min_delay_cs;
271 struct ctl_table dummy = *table; 273 struct ctl_table dummy = *table;
@@ -296,8 +298,8 @@ int proc_console_min_delay_cs(struct ctl_table *table, int write,
296 return rc; 298 return rc;
297} 299}
298 300
299int proc_console_backoff(struct ctl_table *table, int write, 301static int proc_console_backoff(struct ctl_table *table, int write,
300 void __user *buffer, size_t *lenp, loff_t *ppos) 302 void __user *buffer, size_t *lenp, loff_t *ppos)
301{ 303{
302 int rc, backoff; 304 int rc, backoff;
303 struct ctl_table dummy = *table; 305 struct ctl_table dummy = *table;
@@ -324,16 +326,18 @@ int proc_console_backoff(struct ctl_table *table, int write,
324 return rc; 326 return rc;
325} 327}
326 328
327int libcfs_force_lbug(struct ctl_table *table, int write, void __user *buffer, 329static int libcfs_force_lbug(struct ctl_table *table, int write,
328 size_t *lenp, loff_t *ppos) 330 void __user *buffer,
331 size_t *lenp, loff_t *ppos)
329{ 332{
330 if (write) 333 if (write)
331 LBUG(); 334 LBUG();
332 return 0; 335 return 0;
333} 336}
334 337
335int proc_fail_loc(struct ctl_table *table, int write, void __user *buffer, 338static int proc_fail_loc(struct ctl_table *table, int write,
336 size_t *lenp, loff_t *ppos) 339 void __user *buffer,
340 size_t *lenp, loff_t *ppos)
337{ 341{
338 int rc; 342 int rc;
339 long old_fail_loc = cfs_fail_loc; 343 long old_fail_loc = cfs_fail_loc;
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
index b91a1f95bbd0..cd2fc01dea4c 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
@@ -43,7 +43,7 @@
43/* For sys_open & sys_close */ 43/* For sys_open & sys_close */
44#include <linux/syscalls.h> 44#include <linux/syscalls.h>
45 45
46int 46static int
47libcfs_sock_ioctl(int cmd, unsigned long arg) 47libcfs_sock_ioctl(int cmd, unsigned long arg)
48{ 48{
49 mm_segment_t oldmm = get_fs(); 49 mm_segment_t oldmm = get_fs();
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
index 976c61ed49f4..c8e293002e07 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
@@ -151,6 +151,7 @@ cfs_trace_buf_type_t cfs_trace_buf_idx_get(void)
151 * for details. 151 * for details.
152 */ 152 */
153int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking) 153int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
154 __acquires(&tcd->tc_lock)
154{ 155{
155 __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX); 156 __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
156 if (tcd->tcd_type == CFS_TCD_TYPE_IRQ) 157 if (tcd->tcd_type == CFS_TCD_TYPE_IRQ)
@@ -165,6 +166,7 @@ int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
165} 166}
166 167
167void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking) 168void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
169 __releases(&tcd->tcd_lock)
168{ 170{
169 __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX); 171 __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
170 if (tcd->tcd_type == CFS_TCD_TYPE_IRQ) 172 if (tcd->tcd_type == CFS_TCD_TYPE_IRQ)
@@ -269,5 +271,5 @@ int cfs_trace_max_debug_mb(void)
269{ 271{
270 int total_mb = (totalram_pages >> (20 - PAGE_SHIFT)); 272 int total_mb = (totalram_pages >> (20 - PAGE_SHIFT));
271 273
272 return MAX(512, (total_mb * 80)/100); 274 return max(512, (total_mb * 80)/100);
273} 275}
diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c
index 2c4fc74505bc..7dc77dd402b8 100644
--- a/drivers/staging/lustre/lustre/libcfs/module.c
+++ b/drivers/staging/lustre/lustre/libcfs/module.c
@@ -42,8 +42,7 @@
42#include "../../include/linux/lnet/lnet.h" 42#include "../../include/linux/lnet/lnet.h"
43#include "tracefile.h" 43#include "tracefile.h"
44 44
45void 45static void kportal_memhog_free (struct libcfs_device_userstate *ldu)
46kportal_memhog_free (struct libcfs_device_userstate *ldu)
47{ 46{
48 struct page **level0p = &ldu->ldu_memhog_root_page; 47 struct page **level0p = &ldu->ldu_memhog_root_page;
49 struct page **level1p; 48 struct page **level1p;
@@ -86,8 +85,7 @@ kportal_memhog_free (struct libcfs_device_userstate *ldu)
86 LASSERT (ldu->ldu_memhog_pages == 0); 85 LASSERT (ldu->ldu_memhog_pages == 0);
87} 86}
88 87
89int 88static int kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
90kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
91 gfp_t flags) 89 gfp_t flags)
92{ 90{
93 struct page **level0p; 91 struct page **level0p;
@@ -334,8 +332,6 @@ extern struct mutex cfs_trace_thread_mutex;
334extern struct cfs_wi_sched *cfs_sched_rehash; 332extern struct cfs_wi_sched *cfs_sched_rehash;
335 333
336extern void libcfs_init_nidstrings(void); 334extern void libcfs_init_nidstrings(void);
337extern int libcfs_arch_init(void);
338extern void libcfs_arch_cleanup(void);
339 335
340static int init_libcfs_module(void) 336static int init_libcfs_module(void)
341{ 337{
diff --git a/drivers/staging/lustre/lustre/libcfs/nidstrings.c b/drivers/staging/lustre/lustre/libcfs/nidstrings.c
index 47c239f22ba8..087449f4e6c1 100644
--- a/drivers/staging/lustre/lustre/libcfs/nidstrings.c
+++ b/drivers/staging/lustre/lustre/libcfs/nidstrings.c
@@ -81,14 +81,105 @@ libcfs_next_nidstring(void)
81 return str; 81 return str;
82} 82}
83 83
84static int libcfs_lo_str2addr(const char *str, int nob, __u32 *addr); 84static int libcfs_lo_str2addr(const char *str, int nob, __u32 *addr)
85static void libcfs_ip_addr2str(__u32 addr, char *str); 85{
86static int libcfs_ip_str2addr(const char *str, int nob, __u32 *addr); 86 *addr = 0;
87static void libcfs_decnum_addr2str(__u32 addr, char *str); 87 return 1;
88static void libcfs_hexnum_addr2str(__u32 addr, char *str); 88}
89static int libcfs_num_str2addr(const char *str, int nob, __u32 *addr); 89
90static int libcfs_num_parse(char *str, int len, struct list_head *list); 90static void libcfs_ip_addr2str(__u32 addr, char *str)
91static int libcfs_num_match(__u32 addr, struct list_head *list); 91{
92 snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u",
93 (addr >> 24) & 0xff, (addr >> 16) & 0xff,
94 (addr >> 8) & 0xff, addr & 0xff);
95}
96
97static int libcfs_ip_str2addr(const char *str, int nob, __u32 *addr)
98{
99 unsigned int a;
100 unsigned int b;
101 unsigned int c;
102 unsigned int d;
103 int n = nob; /* XscanfX */
104
105 /* numeric IP? */
106 if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 &&
107 n == nob &&
108 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
109 (c & ~0xff) == 0 && (d & ~0xff) == 0) {
110 *addr = ((a<<24)|(b<<16)|(c<<8)|d);
111 return 1;
112 }
113
114 return 0;
115}
116
117static void libcfs_decnum_addr2str(__u32 addr, char *str)
118{
119 snprintf(str, LNET_NIDSTR_SIZE, "%u", addr);
120}
121
122static void libcfs_hexnum_addr2str(__u32 addr, char *str)
123{
124 snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr);
125}
126
127static int libcfs_num_str2addr(const char *str, int nob, __u32 *addr)
128{
129 int n;
130
131 n = nob;
132 if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob)
133 return 1;
134
135 n = nob;
136 if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob)
137 return 1;
138
139 n = nob;
140 if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob)
141 return 1;
142
143 return 0;
144}
145
146/**
147 * Nf_parse_addrlist method for networks using numeric addresses.
148 *
149 * Examples of such networks are gm and elan.
150 *
151 * \retval 0 if \a str parsed to numeric address
152 * \retval errno otherwise
153 */
154static int
155libcfs_num_parse(char *str, int len, struct list_head *list)
156{
157 struct cfs_expr_list *el;
158 int rc;
159
160 rc = cfs_expr_list_parse(str, len, 0, MAX_NUMERIC_VALUE, &el);
161 if (rc == 0)
162 list_add_tail(&el->el_link, list);
163
164 return rc;
165}
166
167/*
168 * Nf_match_addr method for networks using numeric addresses
169 *
170 * \retval 1 on match
171 * \retval 0 otherwise
172 */
173static int
174libcfs_num_match(__u32 addr, struct list_head *numaddr)
175{
176 struct cfs_expr_list *el;
177
178 LASSERT(!list_empty(numaddr));
179 el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
180
181 return cfs_expr_list_match(addr, el);
182}
92 183
93struct netstrfns { 184struct netstrfns {
94 int nf_type; 185 int nf_type;
@@ -197,24 +288,7 @@ static struct netstrfns libcfs_netstrfns[] = {
197 {/* .nf_type */ -1}, 288 {/* .nf_type */ -1},
198}; 289};
199 290
200const int libcfs_nnetstrfns = ARRAY_SIZE(libcfs_netstrfns); 291static const int libcfs_nnetstrfns = ARRAY_SIZE(libcfs_netstrfns);
201
202int
203libcfs_lo_str2addr(const char *str, int nob, __u32 *addr)
204{
205 *addr = 0;
206 return 1;
207}
208
209void
210libcfs_ip_addr2str(__u32 addr, char *str)
211{
212#if 0 /* never lookup */
213#endif
214 snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u",
215 (addr >> 24) & 0xff, (addr >> 16) & 0xff,
216 (addr >> 8) & 0xff, addr & 0xff);
217}
218 292
219/* CAVEAT EMPTOR XscanfX 293/* CAVEAT EMPTOR XscanfX
220 * I use "%n" at the end of a sscanf format to detect trailing junk. However 294 * I use "%n" at the end of a sscanf format to detect trailing junk. However
@@ -223,60 +297,7 @@ libcfs_ip_addr2str(__u32 addr, char *str)
223 * fine, if it doesn't, then the scan ended at the end of the string, which is 297 * fine, if it doesn't, then the scan ended at the end of the string, which is
224 * fine too :) */ 298 * fine too :) */
225 299
226int 300static struct netstrfns *
227libcfs_ip_str2addr(const char *str, int nob, __u32 *addr)
228{
229 unsigned int a;
230 unsigned int b;
231 unsigned int c;
232 unsigned int d;
233 int n = nob; /* XscanfX */
234
235 /* numeric IP? */
236 if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 &&
237 n == nob &&
238 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
239 (c & ~0xff) == 0 && (d & ~0xff) == 0) {
240 *addr = ((a<<24)|(b<<16)|(c<<8)|d);
241 return 1;
242 }
243
244 return 0;
245}
246
247void
248libcfs_decnum_addr2str(__u32 addr, char *str)
249{
250 snprintf(str, LNET_NIDSTR_SIZE, "%u", addr);
251}
252
253void
254libcfs_hexnum_addr2str(__u32 addr, char *str)
255{
256 snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr);
257}
258
259int
260libcfs_num_str2addr(const char *str, int nob, __u32 *addr)
261{
262 int n;
263
264 n = nob;
265 if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob)
266 return 1;
267
268 n = nob;
269 if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob)
270 return 1;
271
272 n = nob;
273 if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob)
274 return 1;
275
276 return 0;
277}
278
279struct netstrfns *
280libcfs_lnd2netstrfns(int lnd) 301libcfs_lnd2netstrfns(int lnd)
281{ 302{
282 int i; 303 int i;
@@ -289,7 +310,7 @@ libcfs_lnd2netstrfns(int lnd)
289 return NULL; 310 return NULL;
290} 311}
291 312
292struct netstrfns * 313static struct netstrfns *
293libcfs_namenum2netstrfns(const char *name) 314libcfs_namenum2netstrfns(const char *name)
294{ 315{
295 struct netstrfns *nf; 316 struct netstrfns *nf;
@@ -304,7 +325,7 @@ libcfs_namenum2netstrfns(const char *name)
304 return NULL; 325 return NULL;
305} 326}
306 327
307struct netstrfns * 328static struct netstrfns *
308libcfs_name2netstrfns(const char *name) 329libcfs_name2netstrfns(const char *name)
309{ 330{
310 int i; 331 int i;
@@ -343,7 +364,7 @@ libcfs_lnd2str(int lnd)
343 return nf->nf_name; 364 return nf->nf_name;
344 365
345 str = libcfs_next_nidstring(); 366 str = libcfs_next_nidstring();
346 snprintf(str, LNET_NIDSTR_SIZE, "?%u?", lnd); 367 snprintf(str, LNET_NIDSTR_SIZE, "?%d?", lnd);
347 return str; 368 return str;
348} 369}
349EXPORT_SYMBOL(libcfs_lnd2str); 370EXPORT_SYMBOL(libcfs_lnd2str);
@@ -369,11 +390,11 @@ libcfs_net2str(__u32 net)
369 char *str = libcfs_next_nidstring(); 390 char *str = libcfs_next_nidstring();
370 391
371 if (nf == NULL) 392 if (nf == NULL)
372 snprintf(str, LNET_NIDSTR_SIZE, "<%u:%u>", lnd, num); 393 snprintf(str, LNET_NIDSTR_SIZE, "<%d:%d>", lnd, num);
373 else if (num == 0) 394 else if (num == 0)
374 snprintf(str, LNET_NIDSTR_SIZE, "%s", nf->nf_name); 395 snprintf(str, LNET_NIDSTR_SIZE, "%s", nf->nf_name);
375 else 396 else
376 snprintf(str, LNET_NIDSTR_SIZE, "%s%u", nf->nf_name, num); 397 snprintf(str, LNET_NIDSTR_SIZE, "%s%d", nf->nf_name, num);
377 398
378 return str; 399 return str;
379} 400}
@@ -397,7 +418,7 @@ libcfs_nid2str(lnet_nid_t nid)
397 str = libcfs_next_nidstring(); 418 str = libcfs_next_nidstring();
398 419
399 if (nf == NULL) 420 if (nf == NULL)
400 snprintf(str, LNET_NIDSTR_SIZE, "%x@<%u:%u>", addr, lnd, nnum); 421 snprintf(str, LNET_NIDSTR_SIZE, "%x@<%d:%d>", addr, lnd, nnum);
401 else { 422 else {
402 nf->nf_addr2str(addr, str); 423 nf->nf_addr2str(addr, str);
403 nob = strlen(str); 424 nob = strlen(str);
@@ -405,7 +426,7 @@ libcfs_nid2str(lnet_nid_t nid)
405 snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s", 426 snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s",
406 nf->nf_name); 427 nf->nf_name);
407 else 428 else
408 snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s%u", 429 snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s%d",
409 nf->nf_name, nnum); 430 nf->nf_name, nnum);
410 } 431 }
411 432
@@ -586,27 +607,6 @@ struct addrrange {
586}; 607};
587 608
588/** 609/**
589 * Nf_parse_addrlist method for networks using numeric addresses.
590 *
591 * Examples of such networks are gm and elan.
592 *
593 * \retval 0 if \a str parsed to numeric address
594 * \retval errno otherwise
595 */
596static int
597libcfs_num_parse(char *str, int len, struct list_head *list)
598{
599 struct cfs_expr_list *el;
600 int rc;
601
602 rc = cfs_expr_list_parse(str, len, 0, MAX_NUMERIC_VALUE, &el);
603 if (rc == 0)
604 list_add_tail(&el->el_link, list);
605
606 return rc;
607}
608
609/**
610 * Parses \<addrrange\> token on the syntax. 610 * Parses \<addrrange\> token on the syntax.
611 * 611 *
612 * Allocates struct addrrange and links to \a nidrange via 612 * Allocates struct addrrange and links to \a nidrange via
@@ -812,23 +812,6 @@ cfs_parse_nidlist(char *str, int len, struct list_head *nidlist)
812} 812}
813EXPORT_SYMBOL(cfs_parse_nidlist); 813EXPORT_SYMBOL(cfs_parse_nidlist);
814 814
815/*
816 * Nf_match_addr method for networks using numeric addresses
817 *
818 * \retval 1 on match
819 * \retval 0 otherwise
820 */
821static int
822libcfs_num_match(__u32 addr, struct list_head *numaddr)
823{
824 struct cfs_expr_list *el;
825
826 LASSERT(!list_empty(numaddr));
827 el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
828
829 return cfs_expr_list_match(addr, el);
830}
831
832/** 815/**
833 * Matches a nid (\a nid) against the compiled list of nidranges (\a nidlist). 816 * Matches a nid (\a nid) against the compiled list of nidranges (\a nidlist).
834 * 817 *
diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c
index 5917c31c7ed6..eb65b50f832d 100644
--- a/drivers/staging/lustre/lustre/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c
@@ -55,7 +55,7 @@ static struct tracefiled_ctl trace_tctl;
55struct mutex cfs_trace_thread_mutex; 55struct mutex cfs_trace_thread_mutex;
56static int thread_running = 0; 56static int thread_running = 0;
57 57
58atomic_t cfs_tage_allocated = ATOMIC_INIT(0); 58static atomic_t cfs_tage_allocated = ATOMIC_INIT(0);
59 59
60static void put_pages_on_tcd_daemon_list(struct page_collection *pc, 60static void put_pages_on_tcd_daemon_list(struct page_collection *pc,
61 struct cfs_trace_cpu_data *tcd); 61 struct cfs_trace_cpu_data *tcd);
@@ -1037,6 +1037,7 @@ static int tracefiled(void *arg)
1037 tage->used, rc); 1037 tage->used, rc);
1038 put_pages_back(&pc); 1038 put_pages_back(&pc);
1039 __LASSERT(list_empty(&pc.pc_pages)); 1039 __LASSERT(list_empty(&pc.pc_pages));
1040 break;
1040 } 1041 }
1041 } 1042 }
1042 MMSPACE_CLOSE; 1043 MMSPACE_CLOSE;
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index 1ac7a702ce26..a18201913273 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -183,7 +183,10 @@ static int ll_dir_filler(void *_hash, struct page *page0)
183 op_data->op_offset = hash; 183 op_data->op_offset = hash;
184 rc = md_readpage(exp, op_data, page_pool, &request); 184 rc = md_readpage(exp, op_data, page_pool, &request);
185 ll_finish_md_op_data(op_data); 185 ll_finish_md_op_data(op_data);
186 if (rc == 0) { 186 if (rc < 0) {
187 /* page0 is special, which was added into page cache early */
188 delete_from_page_cache(page0);
189 } else if (rc == 0) {
187 body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); 190 body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
188 /* Checked by mdc_readpage() */ 191 /* Checked by mdc_readpage() */
189 LASSERT(body != NULL); 192 LASSERT(body != NULL);
@@ -278,7 +281,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
278 spin_lock_irq(&mapping->tree_lock); 281 spin_lock_irq(&mapping->tree_lock);
279 found = radix_tree_gang_lookup(&mapping->page_tree, 282 found = radix_tree_gang_lookup(&mapping->page_tree,
280 (void **)&page, offset, 1); 283 (void **)&page, offset, 1);
281 if (found > 0) { 284 if (found > 0 && !radix_tree_exceptional_entry(page)) {
282 struct lu_dirpage *dp; 285 struct lu_dirpage *dp;
283 286
284 page_cache_get(page); 287 page_cache_get(page);
@@ -652,8 +655,8 @@ static int ll_send_mgc_param(struct obd_export *mgc, char *string)
652 return rc; 655 return rc;
653} 656}
654 657
655int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump, 658static int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump,
656 char *filename) 659 char *filename)
657{ 660{
658 struct ptlrpc_request *request = NULL; 661 struct ptlrpc_request *request = NULL;
659 struct md_op_data *op_data; 662 struct md_op_data *op_data;
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 35a2df01528c..7c7ef7ec908e 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1553,6 +1553,11 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
1553 struct ccc_grouplock grouplock; 1553 struct ccc_grouplock grouplock;
1554 int rc; 1554 int rc;
1555 1555
1556 if (arg == 0) {
1557 CWARN("group id for group lock must not be 0\n");
1558 return -EINVAL;
1559 }
1560
1556 if (ll_file_nolock(file)) 1561 if (ll_file_nolock(file))
1557 return -EOPNOTSUPP; 1562 return -EOPNOTSUPP;
1558 1563
@@ -1587,7 +1592,8 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
1587 return 0; 1592 return 0;
1588} 1593}
1589 1594
1590int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg) 1595static int ll_put_grouplock(struct inode *inode, struct file *file,
1596 unsigned long arg)
1591{ 1597{
1592 struct ll_inode_info *lli = ll_i2info(inode); 1598 struct ll_inode_info *lli = ll_i2info(inode);
1593 struct ll_file_data *fd = LUSTRE_FPRIVATE(file); 1599 struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index e6a909e6faf0..aaa13bd3e8de 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -399,9 +399,6 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
399 return -ERANGE; 399 return -ERANGE;
400 } 400 }
401 401
402 if (sbi->ll_dt_exp == NULL)
403 return -ENODEV;
404
405 spin_lock(&sbi->ll_lock); 402 spin_lock(&sbi->ll_lock);
406 diff = pages_number - cache->ccc_lru_max; 403 diff = pages_number - cache->ccc_lru_max;
407 spin_unlock(&sbi->ll_lock); 404 spin_unlock(&sbi->ll_lock);
@@ -437,6 +434,11 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
437 if (diff <= 0) 434 if (diff <= 0)
438 break; 435 break;
439 436
437 if (sbi->ll_dt_exp == NULL) { /* being initialized */
438 rc = -ENODEV;
439 break;
440 }
441
440 /* difficult - have to ask OSCs to drop LRU slots. */ 442 /* difficult - have to ask OSCs to drop LRU slots. */
441 tmp = diff << 1; 443 tmp = diff << 1;
442 rc = obd_set_info_async(NULL, sbi->ll_dt_exp, 444 rc = obd_set_info_async(NULL, sbi->ll_dt_exp,
diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c
index 6aff155651cc..7c1e02a031ba 100644
--- a/drivers/staging/lustre/lustre/llite/super25.c
+++ b/drivers/staging/lustre/lustre/llite/super25.c
@@ -72,21 +72,6 @@ static void ll_destroy_inode(struct inode *inode)
72 call_rcu(&inode->i_rcu, ll_inode_destroy_callback); 72 call_rcu(&inode->i_rcu, ll_inode_destroy_callback);
73} 73}
74 74
75static int ll_init_inodecache(void)
76{
77 ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
78 sizeof(struct ll_inode_info),
79 0, SLAB_HWCACHE_ALIGN, NULL);
80 if (ll_inode_cachep == NULL)
81 return -ENOMEM;
82 return 0;
83}
84
85static void ll_destroy_inodecache(void)
86{
87 kmem_cache_destroy(ll_inode_cachep);
88}
89
90/* exported operations */ 75/* exported operations */
91struct super_operations lustre_super_operations = { 76struct super_operations lustre_super_operations = {
92 .alloc_inode = ll_alloc_inode, 77 .alloc_inode = ll_alloc_inode,
@@ -104,9 +89,10 @@ void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));
104 89
105static int __init init_lustre_lite(void) 90static int __init init_lustre_lite(void)
106{ 91{
107 int i, rc, seed[2]; 92 struct proc_dir_entry *entry;
108 struct timeval tv;
109 lnet_process_id_t lnet_id; 93 lnet_process_id_t lnet_id;
94 struct timeval tv;
95 int i, rc, seed[2];
110 96
111 CLASSERT(sizeof(LUSTRE_VOLATILE_HDR) == LUSTRE_VOLATILE_HDR_LEN + 1); 97 CLASSERT(sizeof(LUSTRE_VOLATILE_HDR) == LUSTRE_VOLATILE_HDR_LEN + 1);
112 98
@@ -116,59 +102,52 @@ static int __init init_lustre_lite(void)
116 CDEBUG(D_INFO, "Lustre client module (%p).\n", 102 CDEBUG(D_INFO, "Lustre client module (%p).\n",
117 &lustre_super_operations); 103 &lustre_super_operations);
118 104
119 rc = ll_init_inodecache(); 105 rc = -ENOMEM;
120 if (rc) 106 ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
121 return -ENOMEM; 107 sizeof(struct ll_inode_info),
108 0, SLAB_HWCACHE_ALIGN, NULL);
109 if (ll_inode_cachep == NULL)
110 goto out_cache;
111
122 ll_file_data_slab = kmem_cache_create("ll_file_data", 112 ll_file_data_slab = kmem_cache_create("ll_file_data",
123 sizeof(struct ll_file_data), 0, 113 sizeof(struct ll_file_data), 0,
124 SLAB_HWCACHE_ALIGN, NULL); 114 SLAB_HWCACHE_ALIGN, NULL);
125 if (ll_file_data_slab == NULL) { 115 if (ll_file_data_slab == NULL)
126 ll_destroy_inodecache(); 116 goto out_cache;
127 return -ENOMEM;
128 }
129 117
130 ll_remote_perm_cachep = kmem_cache_create("ll_remote_perm_cache", 118 ll_remote_perm_cachep = kmem_cache_create("ll_remote_perm_cache",
131 sizeof(struct ll_remote_perm), 119 sizeof(struct ll_remote_perm),
132 0, 0, NULL); 120 0, 0, NULL);
133 if (ll_remote_perm_cachep == NULL) { 121 if (ll_remote_perm_cachep == NULL)
134 kmem_cache_destroy(ll_file_data_slab); 122 goto out_cache;
135 ll_file_data_slab = NULL;
136 ll_destroy_inodecache();
137 return -ENOMEM;
138 }
139 123
140 ll_rmtperm_hash_cachep = kmem_cache_create("ll_rmtperm_hash_cache", 124 ll_rmtperm_hash_cachep = kmem_cache_create("ll_rmtperm_hash_cache",
141 REMOTE_PERM_HASHSIZE * 125 REMOTE_PERM_HASHSIZE *
142 sizeof(struct list_head), 126 sizeof(struct list_head),
143 0, 0, NULL); 127 0, 0, NULL);
144 if (ll_rmtperm_hash_cachep == NULL) { 128 if (ll_rmtperm_hash_cachep == NULL)
145 kmem_cache_destroy(ll_remote_perm_cachep); 129 goto out_cache;
146 ll_remote_perm_cachep = NULL; 130
147 kmem_cache_destroy(ll_file_data_slab); 131 entry = lprocfs_register("llite", proc_lustre_root, NULL, NULL);
148 ll_file_data_slab = NULL; 132 if (IS_ERR(entry)) {
149 ll_destroy_inodecache(); 133 rc = PTR_ERR(entry);
150 return -ENOMEM; 134 CERROR("cannot register '/proc/fs/lustre/llite': rc = %d\n",
135 rc);
136 goto out_cache;
151 } 137 }
152 138
153 proc_lustre_fs_root = proc_lustre_root ? 139 proc_lustre_fs_root = entry;
154 lprocfs_register("llite", proc_lustre_root, NULL, NULL) : NULL;
155
156 lustre_register_client_fill_super(ll_fill_super);
157 lustre_register_kill_super_cb(ll_kill_super);
158
159 lustre_register_client_process_config(ll_process_config);
160 140
161 cfs_get_random_bytes(seed, sizeof(seed)); 141 cfs_get_random_bytes(seed, sizeof(seed));
162 142
163 /* Nodes with small feet have little entropy 143 /* Nodes with small feet have little entropy. The NID for this
164 * the NID for this node gives the most entropy in the low bits */ 144 * node gives the most entropy in the low bits */
165 for (i = 0; ; i++) { 145 for (i = 0;; i++) {
166 if (LNetGetId(i, &lnet_id) == -ENOENT) { 146 if (LNetGetId(i, &lnet_id) == -ENOENT)
167 break; 147 break;
168 } 148
169 if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND) { 149 if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND)
170 seed[0] ^= LNET_NIDADDR(lnet_id.nid); 150 seed[0] ^= LNET_NIDADDR(lnet_id.nid);
171 }
172 } 151 }
173 152
174 do_gettimeofday(&tv); 153 do_gettimeofday(&tv);
@@ -177,20 +156,54 @@ static int __init init_lustre_lite(void)
177 init_timer(&ll_capa_timer); 156 init_timer(&ll_capa_timer);
178 ll_capa_timer.function = ll_capa_timer_callback; 157 ll_capa_timer.function = ll_capa_timer_callback;
179 rc = ll_capa_thread_start(); 158 rc = ll_capa_thread_start();
180 /* 159 if (rc != 0)
181 * XXX normal cleanup is needed here. 160 goto out_proc;
182 */
183 if (rc == 0)
184 rc = vvp_global_init();
185 161
186 if (rc == 0) 162 rc = vvp_global_init();
187 rc = ll_xattr_init(); 163 if (rc != 0)
164 goto out_capa;
165
166 rc = ll_xattr_init();
167 if (rc != 0)
168 goto out_vvp;
169
170 lustre_register_client_fill_super(ll_fill_super);
171 lustre_register_kill_super_cb(ll_kill_super);
172 lustre_register_client_process_config(ll_process_config);
173
174 return 0;
175
176out_vvp:
177 vvp_global_fini();
178out_capa:
179 del_timer(&ll_capa_timer);
180 ll_capa_thread_stop();
181out_proc:
182 lprocfs_remove(&proc_lustre_fs_root);
183out_cache:
184 if (ll_inode_cachep != NULL)
185 kmem_cache_destroy(ll_inode_cachep);
186
187 if (ll_file_data_slab != NULL)
188 kmem_cache_destroy(ll_file_data_slab);
189
190 if (ll_remote_perm_cachep != NULL)
191 kmem_cache_destroy(ll_remote_perm_cachep);
192
193 if (ll_rmtperm_hash_cachep != NULL)
194 kmem_cache_destroy(ll_rmtperm_hash_cachep);
188 195
189 return rc; 196 return rc;
190} 197}
191 198
192static void __exit exit_lustre_lite(void) 199static void __exit exit_lustre_lite(void)
193{ 200{
201 lustre_register_client_fill_super(NULL);
202 lustre_register_kill_super_cb(NULL);
203 lustre_register_client_process_config(NULL);
204
205 lprocfs_remove(&proc_lustre_fs_root);
206
194 ll_xattr_fini(); 207 ll_xattr_fini();
195 vvp_global_fini(); 208 vvp_global_fini();
196 del_timer(&ll_capa_timer); 209 del_timer(&ll_capa_timer);
@@ -199,22 +212,12 @@ static void __exit exit_lustre_lite(void)
199 "client remaining capa count %d\n", 212 "client remaining capa count %d\n",
200 capa_count[CAPA_SITE_CLIENT]); 213 capa_count[CAPA_SITE_CLIENT]);
201 214
202 lustre_register_client_fill_super(NULL); 215 kmem_cache_destroy(ll_inode_cachep);
203 lustre_register_kill_super_cb(NULL);
204
205 lustre_register_client_process_config(NULL);
206
207 ll_destroy_inodecache();
208
209 kmem_cache_destroy(ll_rmtperm_hash_cachep); 216 kmem_cache_destroy(ll_rmtperm_hash_cachep);
210 ll_rmtperm_hash_cachep = NULL;
211 217
212 kmem_cache_destroy(ll_remote_perm_cachep); 218 kmem_cache_destroy(ll_remote_perm_cachep);
213 ll_remote_perm_cachep = NULL;
214 219
215 kmem_cache_destroy(ll_file_data_slab); 220 kmem_cache_destroy(ll_file_data_slab);
216 if (proc_lustre_fs_root && !IS_ERR(proc_lustre_fs_root))
217 lprocfs_remove(&proc_lustre_fs_root);
218} 221}
219 222
220MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>"); 223MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index 65d610abe06e..91bba79678cf 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -307,18 +307,13 @@ static int vvp_io_rw_lock(const struct lu_env *env, struct cl_io *io,
307static int vvp_io_read_lock(const struct lu_env *env, 307static int vvp_io_read_lock(const struct lu_env *env,
308 const struct cl_io_slice *ios) 308 const struct cl_io_slice *ios)
309{ 309{
310 struct cl_io *io = ios->cis_io; 310 struct cl_io *io = ios->cis_io;
311 struct ll_inode_info *lli = ll_i2info(ccc_object_inode(io->ci_obj)); 311 struct cl_io_rw_common *rd = &io->u.ci_rd.rd;
312 int result; 312 int result;
313 313
314 /* XXX: Layer violation, we shouldn't see lsm at llite level. */ 314 result = vvp_io_rw_lock(env, io, CLM_READ, rd->crw_pos,
315 if (lli->lli_has_smd) /* lsm-less file doesn't need to lock */ 315 rd->crw_pos + rd->crw_count - 1);
316 result = vvp_io_rw_lock(env, io, CLM_READ, 316
317 io->u.ci_rd.rd.crw_pos,
318 io->u.ci_rd.rd.crw_pos +
319 io->u.ci_rd.rd.crw_count - 1);
320 else
321 result = 0;
322 return result; 317 return result;
323} 318}
324 319
diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c
index 372633e164b9..f354e82d4ae7 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_lock.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c
@@ -71,6 +71,7 @@ static const struct cl_lock_operations vvp_lock_ops = {
71 .clo_fini = ccc_lock_fini, 71 .clo_fini = ccc_lock_fini,
72 .clo_enqueue = ccc_lock_enqueue, 72 .clo_enqueue = ccc_lock_enqueue,
73 .clo_wait = ccc_lock_wait, 73 .clo_wait = ccc_lock_wait,
74 .clo_use = ccc_lock_use,
74 .clo_unuse = ccc_lock_unuse, 75 .clo_unuse = ccc_lock_unuse,
75 .clo_fits_into = ccc_lock_fits_into, 76 .clo_fits_into = ccc_lock_fits_into,
76 .clo_state = ccc_lock_state, 77 .clo_state = ccc_lock_state,
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 9f3837412cdf..b779f47384c5 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -128,7 +128,7 @@ static int lmv_set_mdc_active(struct lmv_obd *lmv, struct obd_uuid *uuid,
128 return rc; 128 return rc;
129} 129}
130 130
131struct obd_uuid *lmv_get_uuid(struct obd_export *exp) 131static struct obd_uuid *lmv_get_uuid(struct obd_export *exp)
132{ 132{
133 struct lmv_obd *lmv = &exp->exp_obd->u.lmv; 133 struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
134 134
@@ -335,7 +335,7 @@ static int lmv_init_ea_size(struct obd_export *exp, int easize,
335 335
336#define MAX_STRING_SIZE 128 336#define MAX_STRING_SIZE 128
337 337
338int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) 338static int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
339{ 339{
340 struct proc_dir_entry *lmv_proc_dir; 340 struct proc_dir_entry *lmv_proc_dir;
341 struct lmv_obd *lmv = &obd->u.lmv; 341 struct lmv_obd *lmv = &obd->u.lmv;
@@ -1663,10 +1663,10 @@ struct lmv_tgt_desc
1663 return tgt; 1663 return tgt;
1664} 1664}
1665 1665
1666int lmv_create(struct obd_export *exp, struct md_op_data *op_data, 1666static int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
1667 const void *data, int datalen, int mode, __u32 uid, 1667 const void *data, int datalen, int mode, __u32 uid,
1668 __u32 gid, cfs_cap_t cap_effective, __u64 rdev, 1668 __u32 gid, cfs_cap_t cap_effective, __u64 rdev,
1669 struct ptlrpc_request **request) 1669 struct ptlrpc_request **request)
1670{ 1670{
1671 struct obd_device *obd = exp->exp_obd; 1671 struct obd_device *obd = exp->exp_obd;
1672 struct lmv_obd *lmv = &obd->u.lmv; 1672 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2387,9 +2387,9 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
2387 return -EINVAL; 2387 return -EINVAL;
2388} 2388}
2389 2389
2390int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp, 2390static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
2391 u32 keylen, void *key, u32 vallen, 2391 u32 keylen, void *key, u32 vallen,
2392 void *val, struct ptlrpc_request_set *set) 2392 void *val, struct ptlrpc_request_set *set)
2393{ 2393{
2394 struct lmv_tgt_desc *tgt; 2394 struct lmv_tgt_desc *tgt;
2395 struct obd_device *obd; 2395 struct obd_device *obd;
@@ -2425,8 +2425,8 @@ int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
2425 return -EINVAL; 2425 return -EINVAL;
2426} 2426}
2427 2427
2428int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, 2428static int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
2429 struct lov_stripe_md *lsm) 2429 struct lov_stripe_md *lsm)
2430{ 2430{
2431 struct obd_device *obd = class_exp2obd(exp); 2431 struct obd_device *obd = class_exp2obd(exp);
2432 struct lmv_obd *lmv = &obd->u.lmv; 2432 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2473,8 +2473,8 @@ int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
2473 return mea_size; 2473 return mea_size;
2474} 2474}
2475 2475
2476int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, 2476static int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
2477 struct lov_mds_md *lmm, int lmm_size) 2477 struct lov_mds_md *lmm, int lmm_size)
2478{ 2478{
2479 struct obd_device *obd = class_exp2obd(exp); 2479 struct obd_device *obd = class_exp2obd(exp);
2480 struct lmv_stripe_md **tmea = (struct lmv_stripe_md **)lsmp; 2480 struct lmv_stripe_md **tmea = (struct lmv_stripe_md **)lsmp;
@@ -2551,8 +2551,8 @@ static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid,
2551 return rc; 2551 return rc;
2552} 2552}
2553 2553
2554int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, 2554static int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
2555 __u64 *bits) 2555 __u64 *bits)
2556{ 2556{
2557 struct lmv_obd *lmv = &exp->exp_obd->u.lmv; 2557 struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
2558 int rc; 2558 int rc;
@@ -2561,10 +2561,10 @@ int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
2561 return rc; 2561 return rc;
2562} 2562}
2563 2563
2564ldlm_mode_t lmv_lock_match(struct obd_export *exp, __u64 flags, 2564static ldlm_mode_t lmv_lock_match(struct obd_export *exp, __u64 flags,
2565 const struct lu_fid *fid, ldlm_type_t type, 2565 const struct lu_fid *fid, ldlm_type_t type,
2566 ldlm_policy_data_t *policy, ldlm_mode_t mode, 2566 ldlm_policy_data_t *policy, ldlm_mode_t mode,
2567 struct lustre_handle *lockh) 2567 struct lustre_handle *lockh)
2568{ 2568{
2569 struct obd_device *obd = exp->exp_obd; 2569 struct obd_device *obd = exp->exp_obd;
2570 struct lmv_obd *lmv = &obd->u.lmv; 2570 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2594,16 +2594,18 @@ ldlm_mode_t lmv_lock_match(struct obd_export *exp, __u64 flags,
2594 return 0; 2594 return 0;
2595} 2595}
2596 2596
2597int lmv_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, 2597static int lmv_get_lustre_md(struct obd_export *exp,
2598 struct obd_export *dt_exp, struct obd_export *md_exp, 2598 struct ptlrpc_request *req,
2599 struct lustre_md *md) 2599 struct obd_export *dt_exp,
2600 struct obd_export *md_exp,
2601 struct lustre_md *md)
2600{ 2602{
2601 struct lmv_obd *lmv = &exp->exp_obd->u.lmv; 2603 struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
2602 2604
2603 return md_get_lustre_md(lmv->tgts[0]->ltd_exp, req, dt_exp, md_exp, md); 2605 return md_get_lustre_md(lmv->tgts[0]->ltd_exp, req, dt_exp, md_exp, md);
2604} 2606}
2605 2607
2606int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md) 2608static int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
2607{ 2609{
2608 struct obd_device *obd = exp->exp_obd; 2610 struct obd_device *obd = exp->exp_obd;
2609 struct lmv_obd *lmv = &obd->u.lmv; 2611 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2613,9 +2615,9 @@ int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
2613 return md_free_lustre_md(lmv->tgts[0]->ltd_exp, md); 2615 return md_free_lustre_md(lmv->tgts[0]->ltd_exp, md);
2614} 2616}
2615 2617
2616int lmv_set_open_replay_data(struct obd_export *exp, 2618static int lmv_set_open_replay_data(struct obd_export *exp,
2617 struct obd_client_handle *och, 2619 struct obd_client_handle *och,
2618 struct lookup_intent *it) 2620 struct lookup_intent *it)
2619{ 2621{
2620 struct obd_device *obd = exp->exp_obd; 2622 struct obd_device *obd = exp->exp_obd;
2621 struct lmv_obd *lmv = &obd->u.lmv; 2623 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2628,8 +2630,8 @@ int lmv_set_open_replay_data(struct obd_export *exp,
2628 return md_set_open_replay_data(tgt->ltd_exp, och, it); 2630 return md_set_open_replay_data(tgt->ltd_exp, och, it);
2629} 2631}
2630 2632
2631int lmv_clear_open_replay_data(struct obd_export *exp, 2633static int lmv_clear_open_replay_data(struct obd_export *exp,
2632 struct obd_client_handle *och) 2634 struct obd_client_handle *och)
2633{ 2635{
2634 struct obd_device *obd = exp->exp_obd; 2636 struct obd_device *obd = exp->exp_obd;
2635 struct lmv_obd *lmv = &obd->u.lmv; 2637 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2684,17 +2686,18 @@ static int lmv_renew_capa(struct obd_export *exp, struct obd_capa *oc,
2684 return rc; 2686 return rc;
2685} 2687}
2686 2688
2687int lmv_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req, 2689static int lmv_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req,
2688 const struct req_msg_field *field, struct obd_capa **oc) 2690 const struct req_msg_field *field,
2691 struct obd_capa **oc)
2689{ 2692{
2690 struct lmv_obd *lmv = &exp->exp_obd->u.lmv; 2693 struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
2691 2694
2692 return md_unpack_capa(lmv->tgts[0]->ltd_exp, req, field, oc); 2695 return md_unpack_capa(lmv->tgts[0]->ltd_exp, req, field, oc);
2693} 2696}
2694 2697
2695int lmv_intent_getattr_async(struct obd_export *exp, 2698static int lmv_intent_getattr_async(struct obd_export *exp,
2696 struct md_enqueue_info *minfo, 2699 struct md_enqueue_info *minfo,
2697 struct ldlm_enqueue_info *einfo) 2700 struct ldlm_enqueue_info *einfo)
2698{ 2701{
2699 struct md_op_data *op_data = &minfo->mi_data; 2702 struct md_op_data *op_data = &minfo->mi_data;
2700 struct obd_device *obd = exp->exp_obd; 2703 struct obd_device *obd = exp->exp_obd;
@@ -2714,8 +2717,8 @@ int lmv_intent_getattr_async(struct obd_export *exp,
2714 return rc; 2717 return rc;
2715} 2718}
2716 2719
2717int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, 2720static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
2718 struct lu_fid *fid, __u64 *bits) 2721 struct lu_fid *fid, __u64 *bits)
2719{ 2722{
2720 struct obd_device *obd = exp->exp_obd; 2723 struct obd_device *obd = exp->exp_obd;
2721 struct lmv_obd *lmv = &obd->u.lmv; 2724 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2739,8 +2742,8 @@ int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
2739 * process with other slave MDTs. The only exception is Q_GETOQUOTA for which 2742 * process with other slave MDTs. The only exception is Q_GETOQUOTA for which
2740 * we directly fetch data from the slave MDTs. 2743 * we directly fetch data from the slave MDTs.
2741 */ 2744 */
2742int lmv_quotactl(struct obd_device *unused, struct obd_export *exp, 2745static int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
2743 struct obd_quotactl *oqctl) 2746 struct obd_quotactl *oqctl)
2744{ 2747{
2745 struct obd_device *obd = class_exp2obd(exp); 2748 struct obd_device *obd = class_exp2obd(exp);
2746 struct lmv_obd *lmv = &obd->u.lmv; 2749 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2786,8 +2789,8 @@ int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
2786 return rc; 2789 return rc;
2787} 2790}
2788 2791
2789int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp, 2792static int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
2790 struct obd_quotactl *oqctl) 2793 struct obd_quotactl *oqctl)
2791{ 2794{
2792 struct obd_device *obd = class_exp2obd(exp); 2795 struct obd_device *obd = class_exp2obd(exp);
2793 struct lmv_obd *lmv = &obd->u.lmv; 2796 struct lmv_obd *lmv = &obd->u.lmv;
@@ -2810,7 +2813,7 @@ int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
2810 return rc; 2813 return rc;
2811} 2814}
2812 2815
2813struct obd_ops lmv_obd_ops = { 2816static struct obd_ops lmv_obd_ops = {
2814 .o_owner = THIS_MODULE, 2817 .o_owner = THIS_MODULE,
2815 .o_setup = lmv_setup, 2818 .o_setup = lmv_setup,
2816 .o_cleanup = lmv_cleanup, 2819 .o_cleanup = lmv_cleanup,
@@ -2830,7 +2833,7 @@ struct obd_ops lmv_obd_ops = {
2830 .o_quotactl = lmv_quotactl 2833 .o_quotactl = lmv_quotactl
2831}; 2834};
2832 2835
2833struct md_ops lmv_md_ops = { 2836static struct md_ops lmv_md_ops = {
2834 .m_getstatus = lmv_getstatus, 2837 .m_getstatus = lmv_getstatus,
2835 .m_null_inode = lmv_null_inode, 2838 .m_null_inode = lmv_null_inode,
2836 .m_find_cbdata = lmv_find_cbdata, 2839 .m_find_cbdata = lmv_find_cbdata,
@@ -2864,7 +2867,7 @@ struct md_ops lmv_md_ops = {
2864 .m_revalidate_lock = lmv_revalidate_lock 2867 .m_revalidate_lock = lmv_revalidate_lock
2865}; 2868};
2866 2869
2867int __init lmv_init(void) 2870static int __init lmv_init(void)
2868{ 2871{
2869 struct lprocfs_static_vars lvars; 2872 struct lprocfs_static_vars lvars;
2870 int rc; 2873 int rc;
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index 117002097b28..5be4176829d3 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -175,7 +175,7 @@ static int lmv_tgt_seq_show(struct seq_file *p, void *v)
175 tgt->ltd_uuid.uuid, tgt->ltd_active ? "" : "IN"); 175 tgt->ltd_uuid.uuid, tgt->ltd_active ? "" : "IN");
176} 176}
177 177
178struct seq_operations lmv_tgt_sops = { 178static struct seq_operations lmv_tgt_sops = {
179 .start = lmv_tgt_seq_start, 179 .start = lmv_tgt_seq_start,
180 .stop = lmv_tgt_seq_stop, 180 .stop = lmv_tgt_seq_stop,
181 .next = lmv_tgt_seq_next, 181 .next = lmv_tgt_seq_next,
@@ -199,7 +199,7 @@ static int lmv_target_seq_open(struct inode *inode, struct file *file)
199 199
200LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid); 200LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid);
201 201
202struct lprocfs_vars lprocfs_lmv_obd_vars[] = { 202static struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
203 { "numobd", &lmv_numobd_fops, NULL, 0 }, 203 { "numobd", &lmv_numobd_fops, NULL, 0 },
204 { "placement", &lmv_placement_fops, NULL, 0 }, 204 { "placement", &lmv_placement_fops, NULL, 0 },
205 { "activeobd", &lmv_activeobd_fops, NULL, 0 }, 205 { "activeobd", &lmv_activeobd_fops, NULL, 0 },
diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c
index c993f25fb303..c99f2f44ec62 100644
--- a/drivers/staging/lustre/lustre/lov/lproc_lov.c
+++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c
@@ -51,8 +51,9 @@ static int lov_stripesize_seq_show(struct seq_file *m, void *v)
51 return seq_printf(m, "%llu\n", desc->ld_default_stripe_size); 51 return seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
52} 52}
53 53
54static ssize_t lov_stripesize_seq_write(struct file *file, const char *buffer, 54static ssize_t lov_stripesize_seq_write(struct file *file,
55 size_t count, loff_t *off) 55 const char __user *buffer,
56 size_t count, loff_t *off)
56{ 57{
57 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 58 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
58 struct lov_desc *desc; 59 struct lov_desc *desc;
@@ -81,8 +82,9 @@ static int lov_stripeoffset_seq_show(struct seq_file *m, void *v)
81 return seq_printf(m, "%llu\n", desc->ld_default_stripe_offset); 82 return seq_printf(m, "%llu\n", desc->ld_default_stripe_offset);
82} 83}
83 84
84static ssize_t lov_stripeoffset_seq_write(struct file *file, const char *buffer, 85static ssize_t lov_stripeoffset_seq_write(struct file *file,
85 size_t count, loff_t *off) 86 const char __user *buffer,
87 size_t count, loff_t *off)
86{ 88{
87 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 89 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
88 struct lov_desc *desc; 90 struct lov_desc *desc;
@@ -110,8 +112,9 @@ static int lov_stripetype_seq_show(struct seq_file *m, void *v)
110 return seq_printf(m, "%u\n", desc->ld_pattern); 112 return seq_printf(m, "%u\n", desc->ld_pattern);
111} 113}
112 114
113static ssize_t lov_stripetype_seq_write(struct file *file, const char *buffer, 115static ssize_t lov_stripetype_seq_write(struct file *file,
114 size_t count, loff_t *off) 116 const char __user *buffer,
117 size_t count, loff_t *off)
115{ 118{
116 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 119 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
117 struct lov_desc *desc; 120 struct lov_desc *desc;
@@ -140,8 +143,9 @@ static int lov_stripecount_seq_show(struct seq_file *m, void *v)
140 (__s16)(desc->ld_default_stripe_count + 1) - 1); 143 (__s16)(desc->ld_default_stripe_count + 1) - 1);
141} 144}
142 145
143static ssize_t lov_stripecount_seq_write(struct file *file, const char *buffer, 146static ssize_t lov_stripecount_seq_write(struct file *file,
144 size_t count, loff_t *off) 147 const char __user *buffer,
148 size_t count, loff_t *off)
145{ 149{
146 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 150 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
147 struct lov_desc *desc; 151 struct lov_desc *desc;
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index 16341c818358..c791941bd810 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -52,7 +52,7 @@ static int mdc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
52} 52}
53 53
54static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file, 54static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file,
55 const char *buffer, 55 const char __user *buffer,
56 size_t count, 56 size_t count,
57 loff_t *off) 57 loff_t *off)
58{ 58{
@@ -82,8 +82,9 @@ static int mdc_kuc_open(struct inode *inode, struct file *file)
82} 82}
83 83
84/* temporary for testing */ 84/* temporary for testing */
85static ssize_t mdc_kuc_write(struct file *file, const char *buffer, 85static ssize_t mdc_kuc_write(struct file *file,
86 size_t count, loff_t *off) 86 const char __user *buffer,
87 size_t count, loff_t *off)
87{ 88{
88 struct obd_device *obd = 89 struct obd_device *obd =
89 ((struct seq_file *)file->private_data)->private; 90 ((struct seq_file *)file->private_data)->private;
@@ -105,6 +106,8 @@ static ssize_t mdc_kuc_write(struct file *file, const char *buffer,
105 /* for mockup below */ 2 * cfs_size_round(sizeof(*hai)); 106 /* for mockup below */ 2 * cfs_size_round(sizeof(*hai));
106 107
107 OBD_ALLOC(lh, len); 108 OBD_ALLOC(lh, len);
109 if (!lh)
110 return -ENOMEM;
108 111
109 lh->kuc_magic = KUC_MAGIC; 112 lh->kuc_magic = KUC_MAGIC;
110 lh->kuc_transport = KUC_TRANSPORT_HSM; 113 lh->kuc_transport = KUC_TRANSPORT_HSM;
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
index 4e59995e0042..d3234cb1ea22 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
@@ -222,10 +222,9 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
222 rec->cr_fsuid = from_kuid(&init_user_ns, current_fsuid()); 222 rec->cr_fsuid = from_kuid(&init_user_ns, current_fsuid());
223 rec->cr_fsgid = from_kgid(&init_user_ns, current_fsgid()); 223 rec->cr_fsgid = from_kgid(&init_user_ns, current_fsgid());
224 rec->cr_cap = cfs_curproc_cap_pack(); 224 rec->cr_cap = cfs_curproc_cap_pack();
225 if (op_data != NULL) { 225 rec->cr_fid1 = op_data->op_fid1;
226 rec->cr_fid1 = op_data->op_fid1; 226 rec->cr_fid2 = op_data->op_fid2;
227 rec->cr_fid2 = op_data->op_fid2; 227
228 }
229 rec->cr_mode = mode; 228 rec->cr_mode = mode;
230 cr_flags = mds_pack_open_flags(flags, mode); 229 cr_flags = mds_pack_open_flags(flags, mode);
231 rec->cr_rdev = rdev; 230 rec->cr_rdev = rdev;
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
index 8c9b4f5494e9..d1c224ecd2b7 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
@@ -828,6 +828,7 @@ resend:
828 einfo->ei_type); 828 einfo->ei_type);
829 policy = (ldlm_policy_data_t *)lmm; 829 policy = (ldlm_policy_data_t *)lmm;
830 res_id.name[3] = LDLM_FLOCK; 830 res_id.name[3] = LDLM_FLOCK;
831 req = NULL;
831 } else if (it->it_op & IT_OPEN) { 832 } else if (it->it_op & IT_OPEN) {
832 req = mdc_intent_open_pack(exp, it, op_data, lmm, lmmsize, 833 req = mdc_intent_open_pack(exp, it, op_data, lmm, lmmsize,
833 einfo->ei_cbdata); 834 einfo->ei_cbdata);
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 3b0f245a8780..ef2744700d8b 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -855,8 +855,8 @@ static void mdc_close_handle_reply(struct ptlrpc_request *req,
855 } 855 }
856} 856}
857 857
858int mdc_close(struct obd_export *exp, struct md_op_data *op_data, 858static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
859 struct md_open_data *mod, struct ptlrpc_request **request) 859 struct md_open_data *mod, struct ptlrpc_request **request)
860{ 860{
861 struct obd_device *obd = class_exp2obd(exp); 861 struct obd_device *obd = class_exp2obd(exp);
862 struct ptlrpc_request *req; 862 struct ptlrpc_request *req;
@@ -974,8 +974,8 @@ int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
974 return rc < 0 ? rc : saved_rc; 974 return rc < 0 ? rc : saved_rc;
975} 975}
976 976
977int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data, 977static int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
978 struct md_open_data *mod) 978 struct md_open_data *mod)
979{ 979{
980 struct obd_device *obd = class_exp2obd(exp); 980 struct obd_device *obd = class_exp2obd(exp);
981 struct ptlrpc_request *req; 981 struct ptlrpc_request *req;
@@ -1044,8 +1044,8 @@ int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
1044} 1044}
1045 1045
1046 1046
1047int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data, 1047static int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data,
1048 struct page **pages, struct ptlrpc_request **request) 1048 struct page **pages, struct ptlrpc_request **request)
1049{ 1049{
1050 struct ptlrpc_request *req; 1050 struct ptlrpc_request *req;
1051 struct ptlrpc_bulk_desc *desc; 1051 struct ptlrpc_bulk_desc *desc;
@@ -1908,8 +1908,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
1908 1908
1909 /* copy UUID */ 1909 /* copy UUID */
1910 if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(obd), 1910 if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(obd),
1911 min((int) data->ioc_plen2, 1911 min_t(size_t, data->ioc_plen2,
1912 (int) sizeof(struct obd_uuid)))) { 1912 sizeof(struct obd_uuid)))) {
1913 rc = -EFAULT; 1913 rc = -EFAULT;
1914 goto out; 1914 goto out;
1915 } 1915 }
@@ -1921,8 +1921,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
1921 goto out; 1921 goto out;
1922 1922
1923 if (copy_to_user(data->ioc_pbuf1, &stat_buf, 1923 if (copy_to_user(data->ioc_pbuf1, &stat_buf,
1924 min((int) data->ioc_plen1, 1924 min_t(size_t, data->ioc_plen1,
1925 (int) sizeof(stat_buf)))) { 1925 sizeof(stat_buf)))) {
1926 rc = -EFAULT; 1926 rc = -EFAULT;
1927 goto out; 1927 goto out;
1928 } 1928 }
@@ -1974,9 +1974,9 @@ out:
1974 return rc; 1974 return rc;
1975} 1975}
1976 1976
1977int mdc_get_info_rpc(struct obd_export *exp, 1977static int mdc_get_info_rpc(struct obd_export *exp,
1978 u32 keylen, void *key, 1978 u32 keylen, void *key,
1979 int vallen, void *val) 1979 int vallen, void *val)
1980{ 1980{
1981 struct obd_import *imp = class_exp2cliimp(exp); 1981 struct obd_import *imp = class_exp2cliimp(exp);
1982 struct ptlrpc_request *req; 1982 struct ptlrpc_request *req;
@@ -2148,11 +2148,11 @@ static int mdc_kuc_reregister(struct obd_import *imp)
2148 (void *)imp); 2148 (void *)imp);
2149} 2149}
2150 2150
2151int mdc_set_info_async(const struct lu_env *env, 2151static int mdc_set_info_async(const struct lu_env *env,
2152 struct obd_export *exp, 2152 struct obd_export *exp,
2153 u32 keylen, void *key, 2153 u32 keylen, void *key,
2154 u32 vallen, void *val, 2154 u32 vallen, void *val,
2155 struct ptlrpc_request_set *set) 2155 struct ptlrpc_request_set *set)
2156{ 2156{
2157 struct obd_import *imp = class_exp2cliimp(exp); 2157 struct obd_import *imp = class_exp2cliimp(exp);
2158 int rc; 2158 int rc;
@@ -2199,9 +2199,9 @@ int mdc_set_info_async(const struct lu_env *env,
2199 return -EINVAL; 2199 return -EINVAL;
2200} 2200}
2201 2201
2202int mdc_get_info(const struct lu_env *env, struct obd_export *exp, 2202static int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
2203 __u32 keylen, void *key, __u32 *vallen, void *val, 2203 __u32 keylen, void *key, __u32 *vallen, void *val,
2204 struct lov_stripe_md *lsm) 2204 struct lov_stripe_md *lsm)
2205{ 2205{
2206 int rc = -EINVAL; 2206 int rc = -EINVAL;
2207 2207
@@ -2263,8 +2263,8 @@ int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
2263 return rc; 2263 return rc;
2264} 2264}
2265 2265
2266int mdc_sync(struct obd_export *exp, const struct lu_fid *fid, 2266static int mdc_sync(struct obd_export *exp, const struct lu_fid *fid,
2267 struct obd_capa *oc, struct ptlrpc_request **request) 2267 struct obd_capa *oc, struct ptlrpc_request **request)
2268{ 2268{
2269 struct ptlrpc_request *req; 2269 struct ptlrpc_request *req;
2270 int rc; 2270 int rc;
@@ -2356,7 +2356,7 @@ int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
2356 return seq_client_alloc_fid(NULL, seq, fid); 2356 return seq_client_alloc_fid(NULL, seq, fid);
2357} 2357}
2358 2358
2359struct obd_uuid *mdc_get_uuid(struct obd_export *exp) 2359static struct obd_uuid *mdc_get_uuid(struct obd_export *exp)
2360{ 2360{
2361 struct client_obd *cli = &exp->exp_obd->u.cli; 2361 struct client_obd *cli = &exp->exp_obd->u.cli;
2362 2362
@@ -2390,7 +2390,7 @@ static int mdc_resource_inode_free(struct ldlm_resource *res)
2390 return 0; 2390 return 0;
2391} 2391}
2392 2392
2393struct ldlm_valblock_ops inode_lvbo = { 2393static struct ldlm_valblock_ops inode_lvbo = {
2394 .lvbo_free = mdc_resource_inode_free, 2394 .lvbo_free = mdc_resource_inode_free,
2395}; 2395};
2396 2396
@@ -2550,9 +2550,9 @@ static int mdc_process_config(struct obd_device *obd, u32 len, void *buf)
2550 2550
2551 2551
2552/* get remote permission for current user on fid */ 2552/* get remote permission for current user on fid */
2553int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid, 2553static int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid,
2554 struct obd_capa *oc, __u32 suppgid, 2554 struct obd_capa *oc, __u32 suppgid,
2555 struct ptlrpc_request **request) 2555 struct ptlrpc_request **request)
2556{ 2556{
2557 struct ptlrpc_request *req; 2557 struct ptlrpc_request *req;
2558 int rc; 2558 int rc;
@@ -2647,7 +2647,7 @@ static int mdc_renew_capa(struct obd_export *exp, struct obd_capa *oc,
2647 return 0; 2647 return 0;
2648} 2648}
2649 2649
2650struct obd_ops mdc_obd_ops = { 2650static struct obd_ops mdc_obd_ops = {
2651 .o_owner = THIS_MODULE, 2651 .o_owner = THIS_MODULE,
2652 .o_setup = mdc_setup, 2652 .o_setup = mdc_setup,
2653 .o_precleanup = mdc_precleanup, 2653 .o_precleanup = mdc_precleanup,
@@ -2670,7 +2670,7 @@ struct obd_ops mdc_obd_ops = {
2670 .o_quotacheck = mdc_quotacheck 2670 .o_quotacheck = mdc_quotacheck
2671}; 2671};
2672 2672
2673struct md_ops mdc_md_ops = { 2673static struct md_ops mdc_md_ops = {
2674 .m_getstatus = mdc_getstatus, 2674 .m_getstatus = mdc_getstatus,
2675 .m_null_inode = mdc_null_inode, 2675 .m_null_inode = mdc_null_inode,
2676 .m_find_cbdata = mdc_find_cbdata, 2676 .m_find_cbdata = mdc_find_cbdata,
@@ -2705,7 +2705,7 @@ struct md_ops mdc_md_ops = {
2705 .m_revalidate_lock = mdc_revalidate_lock 2705 .m_revalidate_lock = mdc_revalidate_lock
2706}; 2706};
2707 2707
2708int __init mdc_init(void) 2708static int __init mdc_init(void)
2709{ 2709{
2710 int rc; 2710 int rc;
2711 struct lprocfs_static_vars lvars = { NULL }; 2711 struct lprocfs_static_vars lvars = { NULL };
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index ce96bd279111..f13d1fbffd9d 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -193,6 +193,7 @@ static spinlock_t *cl_object_attr_guard(struct cl_object *o)
193 * cl_object_attr_get(), cl_object_attr_set(). 193 * cl_object_attr_get(), cl_object_attr_set().
194 */ 194 */
195void cl_object_attr_lock(struct cl_object *o) 195void cl_object_attr_lock(struct cl_object *o)
196 __acquires(cl_object_attr_guard(o))
196{ 197{
197 spin_lock(cl_object_attr_guard(o)); 198 spin_lock(cl_object_attr_guard(o));
198} 199}
@@ -202,6 +203,7 @@ EXPORT_SYMBOL(cl_object_attr_lock);
202 * Releases data-attributes lock, acquired by cl_object_attr_lock(). 203 * Releases data-attributes lock, acquired by cl_object_attr_lock().
203 */ 204 */
204void cl_object_attr_unlock(struct cl_object *o) 205void cl_object_attr_unlock(struct cl_object *o)
206 __releases(cl_object_attr_guard(o))
205{ 207{
206 spin_unlock(cl_object_attr_guard(o)); 208 spin_unlock(cl_object_attr_guard(o));
207} 209}
@@ -662,7 +664,8 @@ static int cl_env_store_init(void) {
662 return cl_env_hash != NULL ? 0 :-ENOMEM; 664 return cl_env_hash != NULL ? 0 :-ENOMEM;
663} 665}
664 666
665static void cl_env_store_fini(void) { 667static void cl_env_store_fini(void)
668{
666 cfs_hash_putref(cl_env_hash); 669 cfs_hash_putref(cl_env_hash);
667} 670}
668 671
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 89a3fb2e56b2..29456e1ad225 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -61,7 +61,7 @@ __u64 obd_alloc;
61EXPORT_SYMBOL(obd_alloc); 61EXPORT_SYMBOL(obd_alloc);
62__u64 obd_pages; 62__u64 obd_pages;
63EXPORT_SYMBOL(obd_pages); 63EXPORT_SYMBOL(obd_pages);
64DEFINE_SPINLOCK(obd_updatemax_lock); 64static DEFINE_SPINLOCK(obd_updatemax_lock);
65 65
66/* The following are visible and mutable through /proc/sys/lustre/. */ 66/* The following are visible and mutable through /proc/sys/lustre/. */
67unsigned int obd_alloc_fail_rate = 0; 67unsigned int obd_alloc_fail_rate = 0;
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 736ca410aca3..82508210465e 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -1151,22 +1151,24 @@ void class_export_recovery_cleanup(struct obd_export *exp)
1151 exp->exp_obd->obd_stale_clients++; 1151 exp->exp_obd->obd_stale_clients++;
1152 } 1152 }
1153 spin_unlock(&obd->obd_recovery_task_lock); 1153 spin_unlock(&obd->obd_recovery_task_lock);
1154
1155 spin_lock(&exp->exp_lock);
1154 /** Cleanup req replay fields */ 1156 /** Cleanup req replay fields */
1155 if (exp->exp_req_replay_needed) { 1157 if (exp->exp_req_replay_needed) {
1156 spin_lock(&exp->exp_lock);
1157 exp->exp_req_replay_needed = 0; 1158 exp->exp_req_replay_needed = 0;
1158 spin_unlock(&exp->exp_lock); 1159
1159 LASSERT(atomic_read(&obd->obd_req_replay_clients)); 1160 LASSERT(atomic_read(&obd->obd_req_replay_clients));
1160 atomic_dec(&obd->obd_req_replay_clients); 1161 atomic_dec(&obd->obd_req_replay_clients);
1161 } 1162 }
1163
1162 /** Cleanup lock replay data */ 1164 /** Cleanup lock replay data */
1163 if (exp->exp_lock_replay_needed) { 1165 if (exp->exp_lock_replay_needed) {
1164 spin_lock(&exp->exp_lock);
1165 exp->exp_lock_replay_needed = 0; 1166 exp->exp_lock_replay_needed = 0;
1166 spin_unlock(&exp->exp_lock); 1167
1167 LASSERT(atomic_read(&obd->obd_lock_replay_clients)); 1168 LASSERT(atomic_read(&obd->obd_lock_replay_clients));
1168 atomic_dec(&obd->obd_lock_replay_clients); 1169 atomic_dec(&obd->obd_lock_replay_clients);
1169 } 1170 }
1171 spin_unlock(&exp->exp_lock);
1170} 1172}
1171 1173
1172/* This function removes 1-3 references from the export: 1174/* This function removes 1-3 references from the export:
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index 66ceab20c743..b94aeac18a37 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -83,9 +83,8 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
83 int err; 83 int err;
84 int offset = 0; 84 int offset = 0;
85 85
86 err = copy_from_user(&hdr, (void *)arg, sizeof(hdr)); 86 if (copy_from_user(&hdr, (void *)arg, sizeof(hdr)))
87 if (err) 87 return -EFAULT;
88 return err;
89 88
90 if (hdr.ioc_version != OBD_IOCTL_VERSION) { 89 if (hdr.ioc_version != OBD_IOCTL_VERSION) {
91 CERROR("Version mismatch kernel (%x) vs application (%x)\n", 90 CERROR("Version mismatch kernel (%x) vs application (%x)\n",
@@ -117,18 +116,19 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
117 *len = hdr.ioc_len; 116 *len = hdr.ioc_len;
118 data = (struct obd_ioctl_data *)*buf; 117 data = (struct obd_ioctl_data *)*buf;
119 118
120 err = copy_from_user(*buf, (void *)arg, hdr.ioc_len); 119 if (copy_from_user(*buf, (void *)arg, hdr.ioc_len)) {
121 if (err) { 120 err = -EFAULT;
122 OBD_FREE_LARGE(*buf, hdr.ioc_len); 121 goto free_buf;
123 return err; 122 }
123 if (hdr.ioc_len != data->ioc_len) {
124 err = -EINVAL;
125 goto free_buf;
124 } 126 }
125 if (hdr.ioc_len != data->ioc_len)
126 return -EINVAL;
127 127
128 if (obd_ioctl_is_invalid(data)) { 128 if (obd_ioctl_is_invalid(data)) {
129 CERROR("ioctl not correctly formatted\n"); 129 CERROR("ioctl not correctly formatted\n");
130 OBD_FREE_LARGE(*buf, hdr.ioc_len); 130 err = -EINVAL;
131 return -EINVAL; 131 goto free_buf;
132 } 132 }
133 133
134 if (data->ioc_inllen1) { 134 if (data->ioc_inllen1) {
@@ -151,6 +151,10 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
151 } 151 }
152 152
153 return 0; 153 return 0;
154
155free_buf:
156 OBD_FREE_LARGE(*buf, hdr.ioc_len);
157 return err;
154} 158}
155EXPORT_SYMBOL(obd_ioctl_getdata); 159EXPORT_SYMBOL(obd_ioctl_getdata);
156 160
@@ -272,8 +276,9 @@ static int obd_proc_jobid_var_seq_show(struct seq_file *m, void *v)
272 return seq_printf(m, "%s\n", obd_jobid_var); 276 return seq_printf(m, "%s\n", obd_jobid_var);
273} 277}
274 278
275static ssize_t obd_proc_jobid_var_seq_write(struct file *file, const char *buffer, 279static ssize_t obd_proc_jobid_var_seq_write(struct file *file,
276 size_t count, loff_t *off) 280 const char __user *buffer,
281 size_t count, loff_t *off)
277{ 282{
278 if (!count || count > JOBSTATS_JOBID_VAR_MAX_LEN) 283 if (!count || count > JOBSTATS_JOBID_VAR_MAX_LEN)
279 return -EINVAL; 284 return -EINVAL;
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
index d3ec90e85eb9..a2d5aa105d6b 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
@@ -168,7 +168,8 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
168 } 168 }
169 case CHANGELOG_REC: 169 case CHANGELOG_REC:
170 { 170 {
171 struct llog_changelog_rec *cr = (struct llog_changelog_rec *)rec; 171 struct llog_changelog_rec *cr =
172 (struct llog_changelog_rec *)rec;
172 173
173 __swab16s(&cr->cr.cr_namelen); 174 __swab16s(&cr->cr.cr_namelen);
174 __swab16s(&cr->cr.cr_flags); 175 __swab16s(&cr->cr.cr_flags);
@@ -188,6 +189,8 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
188 } else { 189 } else {
189 tail = &cr->cr_tail; 190 tail = &cr->cr_tail;
190 } 191 }
192 tail = (struct llog_rec_tail *)((char *)tail +
193 cr->cr.cr_namelen);
191 break; 194 break;
192 } 195 }
193 case CHANGELOG_USER_REC: 196 case CHANGELOG_USER_REC:
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index 3b7dfc367722..ddab94d7ee82 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -45,6 +45,7 @@
45#include "../include/lprocfs_status.h" 45#include "../include/lprocfs_status.h"
46#include "../include/lustre/lustre_idl.h" 46#include "../include/lustre/lustre_idl.h"
47#include <linux/seq_file.h> 47#include <linux/seq_file.h>
48#include <linux/ctype.h>
48 49
49static const char * const obd_connect_names[] = { 50static const char * const obd_connect_names[] = {
50 "read_only", 51 "read_only",
@@ -1849,7 +1850,7 @@ int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult)
1849} 1850}
1850EXPORT_SYMBOL(lprocfs_seq_read_frac_helper); 1851EXPORT_SYMBOL(lprocfs_seq_read_frac_helper);
1851 1852
1852int lprocfs_write_u64_helper(const char *buffer, unsigned long count, 1853int lprocfs_write_u64_helper(const char __user *buffer, unsigned long count,
1853 __u64 *val) 1854 __u64 *val)
1854{ 1855{
1855 return lprocfs_write_frac_u64_helper(buffer, count, val, 1); 1856 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
@@ -1862,6 +1863,7 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1862 char kernbuf[22], *end, *pbuf; 1863 char kernbuf[22], *end, *pbuf;
1863 __u64 whole, frac = 0, units; 1864 __u64 whole, frac = 0, units;
1864 unsigned frac_d = 1; 1865 unsigned frac_d = 1;
1866 int sign = 1;
1865 1867
1866 if (count > (sizeof(kernbuf) - 1)) 1868 if (count > (sizeof(kernbuf) - 1))
1867 return -EINVAL; 1869 return -EINVAL;
@@ -1872,7 +1874,7 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1872 kernbuf[count] = '\0'; 1874 kernbuf[count] = '\0';
1873 pbuf = kernbuf; 1875 pbuf = kernbuf;
1874 if (*pbuf == '-') { 1876 if (*pbuf == '-') {
1875 mult = -mult; 1877 sign = -1;
1876 pbuf++; 1878 pbuf++;
1877 } 1879 }
1878 1880
@@ -1880,7 +1882,7 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1880 if (pbuf == end) 1882 if (pbuf == end)
1881 return -EINVAL; 1883 return -EINVAL;
1882 1884
1883 if (end != NULL && *end == '.') { 1885 if (*end == '.') {
1884 int i; 1886 int i;
1885 pbuf = end + 1; 1887 pbuf = end + 1;
1886 1888
@@ -1895,25 +1897,25 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1895 } 1897 }
1896 1898
1897 units = 1; 1899 units = 1;
1898 switch (*end) { 1900 switch (tolower(*end)) {
1899 case 'p': case 'P': 1901 case 'p':
1900 units <<= 10; 1902 units <<= 10;
1901 case 't': case 'T': 1903 case 't':
1902 units <<= 10; 1904 units <<= 10;
1903 case 'g': case 'G': 1905 case 'g':
1904 units <<= 10; 1906 units <<= 10;
1905 case 'm': case 'M': 1907 case 'm':
1906 units <<= 10; 1908 units <<= 10;
1907 case 'k': case 'K': 1909 case 'k':
1908 units <<= 10; 1910 units <<= 10;
1909 } 1911 }
1910 /* Specified units override the multiplier */ 1912 /* Specified units override the multiplier */
1911 if (units) 1913 if (units > 1)
1912 mult = mult < 0 ? -units : units; 1914 mult = units;
1913 1915
1914 frac *= mult; 1916 frac *= mult;
1915 do_div(frac, frac_d); 1917 do_div(frac, frac_d);
1916 *val = whole * mult + frac; 1918 *val = sign * (whole * mult + frac);
1917 return 0; 1919 return 0;
1918} 1920}
1919EXPORT_SYMBOL(lprocfs_write_frac_u64_helper); 1921EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
index 4f39cdee1b5c..3c0c9109cefd 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
@@ -376,6 +376,11 @@ int lustre_start_mgc(struct super_block *sb)
376 376
377 /* Random uuid for MGC allows easier reconnects */ 377 /* Random uuid for MGC allows easier reconnects */
378 OBD_ALLOC_PTR(uuid); 378 OBD_ALLOC_PTR(uuid);
379 if (!uuid) {
380 rc = -ENOMEM;
381 goto out_free;
382 }
383
379 ll_generate_random_uuid(uuidc); 384 ll_generate_random_uuid(uuidc);
380 class_uuid_unparse(uuidc, uuid); 385 class_uuid_unparse(uuidc, uuid);
381 386
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 9f719bcecab3..1795d3a7a029 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -53,8 +53,9 @@ static int osc_active_seq_show(struct seq_file *m, void *v)
53 return rc; 53 return rc;
54} 54}
55 55
56static ssize_t osc_active_seq_write(struct file *file, const char *buffer, 56static ssize_t osc_active_seq_write(struct file *file,
57 size_t count, loff_t *off) 57 const char __user *buffer,
58 size_t count, loff_t *off)
58{ 59{
59 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 60 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
60 int val, rc; 61 int val, rc;
@@ -88,7 +89,8 @@ static int osc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
88} 89}
89 90
90static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file, 91static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file,
91 const char *buffer, size_t count, loff_t *off) 92 const char __user *buffer,
93 size_t count, loff_t *off)
92{ 94{
93 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 95 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
94 struct client_obd *cli = &dev->u.cli; 96 struct client_obd *cli = &dev->u.cli;
@@ -130,8 +132,9 @@ static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v)
130 return lprocfs_seq_read_frac_helper(m, val, mult); 132 return lprocfs_seq_read_frac_helper(m, val, mult);
131} 133}
132 134
133static ssize_t osc_max_dirty_mb_seq_write(struct file *file, const char *buffer, 135static ssize_t osc_max_dirty_mb_seq_write(struct file *file,
134 size_t count, loff_t *off) 136 const char __user *buffer,
137 size_t count, loff_t *off)
135{ 138{
136 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 139 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
137 struct client_obd *cli = &dev->u.cli; 140 struct client_obd *cli = &dev->u.cli;
@@ -233,8 +236,9 @@ static int osc_cur_grant_bytes_seq_show(struct seq_file *m, void *v)
233 return rc; 236 return rc;
234} 237}
235 238
236static ssize_t osc_cur_grant_bytes_seq_write(struct file *file, const char *buffer, 239static ssize_t osc_cur_grant_bytes_seq_write(struct file *file,
237 size_t count, loff_t *off) 240 const char __user *buffer,
241 size_t count, loff_t *off)
238{ 242{
239 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 243 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
240 struct client_obd *cli = &obd->u.cli; 244 struct client_obd *cli = &obd->u.cli;
@@ -290,7 +294,8 @@ static int osc_grant_shrink_interval_seq_show(struct seq_file *m, void *v)
290} 294}
291 295
292static ssize_t osc_grant_shrink_interval_seq_write(struct file *file, 296static ssize_t osc_grant_shrink_interval_seq_write(struct file *file,
293 const char *buffer, size_t count, loff_t *off) 297 const char __user *buffer,
298 size_t count, loff_t *off)
294{ 299{
295 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 300 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
296 int val, rc; 301 int val, rc;
@@ -322,8 +327,9 @@ static int osc_checksum_seq_show(struct seq_file *m, void *v)
322 obd->u.cli.cl_checksum ? 1 : 0); 327 obd->u.cli.cl_checksum ? 1 : 0);
323} 328}
324 329
325static ssize_t osc_checksum_seq_write(struct file *file, const char *buffer, 330static ssize_t osc_checksum_seq_write(struct file *file,
326 size_t count, loff_t *off) 331 const char __user *buffer,
332 size_t count, loff_t *off)
327{ 333{
328 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 334 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
329 int val, rc; 335 int val, rc;
@@ -358,11 +364,12 @@ static int osc_checksum_type_seq_show(struct seq_file *m, void *v)
358 else 364 else
359 seq_printf(m, "%s ", cksum_name[i]); 365 seq_printf(m, "%s ", cksum_name[i]);
360 } 366 }
361 seq_printf(m, "\n"); 367 seq_putc(m, '\n');
362 return 0; 368 return 0;
363} 369}
364 370
365static ssize_t osc_checksum_type_seq_write(struct file *file, const char *buffer, 371static ssize_t osc_checksum_type_seq_write(struct file *file,
372 const char __user *buffer,
366 size_t count, loff_t *off) 373 size_t count, loff_t *off)
367{ 374{
368 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 375 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -401,8 +408,9 @@ static int osc_resend_count_seq_show(struct seq_file *m, void *v)
401 return seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_resends)); 408 return seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_resends));
402} 409}
403 410
404static ssize_t osc_resend_count_seq_write(struct file *file, const char *buffer, 411static ssize_t osc_resend_count_seq_write(struct file *file,
405 size_t count, loff_t *off) 412 const char __user *buffer,
413 size_t count, loff_t *off)
406{ 414{
407 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 415 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
408 int val, rc; 416 int val, rc;
@@ -428,8 +436,9 @@ static int osc_contention_seconds_seq_show(struct seq_file *m, void *v)
428 return seq_printf(m, "%u\n", od->od_contention_time); 436 return seq_printf(m, "%u\n", od->od_contention_time);
429} 437}
430 438
431static ssize_t osc_contention_seconds_seq_write(struct file *file, const char *buffer, 439static ssize_t osc_contention_seconds_seq_write(struct file *file,
432 size_t count, loff_t *off) 440 const char __user *buffer,
441 size_t count, loff_t *off)
433{ 442{
434 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 443 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
435 struct osc_device *od = obd2osc_dev(obd); 444 struct osc_device *od = obd2osc_dev(obd);
@@ -447,8 +456,9 @@ static int osc_lockless_truncate_seq_show(struct seq_file *m, void *v)
447 return seq_printf(m, "%u\n", od->od_lockless_truncate); 456 return seq_printf(m, "%u\n", od->od_lockless_truncate);
448} 457}
449 458
450static ssize_t osc_lockless_truncate_seq_write(struct file *file, const char *buffer, 459static ssize_t osc_lockless_truncate_seq_write(struct file *file,
451 size_t count, loff_t *off) 460 const char __user *buffer,
461 size_t count, loff_t *off)
452{ 462{
453 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 463 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
454 struct osc_device *od = obd2osc_dev(obd); 464 struct osc_device *od = obd2osc_dev(obd);
@@ -472,7 +482,8 @@ static int osc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
472} 482}
473 483
474static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file, 484static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file,
475 const char *buffer, size_t count, loff_t *off) 485 const char __user *buffer,
486 size_t count, loff_t *off)
476{ 487{
477 struct obd_device *dev = ((struct seq_file *)file->private_data)->private; 488 struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
478 struct client_obd *cli = &dev->u.cli; 489 struct client_obd *cli = &dev->u.cli;
@@ -590,9 +601,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
590 seq_printf(seq, "pending read pages: %d\n", 601 seq_printf(seq, "pending read pages: %d\n",
591 atomic_read(&cli->cl_pending_r_pages)); 602 atomic_read(&cli->cl_pending_r_pages));
592 603
593 seq_printf(seq, "\n\t\t\tread\t\t\twrite\n"); 604 seq_puts(seq, "\n\t\t\tread\t\t\twrite\n");
594 seq_printf(seq, "pages per rpc rpcs %% cum %% |"); 605 seq_puts(seq, "pages per rpc rpcs % cum % |");
595 seq_printf(seq, " rpcs %% cum %%\n"); 606 seq_puts(seq, " rpcs % cum %\n");
596 607
597 read_tot = lprocfs_oh_sum(&cli->cl_read_page_hist); 608 read_tot = lprocfs_oh_sum(&cli->cl_read_page_hist);
598 write_tot = lprocfs_oh_sum(&cli->cl_write_page_hist); 609 write_tot = lprocfs_oh_sum(&cli->cl_write_page_hist);
@@ -613,9 +624,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
613 break; 624 break;
614 } 625 }
615 626
616 seq_printf(seq, "\n\t\t\tread\t\t\twrite\n"); 627 seq_puts(seq, "\n\t\t\tread\t\t\twrite\n");
617 seq_printf(seq, "rpcs in flight rpcs %% cum %% |"); 628 seq_puts(seq, "rpcs in flight rpcs % cum % |");
618 seq_printf(seq, " rpcs %% cum %%\n"); 629 seq_puts(seq, " rpcs % cum %\n");
619 630
620 read_tot = lprocfs_oh_sum(&cli->cl_read_rpc_hist); 631 read_tot = lprocfs_oh_sum(&cli->cl_read_rpc_hist);
621 write_tot = lprocfs_oh_sum(&cli->cl_write_rpc_hist); 632 write_tot = lprocfs_oh_sum(&cli->cl_write_rpc_hist);
@@ -636,9 +647,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
636 break; 647 break;
637 } 648 }
638 649
639 seq_printf(seq, "\n\t\t\tread\t\t\twrite\n"); 650 seq_puts(seq, "\n\t\t\tread\t\t\twrite\n");
640 seq_printf(seq, "offset rpcs %% cum %% |"); 651 seq_puts(seq, "offset rpcs % cum % |");
641 seq_printf(seq, " rpcs %% cum %%\n"); 652 seq_puts(seq, " rpcs % cum %\n");
642 653
643 read_tot = lprocfs_oh_sum(&cli->cl_read_offset_hist); 654 read_tot = lprocfs_oh_sum(&cli->cl_read_offset_hist);
644 write_tot = lprocfs_oh_sum(&cli->cl_write_offset_hist); 655 write_tot = lprocfs_oh_sum(&cli->cl_write_offset_hist);
@@ -664,8 +675,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
664} 675}
665#undef pct 676#undef pct
666 677
667static ssize_t osc_rpc_stats_seq_write(struct file *file, const char *buf, 678static ssize_t osc_rpc_stats_seq_write(struct file *file,
668 size_t len, loff_t *off) 679 const char __user *buf,
680 size_t len, loff_t *off)
669{ 681{
670 struct seq_file *seq = file->private_data; 682 struct seq_file *seq = file->private_data;
671 struct obd_device *dev = seq->private; 683 struct obd_device *dev = seq->private;
@@ -702,8 +714,9 @@ static int osc_stats_seq_show(struct seq_file *seq, void *v)
702 return 0; 714 return 0;
703} 715}
704 716
705static ssize_t osc_stats_seq_write(struct file *file, const char *buf, 717static ssize_t osc_stats_seq_write(struct file *file,
706 size_t len, loff_t *off) 718 const char __user *buf,
719 size_t len, loff_t *off)
707{ 720{
708 struct seq_file *seq = file->private_data; 721 struct seq_file *seq = file->private_data;
709 struct obd_device *dev = seq->private; 722 struct obd_device *dev = seq->private;
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 370e6d4896c6..7022ed42d2d1 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -1820,6 +1820,9 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
1820 int *pc, unsigned int *max_pages) 1820 int *pc, unsigned int *max_pages)
1821{ 1821{
1822 struct osc_extent *tmp; 1822 struct osc_extent *tmp;
1823 struct osc_async_page *oap = list_first_entry(&ext->oe_pages,
1824 struct osc_async_page,
1825 oap_pending_item);
1823 1826
1824 EASSERT((ext->oe_state == OES_CACHE || ext->oe_state == OES_LOCK_DONE), 1827 EASSERT((ext->oe_state == OES_CACHE || ext->oe_state == OES_LOCK_DONE),
1825 ext); 1828 ext);
@@ -1829,6 +1832,10 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
1829 return 0; 1832 return 0;
1830 1833
1831 list_for_each_entry(tmp, rpclist, oe_link) { 1834 list_for_each_entry(tmp, rpclist, oe_link) {
1835 struct osc_async_page *oap2;
1836
1837 oap2 = list_first_entry(&tmp->oe_pages, struct osc_async_page,
1838 oap_pending_item);
1832 EASSERT(tmp->oe_owner == current, tmp); 1839 EASSERT(tmp->oe_owner == current, tmp);
1833#if 0 1840#if 0
1834 if (overlapped(tmp, ext)) { 1841 if (overlapped(tmp, ext)) {
@@ -1836,6 +1843,11 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
1836 EASSERT(0, ext); 1843 EASSERT(0, ext);
1837 } 1844 }
1838#endif 1845#endif
1846 if (oap2cl_page(oap)->cp_type != oap2cl_page(oap2)->cp_type) {
1847 CDEBUG(D_CACHE, "Do not permit different type of IO"
1848 " for a same RPC\n");
1849 return 0;
1850 }
1839 1851
1840 if (tmp->oe_srvlock != ext->oe_srvlock || 1852 if (tmp->oe_srvlock != ext->oe_srvlock ||
1841 !tmp->oe_grants != !ext->oe_grants) 1853 !tmp->oe_grants != !ext->oe_grants)
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h
index d788dac93cd0..af96c7bc7764 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -160,11 +160,6 @@ static inline unsigned long rpcs_in_flight(struct client_obd *cli)
160 return cli->cl_r_in_flight + cli->cl_w_in_flight; 160 return cli->cl_r_in_flight + cli->cl_w_in_flight;
161} 161}
162 162
163#ifndef min_t
164#define min_t(type, x, y) \
165 ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
166#endif
167
168struct osc_device { 163struct osc_device {
169 struct cl_device od_cl; 164 struct cl_device od_cl;
170 struct obd_export *od_exp; 165 struct obd_export *od_exp;
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index a7f08bc48166..445655724904 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -100,14 +100,14 @@ static int osc_lock_invariant(struct osc_lock *ols)
100 /* 100 /*
101 * If all the following "ergo"s are true, return 1, otherwise 0 101 * If all the following "ergo"s are true, return 1, otherwise 0
102 */ 102 */
103 if (! ergo(olock != NULL, handle_used)) 103 if (!ergo(olock != NULL, handle_used))
104 return 0; 104 return 0;
105 105
106 if (! ergo(olock != NULL, 106 if (!ergo(olock != NULL,
107 olock->l_handle.h_cookie == ols->ols_handle.cookie)) 107 olock->l_handle.h_cookie == ols->ols_handle.cookie))
108 return 0; 108 return 0;
109 109
110 if (! ergo(handle_used, 110 if (!ergo(handle_used,
111 ergo(lock != NULL && olock != NULL, lock == olock) && 111 ergo(lock != NULL && olock != NULL, lock == olock) &&
112 ergo(lock == NULL, olock == NULL))) 112 ergo(lock == NULL, olock == NULL)))
113 return 0; 113 return 0;
@@ -115,18 +115,18 @@ static int osc_lock_invariant(struct osc_lock *ols)
115 * Check that ->ols_handle and ->ols_lock are consistent, but 115 * Check that ->ols_handle and ->ols_lock are consistent, but
116 * take into account that they are set at the different time. 116 * take into account that they are set at the different time.
117 */ 117 */
118 if (! ergo(ols->ols_state == OLS_CANCELLED, 118 if (!ergo(ols->ols_state == OLS_CANCELLED,
119 olock == NULL && !handle_used)) 119 olock == NULL && !handle_used))
120 return 0; 120 return 0;
121 /* 121 /*
122 * DLM lock is destroyed only after we have seen cancellation 122 * DLM lock is destroyed only after we have seen cancellation
123 * ast. 123 * ast.
124 */ 124 */
125 if (! ergo(olock != NULL && ols->ols_state < OLS_CANCELLED, 125 if (!ergo(olock != NULL && ols->ols_state < OLS_CANCELLED,
126 ((olock->l_flags & LDLM_FL_DESTROYED) == 0))) 126 ((olock->l_flags & LDLM_FL_DESTROYED) == 0)))
127 return 0; 127 return 0;
128 128
129 if (! ergo(ols->ols_state == OLS_GRANTED, 129 if (!ergo(ols->ols_state == OLS_GRANTED,
130 olock != NULL && 130 olock != NULL &&
131 olock->l_req_mode == olock->l_granted_mode && 131 olock->l_req_mode == olock->l_granted_mode &&
132 ols->ols_hold)) 132 ols->ols_hold))
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index b9450b95f1c5..0adfa707a763 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -3332,7 +3332,7 @@ extern struct lu_kmem_descr osc_caches[];
3332extern spinlock_t osc_ast_guard; 3332extern spinlock_t osc_ast_guard;
3333extern struct lock_class_key osc_ast_guard_class; 3333extern struct lock_class_key osc_ast_guard_class;
3334 3334
3335int __init osc_init(void) 3335static int __init osc_init(void)
3336{ 3336{
3337 struct lprocfs_static_vars lvars = { NULL }; 3337 struct lprocfs_static_vars lvars = { NULL };
3338 int rc; 3338 int rc;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index dc9e406f3212..4882dd0a4483 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1247,7 +1247,9 @@ static int after_reply(struct ptlrpc_request *req)
1247 time_t now = get_seconds(); 1247 time_t now = get_seconds();
1248 1248
1249 DEBUG_REQ(D_RPCTRACE, req, "Resending request on EINPROGRESS"); 1249 DEBUG_REQ(D_RPCTRACE, req, "Resending request on EINPROGRESS");
1250 spin_lock(&req->rq_lock);
1250 req->rq_resend = 1; 1251 req->rq_resend = 1;
1252 spin_unlock(&req->rq_lock);
1251 req->rq_nr_resend++; 1253 req->rq_nr_resend++;
1252 1254
1253 /* allocate new xid to avoid reply reconstruction */ 1255 /* allocate new xid to avoid reply reconstruction */
@@ -1497,11 +1499,13 @@ static inline int ptlrpc_set_producer(struct ptlrpc_request_set *set)
1497int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) 1499int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
1498{ 1500{
1499 struct list_head *tmp, *next; 1501 struct list_head *tmp, *next;
1502 struct list_head comp_reqs;
1500 int force_timer_recalc = 0; 1503 int force_timer_recalc = 0;
1501 1504
1502 if (atomic_read(&set->set_remaining) == 0) 1505 if (atomic_read(&set->set_remaining) == 0)
1503 return 1; 1506 return 1;
1504 1507
1508 INIT_LIST_HEAD(&comp_reqs);
1505 list_for_each_safe(tmp, next, &set->set_requests) { 1509 list_for_each_safe(tmp, next, &set->set_requests) {
1506 struct ptlrpc_request *req = 1510 struct ptlrpc_request *req =
1507 list_entry(tmp, struct ptlrpc_request, 1511 list_entry(tmp, struct ptlrpc_request,
@@ -1576,8 +1580,10 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
1576 ptlrpc_rqphase_move(req, req->rq_next_phase); 1580 ptlrpc_rqphase_move(req, req->rq_next_phase);
1577 } 1581 }
1578 1582
1579 if (req->rq_phase == RQ_PHASE_COMPLETE) 1583 if (req->rq_phase == RQ_PHASE_COMPLETE) {
1584 list_move_tail(&req->rq_set_chain, &comp_reqs);
1580 continue; 1585 continue;
1586 }
1581 1587
1582 if (req->rq_phase == RQ_PHASE_INTERPRET) 1588 if (req->rq_phase == RQ_PHASE_INTERPRET)
1583 goto interpret; 1589 goto interpret;
@@ -1860,9 +1866,15 @@ interpret:
1860 if (req->rq_status != 0) 1866 if (req->rq_status != 0)
1861 set->set_rc = req->rq_status; 1867 set->set_rc = req->rq_status;
1862 ptlrpc_req_finished(req); 1868 ptlrpc_req_finished(req);
1869 } else {
1870 list_move_tail(&req->rq_set_chain, &comp_reqs);
1863 } 1871 }
1864 } 1872 }
1865 1873
1874 /* move completed request at the head of list so it's easier for
1875 * caller to find them */
1876 list_splice(&comp_reqs, &set->set_requests);
1877
1866 /* If we hit an error, we want to recover promptly. */ 1878 /* If we hit an error, we want to recover promptly. */
1867 return atomic_read(&set->set_remaining) == 0 || force_timer_recalc; 1879 return atomic_read(&set->set_remaining) == 0 || force_timer_recalc;
1868} 1880}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index dc5ceb55d001..bbef666b1d16 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -65,7 +65,6 @@
65#endif 65#endif
66/* struct ptlrpc_request, lustre_msg* */ 66/* struct ptlrpc_request, lustre_msg* */
67#include "../include/lustre_req_layout.h" 67#include "../include/lustre_req_layout.h"
68#include "../include/lustre_update.h"
69#include "../include/lustre_acl.h" 68#include "../include/lustre_acl.h"
70#include "../include/lustre_debug.h" 69#include "../include/lustre_debug.h"
71 70
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index 4011e0050fcb..0e2071b8a36e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -45,7 +45,7 @@
45#include "ptlrpc_internal.h" 45#include "ptlrpc_internal.h"
46 46
47 47
48struct ll_rpc_opcode { 48static struct ll_rpc_opcode {
49 __u32 opcode; 49 __u32 opcode;
50 const char *opname; 50 const char *opname;
51} ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = { 51} ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = {
@@ -136,7 +136,7 @@ struct ll_rpc_opcode {
136 { UPDATE_OBJ, "update_obj" }, 136 { UPDATE_OBJ, "update_obj" },
137}; 137};
138 138
139struct ll_eopcode { 139static struct ll_eopcode {
140 __u32 opcode; 140 __u32 opcode;
141 const char *opname; 141 const char *opname;
142} ll_eopcode_table[EXTRA_LAST_OPC] = { 142} ll_eopcode_table[EXTRA_LAST_OPC] = {
@@ -175,15 +175,17 @@ const char *ll_opcode2str(__u32 opcode)
175 return ll_rpc_opcode_table[offset].opname; 175 return ll_rpc_opcode_table[offset].opname;
176} 176}
177 177
178const char *ll_eopcode2str(__u32 opcode) 178static const char *ll_eopcode2str(__u32 opcode)
179{ 179{
180 LASSERT(ll_eopcode_table[opcode].opcode == opcode); 180 LASSERT(ll_eopcode_table[opcode].opcode == opcode);
181 return ll_eopcode_table[opcode].opname; 181 return ll_eopcode_table[opcode].opname;
182} 182}
183
183#if defined (CONFIG_PROC_FS) 184#if defined (CONFIG_PROC_FS)
184void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, 185static void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
185 char *name, struct proc_dir_entry **procroot_ret, 186 char *name,
186 struct lprocfs_stats **stats_ret) 187 struct proc_dir_entry **procroot_ret,
188 struct lprocfs_stats **stats_ret)
187{ 189{
188 struct proc_dir_entry *svc_procroot; 190 struct proc_dir_entry *svc_procroot;
189 struct lprocfs_stats *svc_stats; 191 struct lprocfs_stats *svc_stats;
@@ -284,8 +286,9 @@ ptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n)
284} 286}
285 287
286static ssize_t 288static ssize_t
287ptlrpc_lprocfs_req_history_max_seq_write(struct file *file, const char *buffer, 289ptlrpc_lprocfs_req_history_max_seq_write(struct file *file,
288 size_t count, loff_t *off) 290 const char __user *buffer,
291 size_t count, loff_t *off)
289{ 292{
290 struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; 293 struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
291 int bufpages; 294 int bufpages;
@@ -329,8 +332,9 @@ ptlrpc_lprocfs_threads_min_seq_show(struct seq_file *m, void *n)
329} 332}
330 333
331static ssize_t 334static ssize_t
332ptlrpc_lprocfs_threads_min_seq_write(struct file *file, const char *buffer, 335ptlrpc_lprocfs_threads_min_seq_write(struct file *file,
333 size_t count, loff_t *off) 336 const char __user *buffer,
337 size_t count, loff_t *off)
334{ 338{
335 struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; 339 struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
336 int val; 340 int val;
@@ -381,8 +385,9 @@ ptlrpc_lprocfs_threads_max_seq_show(struct seq_file *m, void *n)
381} 385}
382 386
383static ssize_t 387static ssize_t
384ptlrpc_lprocfs_threads_max_seq_write(struct file *file, const char *buffer, 388ptlrpc_lprocfs_threads_max_seq_write(struct file *file,
385 size_t count, loff_t *off) 389 const char __user *buffer,
390 size_t count, loff_t *off)
386{ 391{
387 struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; 392 struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
388 int val; 393 int val;
@@ -723,7 +728,7 @@ struct ptlrpc_srh_iterator {
723 struct ptlrpc_request *srhi_req; 728 struct ptlrpc_request *srhi_req;
724}; 729};
725 730
726int 731static int
727ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt, 732ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt,
728 struct ptlrpc_srh_iterator *srhi, 733 struct ptlrpc_srh_iterator *srhi,
729 __u64 seq) 734 __u64 seq)
@@ -1025,7 +1030,7 @@ static int ptlrpc_lprocfs_hp_ratio_seq_show(struct seq_file *m, void *v)
1025} 1030}
1026 1031
1027static ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file, 1032static ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file,
1028 const char *buffer, 1033 const char __user *buffer,
1029 size_t count, 1034 size_t count,
1030 loff_t *off) 1035 loff_t *off)
1031{ 1036{
@@ -1175,7 +1180,7 @@ EXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd);
1175 1180
1176#define BUFLEN (UUID_MAX + 5) 1181#define BUFLEN (UUID_MAX + 5)
1177 1182
1178int lprocfs_wr_evict_client(struct file *file, const char *buffer, 1183int lprocfs_wr_evict_client(struct file *file, const char __user *buffer,
1179 size_t count, loff_t *off) 1184 size_t count, loff_t *off)
1180{ 1185{
1181 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 1186 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -1223,7 +1228,7 @@ EXPORT_SYMBOL(lprocfs_wr_evict_client);
1223 1228
1224#undef BUFLEN 1229#undef BUFLEN
1225 1230
1226int lprocfs_wr_ping(struct file *file, const char *buffer, 1231int lprocfs_wr_ping(struct file *file, const char __user *buffer,
1227 size_t count, loff_t *off) 1232 size_t count, loff_t *off)
1228{ 1233{
1229 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 1234 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -1251,7 +1256,7 @@ EXPORT_SYMBOL(lprocfs_wr_ping);
1251 * The connection UUID is a node's primary NID. For example, 1256 * The connection UUID is a node's primary NID. For example,
1252 * "echo connection=192.168.0.1@tcp0::instance > .../import". 1257 * "echo connection=192.168.0.1@tcp0::instance > .../import".
1253 */ 1258 */
1254int lprocfs_wr_import(struct file *file, const char *buffer, 1259int lprocfs_wr_import(struct file *file, const char __user *buffer,
1255 size_t count, loff_t *off) 1260 size_t count, loff_t *off)
1256{ 1261{
1257 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 1262 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -1329,7 +1334,7 @@ int lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
1329} 1334}
1330EXPORT_SYMBOL(lprocfs_rd_pinger_recov); 1335EXPORT_SYMBOL(lprocfs_rd_pinger_recov);
1331 1336
1332int lprocfs_wr_pinger_recov(struct file *file, const char *buffer, 1337int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
1333 size_t count, loff_t *off) 1338 size_t count, loff_t *off)
1334{ 1339{
1335 struct obd_device *obd = ((struct seq_file *)file->private_data)->private; 1340 struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index cbcc541cac43..4621b71fe0b6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -306,21 +306,16 @@ static int ptlrpcd_check(struct lu_env *env, struct ptlrpcd_ctl *pc)
306 if (atomic_read(&set->set_remaining)) 306 if (atomic_read(&set->set_remaining))
307 rc |= ptlrpc_check_set(env, set); 307 rc |= ptlrpc_check_set(env, set);
308 308
309 if (!list_empty(&set->set_requests)) { 309 /* NB: ptlrpc_check_set has already moved completed request at the
310 /* 310 * head of seq::set_requests */
311 * XXX: our set never completes, so we prune the completed 311 list_for_each_safe(pos, tmp, &set->set_requests) {
312 * reqs after each iteration. boy could this be smarter. 312 req = list_entry(pos, struct ptlrpc_request, rq_set_chain);
313 */ 313 if (req->rq_phase != RQ_PHASE_COMPLETE)
314 list_for_each_safe(pos, tmp, &set->set_requests) { 314 break;
315 req = list_entry(pos, struct ptlrpc_request,
316 rq_set_chain);
317 if (req->rq_phase != RQ_PHASE_COMPLETE)
318 continue;
319 315
320 list_del_init(&req->rq_set_chain); 316 list_del_init(&req->rq_set_chain);
321 req->rq_set = NULL; 317 req->rq_set = NULL;
322 ptlrpc_req_finished(req); 318 ptlrpc_req_finished(req);
323 }
324 } 319 }
325 320
326 if (rc == 0) { 321 if (rc == 0) {
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index c500aff66193..81de68edb04e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -47,6 +47,8 @@
47#include "../include/lustre_net.h" 47#include "../include/lustre_net.h"
48#include "../include/lustre_sec.h" 48#include "../include/lustre_sec.h"
49 49
50#include "ptlrpc_internal.h"
51
50#define SEC_GC_INTERVAL (30 * 60) 52#define SEC_GC_INTERVAL (30 * 60)
51 53
52 54
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 704fa202ee18..a425f71dfb97 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -901,7 +901,7 @@ static int ipipe_set_gbce_params(struct vpfe_ipipe_device *ipipe, void *param)
901 struct device *dev = ipipe->subdev.v4l2_dev->dev; 901 struct device *dev = ipipe->subdev.v4l2_dev->dev;
902 902
903 if (!gbce_param) { 903 if (!gbce_param) {
904 memset(gbce, 0 , sizeof(struct vpfe_ipipe_gbce)); 904 memset(gbce, 0, sizeof(struct vpfe_ipipe_gbce));
905 } else { 905 } else {
906 memcpy(gbce, gbce_param, sizeof(struct vpfe_ipipe_gbce)); 906 memcpy(gbce, gbce_param, sizeof(struct vpfe_ipipe_gbce));
907 if (ipipe_validate_gbce_params(gbce) < 0) { 907 if (ipipe_validate_gbce_params(gbce) < 0) {
@@ -1086,7 +1086,7 @@ static int ipipe_set_car_params(struct vpfe_ipipe_device *ipipe, void *param)
1086 struct vpfe_ipipe_car *car = &ipipe->config.car; 1086 struct vpfe_ipipe_car *car = &ipipe->config.car;
1087 1087
1088 if (!car_param) { 1088 if (!car_param) {
1089 memset(car , 0, sizeof(struct vpfe_ipipe_car)); 1089 memset(car, 0, sizeof(struct vpfe_ipipe_car));
1090 } else { 1090 } else {
1091 memcpy(car, car_param, sizeof(struct vpfe_ipipe_car)); 1091 memcpy(car, car_param, sizeof(struct vpfe_ipipe_car));
1092 if (ipipe_validate_car_params(car) < 0) { 1092 if (ipipe_validate_car_params(car) < 0) {
diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig
index 403174817be7..f3f9cb3b5c35 100644
--- a/drivers/staging/mt29f_spinand/Kconfig
+++ b/drivers/staging/mt29f_spinand/Kconfig
@@ -12,5 +12,5 @@ config MTD_SPINAND_ONDIEECC
12 bool "Use SPINAND internal ECC" 12 bool "Use SPINAND internal ECC"
13 depends on MTD_SPINAND_MT29F 13 depends on MTD_SPINAND_MT29F
14 help 14 help
15 Internel ECC. 15 Internal ECC.
16 Enables Hardware ECC support for Micron SPI NAND. 16 Enables Hardware ECC support for Micron SPI NAND.
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
index 3628bcb840c3..3b191fce45ec 100644
--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -626,7 +626,8 @@ static int spinand_write_page_hwecc(struct mtd_info *mtd,
626static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, 626static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
627 uint8_t *buf, int oob_required, int page) 627 uint8_t *buf, int oob_required, int page)
628{ 628{
629 u8 retval, status; 629 int retval;
630 u8 status;
630 uint8_t *p = buf; 631 uint8_t *p = buf;
631 int eccsize = chip->ecc.size; 632 int eccsize = chip->ecc.size;
632 int eccsteps = chip->ecc.steps; 633 int eccsteps = chip->ecc.steps;
@@ -640,6 +641,13 @@ static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
640 641
641 while (1) { 642 while (1) {
642 retval = spinand_read_status(info->spi, &status); 643 retval = spinand_read_status(info->spi, &status);
644 if (retval < 0) {
645 dev_err(&mtd->dev,
646 "error %d reading status register\n",
647 retval);
648 return retval;
649 }
650
643 if ((status & STATUS_OIP_MASK) == STATUS_READY) { 651 if ((status & STATUS_OIP_MASK) == STATUS_READY) {
644 if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) { 652 if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
645 pr_info("spinand: ECC error\n"); 653 pr_info("spinand: ECC error\n");
@@ -685,6 +693,13 @@ static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
685 693
686 while (time_before(jiffies, timeo)) { 694 while (time_before(jiffies, timeo)) {
687 retval = spinand_read_status(info->spi, &status); 695 retval = spinand_read_status(info->spi, &status);
696 if (retval < 0) {
697 dev_err(&mtd->dev,
698 "error %d reading status register\n",
699 retval);
700 return retval;
701 }
702
688 if ((status & STATUS_OIP_MASK) == STATUS_READY) 703 if ((status & STATUS_OIP_MASK) == STATUS_READY)
689 return 0; 704 return 0;
690 705
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
index 5ecb3e6a5bb3..e8aae09d1624 100644
--- a/drivers/staging/netlogic/xlr_net.c
+++ b/drivers/staging/netlogic/xlr_net.c
@@ -788,7 +788,7 @@ void xlr_set_gmac_speed(struct xlr_net_priv *priv)
788 xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7117); 788 xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7117);
789 priv->phy_speed = speed; 789 priv->phy_speed = speed;
790 } 790 }
791 /* Set SGMII speed in Interface controll reg */ 791 /* Set SGMII speed in Interface control reg */
792 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 792 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
793 if (speed == SPEED_10) 793 if (speed == SPEED_10)
794 xlr_nae_wreg(priv->base_addr, 794 xlr_nae_wreg(priv->base_addr,
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index 120b70d72d79..5868ebb8389e 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -256,7 +256,7 @@ static void nvec_gpio_set_value(struct nvec_chip *nvec, int value)
256 * and return immediately. 256 * and return immediately.
257 * 257 *
258 * Returns: 0 on success, a negative error code on failure. If a failure 258 * Returns: 0 on success, a negative error code on failure. If a failure
259 * occured, the nvec driver may print an error. 259 * occurred, the nvec driver may print an error.
260 */ 260 */
261int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data, 261int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data,
262 short size) 262 short size)
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index 6b8b108c4e6d..1daeb3125a1f 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -2687,7 +2687,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
2687 2687
2688 /* 2688 /*
2689 * Read the channel config info so we can figure out how much data 2689 * Read the channel config info so we can figure out how much data
2690 * transfered 2690 * transferred
2691 */ 2691 */
2692 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, 2692 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb,
2693 CVMX_USBCX_HCCHARX(channel, usb->index)); 2693 CVMX_USBCX_HCCHARX(channel, usb->index));
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index fcbe836aa997..22667dbb10d8 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -109,6 +109,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
109 int interface = cvmx_helper_get_interface_num(work->ipprt); 109 int interface = cvmx_helper_get_interface_num(work->ipprt);
110 int index = cvmx_helper_get_interface_index_num(work->ipprt); 110 int index = cvmx_helper_get_interface_index_num(work->ipprt);
111 union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; 111 union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
112
112 gmxx_rxx_frm_ctl.u64 = 113 gmxx_rxx_frm_ctl.u64 =
113 cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface)); 114 cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
114 if (gmxx_rxx_frm_ctl.s.pre_chk == 0) { 115 if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
@@ -214,6 +215,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
214 did_work_request = 0; 215 did_work_request = 0;
215 if (work == NULL) { 216 if (work == NULL) {
216 union cvmx_pow_wq_int wq_int; 217 union cvmx_pow_wq_int wq_int;
218
217 wq_int.u64 = 0; 219 wq_int.u64 = 0;
218 wq_int.s.iq_dis = 1 << pow_receive_group; 220 wq_int.s.iq_dis = 1 << pow_receive_group;
219 wq_int.s.wq_int = 1 << pow_receive_group; 221 wq_int.s.wq_int = 1 << pow_receive_group;
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index ee321496dcdd..460e8545904f 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -798,7 +798,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
798 cvm_oct_rx_initialize(); 798 cvm_oct_rx_initialize();
799 799
800 /* 800 /*
801 * 150 uS: about 10 1500-byte packtes at 1GE. 801 * 150 uS: about 10 1500-byte packets at 1GE.
802 */ 802 */
803 cvm_oct_tx_poll_interval = 150 * (octeon_get_clock_rate() / 1000000); 803 cvm_oct_tx_poll_interval = 150 * (octeon_get_clock_rate() / 1000000);
804 804
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index 6a9a8815477c..bc7e664cc8a7 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -780,7 +780,7 @@ static const struct i2c_device_id dcon_idtable[] = {
780}; 780};
781MODULE_DEVICE_TABLE(i2c, dcon_idtable); 781MODULE_DEVICE_TABLE(i2c, dcon_idtable);
782 782
783struct i2c_driver dcon_driver = { 783static struct i2c_driver dcon_driver = {
784 .driver = { 784 .driver = {
785 .name = "olpc_dcon", 785 .name = "olpc_dcon",
786 .pm = &dcon_pm_ops, 786 .pm = &dcon_pm_ops,
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
index 77e8eb5a5abd..0c5a10c69401 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
@@ -52,7 +52,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon)
52 * Determine the current state by reading the GPIO bit; earlier 52 * Determine the current state by reading the GPIO bit; earlier
53 * stages of the boot process have established the state. 53 * stages of the boot process have established the state.
54 * 54 *
55 * Note that we read GPIO_OUPUT_VAL rather than GPIO_READ_BACK here; 55 * Note that we read GPIO_OUTPUT_VAL rather than GPIO_READ_BACK here;
56 * this is because OFW will disable input for the pin and set a value.. 56 * this is because OFW will disable input for the pin and set a value..
57 * READ_BACK will only contain a valid value if input is enabled and 57 * READ_BACK will only contain a valid value if input is enabled and
58 * then a value is set. So, future readings of the pin can use 58 * then a value is set. So, future readings of the pin can use
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 98325b7b4462..6ed35b6ecf0d 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -130,6 +130,30 @@
130#define LCD_FLAG_N 0x0040 /* 2-rows mode */ 130#define LCD_FLAG_N 0x0040 /* 2-rows mode */
131#define LCD_FLAG_L 0x0080 /* backlight enabled */ 131#define LCD_FLAG_L 0x0080 /* backlight enabled */
132 132
133/* LCD commands */
134#define LCD_CMD_DISPLAY_CLEAR 0x01 /* Clear entire display */
135
136#define LCD_CMD_ENTRY_MODE 0x04 /* Set entry mode */
137#define LCD_CMD_CURSOR_INC 0x02 /* Increment cursor */
138
139#define LCD_CMD_DISPLAY_CTRL 0x08 /* Display control */
140#define LCD_CMD_DISPLAY_ON 0x04 /* Set display on */
141#define LCD_CMD_CURSOR_ON 0x02 /* Set cursor on */
142#define LCD_CMD_BLINK_ON 0x01 /* Set blink on */
143
144#define LCD_CMD_SHIFT 0x10 /* Shift cursor/display */
145#define LCD_CMD_DISPLAY_SHIFT 0x08 /* Shift display instead of cursor */
146#define LCD_CMD_SHIFT_RIGHT 0x04 /* Shift display/cursor to the right */
147
148#define LCD_CMD_FUNCTION_SET 0x20 /* Set function */
149#define LCD_CMD_DATA_LEN_8BITS 0x10 /* Set data length to 8 bits */
150#define LCD_CMD_TWO_LINES 0x08 /* Set to two display lines */
151#define LCD_CMD_FONT_5X10_DOTS 0x04 /* Set char font to 5x10 dots */
152
153#define LCD_CMD_SET_CGRAM_ADDR 0x40 /* Set char generator RAM address */
154
155#define LCD_CMD_SET_DDRAM_ADDR 0x80 /* Set display data RAM address */
156
133#define LCD_ESCAPE_LEN 24 /* max chars for LCD escape command */ 157#define LCD_ESCAPE_LEN 24 /* max chars for LCD escape command */
134#define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */ 158#define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */
135 159
@@ -228,9 +252,6 @@ static struct {
228 bool initialized; 252 bool initialized;
229 bool must_clear; 253 bool must_clear;
230 254
231 /* TODO: use bool here? */
232 char left_shift;
233
234 int height; 255 int height;
235 int width; 256 int width;
236 int bwidth; 257 int bwidth;
@@ -759,7 +780,7 @@ static void long_sleep(int ms)
759 if (in_interrupt()) { 780 if (in_interrupt()) {
760 mdelay(ms); 781 mdelay(ms);
761 } else { 782 } else {
762 current->state = TASK_INTERRUPTIBLE; 783 __set_current_state(TASK_INTERRUPTIBLE);
763 schedule_timeout((ms * HZ + 999) / 1000); 784 schedule_timeout((ms * HZ + 999) / 1000);
764 } 785 }
765} 786}
@@ -886,7 +907,7 @@ static void lcd_write_data_tilcd(int data)
886 907
887static void lcd_gotoxy(void) 908static void lcd_gotoxy(void)
888{ 909{
889 lcd_write_cmd(0x80 /* set DDRAM address */ 910 lcd_write_cmd(LCD_CMD_SET_DDRAM_ADDR
890 | (lcd.addr.y ? lcd.hwidth : 0) 911 | (lcd.addr.y ? lcd.hwidth : 0)
891 /* we force the cursor to stay at the end of the 912 /* we force the cursor to stay at the end of the
892 line if it wants to go farther */ 913 line if it wants to go farther */
@@ -994,7 +1015,7 @@ static void lcd_clear_fast_tilcd(void)
994/* clears the display and resets X/Y */ 1015/* clears the display and resets X/Y */
995static void lcd_clear_display(void) 1016static void lcd_clear_display(void)
996{ 1017{
997 lcd_write_cmd(0x01); /* clear display */ 1018 lcd_write_cmd(LCD_CMD_DISPLAY_CLEAR);
998 lcd.addr.x = 0; 1019 lcd.addr.x = 0;
999 lcd.addr.y = 0; 1020 lcd.addr.y = 0;
1000 /* we must wait a few milliseconds (15) */ 1021 /* we must wait a few milliseconds (15) */
@@ -1008,26 +1029,29 @@ static void lcd_init_display(void)
1008 1029
1009 long_sleep(20); /* wait 20 ms after power-up for the paranoid */ 1030 long_sleep(20); /* wait 20 ms after power-up for the paranoid */
1010 1031
1011 lcd_write_cmd(0x30); /* 8bits, 1 line, small fonts */ 1032 /* 8bits, 1 line, small fonts; let's do it 3 times */
1033 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1012 long_sleep(10); 1034 long_sleep(10);
1013 lcd_write_cmd(0x30); /* 8bits, 1 line, small fonts */ 1035 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1014 long_sleep(10); 1036 long_sleep(10);
1015 lcd_write_cmd(0x30); /* 8bits, 1 line, small fonts */ 1037 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1016 long_sleep(10); 1038 long_sleep(10);
1017 1039
1018 lcd_write_cmd(0x30 /* set font height and lines number */ 1040 /* set font height and lines number */
1019 | ((lcd.flags & LCD_FLAG_F) ? 4 : 0) 1041 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS
1020 | ((lcd.flags & LCD_FLAG_N) ? 8 : 0) 1042 | ((lcd.flags & LCD_FLAG_F) ? LCD_CMD_FONT_5X10_DOTS : 0)
1043 | ((lcd.flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0)
1021 ); 1044 );
1022 long_sleep(10); 1045 long_sleep(10);
1023 1046
1024 lcd_write_cmd(0x08); /* display off, cursor off, blink off */ 1047 /* display off, cursor off, blink off */
1048 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL);
1025 long_sleep(10); 1049 long_sleep(10);
1026 1050
1027 lcd_write_cmd(0x08 /* set display mode */ 1051 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL /* set display mode */
1028 | ((lcd.flags & LCD_FLAG_D) ? 4 : 0) 1052 | ((lcd.flags & LCD_FLAG_D) ? LCD_CMD_DISPLAY_ON : 0)
1029 | ((lcd.flags & LCD_FLAG_C) ? 2 : 0) 1053 | ((lcd.flags & LCD_FLAG_C) ? LCD_CMD_CURSOR_ON : 0)
1030 | ((lcd.flags & LCD_FLAG_B) ? 1 : 0) 1054 | ((lcd.flags & LCD_FLAG_B) ? LCD_CMD_BLINK_ON : 0)
1031 ); 1055 );
1032 1056
1033 lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0); 1057 lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0);
@@ -1035,7 +1059,7 @@ static void lcd_init_display(void)
1035 long_sleep(10); 1059 long_sleep(10);
1036 1060
1037 /* entry mode set : increment, cursor shifting */ 1061 /* entry mode set : increment, cursor shifting */
1038 lcd_write_cmd(0x06); 1062 lcd_write_cmd(LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
1039 1063
1040 lcd_clear_display(); 1064 lcd_clear_display();
1041} 1065}
@@ -1119,7 +1143,7 @@ static inline int handle_lcd_special_code(void)
1119 if (lcd.addr.x > 0) { 1143 if (lcd.addr.x > 0) {
1120 /* back one char if not at end of line */ 1144 /* back one char if not at end of line */
1121 if (lcd.addr.x < lcd.bwidth) 1145 if (lcd.addr.x < lcd.bwidth)
1122 lcd_write_cmd(0x10); 1146 lcd_write_cmd(LCD_CMD_SHIFT);
1123 lcd.addr.x--; 1147 lcd.addr.x--;
1124 } 1148 }
1125 processed = 1; 1149 processed = 1;
@@ -1127,21 +1151,20 @@ static inline int handle_lcd_special_code(void)
1127 case 'r': /* shift cursor right */ 1151 case 'r': /* shift cursor right */
1128 if (lcd.addr.x < lcd.width) { 1152 if (lcd.addr.x < lcd.width) {
1129 /* allow the cursor to pass the end of the line */ 1153 /* allow the cursor to pass the end of the line */
1130 if (lcd.addr.x < 1154 if (lcd.addr.x < (lcd.bwidth - 1))
1131 (lcd.bwidth - 1)) 1155 lcd_write_cmd(LCD_CMD_SHIFT |
1132 lcd_write_cmd(0x14); 1156 LCD_CMD_SHIFT_RIGHT);
1133 lcd.addr.x++; 1157 lcd.addr.x++;
1134 } 1158 }
1135 processed = 1; 1159 processed = 1;
1136 break; 1160 break;
1137 case 'L': /* shift display left */ 1161 case 'L': /* shift display left */
1138 lcd.left_shift++; 1162 lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT);
1139 lcd_write_cmd(0x18);
1140 processed = 1; 1163 processed = 1;
1141 break; 1164 break;
1142 case 'R': /* shift display right */ 1165 case 'R': /* shift display right */
1143 lcd.left_shift--; 1166 lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT |
1144 lcd_write_cmd(0x1C); 1167 LCD_CMD_SHIFT_RIGHT);
1145 processed = 1; 1168 processed = 1;
1146 break; 1169 break;
1147 case 'k': { /* kill end of line */ 1170 case 'k': { /* kill end of line */
@@ -1157,7 +1180,6 @@ static inline int handle_lcd_special_code(void)
1157 } 1180 }
1158 case 'I': /* reinitialize display */ 1181 case 'I': /* reinitialize display */
1159 lcd_init_display(); 1182 lcd_init_display();
1160 lcd.left_shift = 0;
1161 processed = 1; 1183 processed = 1;
1162 break; 1184 break;
1163 case 'G': { 1185 case 'G': {
@@ -1211,7 +1233,7 @@ static inline int handle_lcd_special_code(void)
1211 esc++; 1233 esc++;
1212 } 1234 }
1213 1235
1214 lcd_write_cmd(0x40 | (cgaddr * 8)); 1236 lcd_write_cmd(LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
1215 for (addr = 0; addr < cgoffset; addr++) 1237 for (addr = 0; addr < cgoffset; addr++)
1216 lcd_write_data(cgbytes[addr]); 1238 lcd_write_data(cgbytes[addr]);
1217 1239
@@ -1244,21 +1266,29 @@ static inline int handle_lcd_special_code(void)
1244 break; 1266 break;
1245 } 1267 }
1246 1268
1269 /* TODO: This indent party here got ugly, clean it! */
1247 /* Check whether one flag was changed */ 1270 /* Check whether one flag was changed */
1248 if (oldflags != lcd.flags) { 1271 if (oldflags != lcd.flags) {
1249 /* check whether one of B,C,D flags were changed */ 1272 /* check whether one of B,C,D flags were changed */
1250 if ((oldflags ^ lcd.flags) & 1273 if ((oldflags ^ lcd.flags) &
1251 (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D)) 1274 (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
1252 /* set display mode */ 1275 /* set display mode */
1253 lcd_write_cmd(0x08 1276 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL
1254 | ((lcd.flags & LCD_FLAG_D) ? 4 : 0) 1277 | ((lcd.flags & LCD_FLAG_D)
1255 | ((lcd.flags & LCD_FLAG_C) ? 2 : 0) 1278 ? LCD_CMD_DISPLAY_ON : 0)
1256 | ((lcd.flags & LCD_FLAG_B) ? 1 : 0)); 1279 | ((lcd.flags & LCD_FLAG_C)
1280 ? LCD_CMD_CURSOR_ON : 0)
1281 | ((lcd.flags & LCD_FLAG_B)
1282 ? LCD_CMD_BLINK_ON : 0));
1257 /* check whether one of F,N flags was changed */ 1283 /* check whether one of F,N flags was changed */
1258 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N)) 1284 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N))
1259 lcd_write_cmd(0x30 1285 lcd_write_cmd(LCD_CMD_FUNCTION_SET
1260 | ((lcd.flags & LCD_FLAG_F) ? 4 : 0) 1286 | LCD_CMD_DATA_LEN_8BITS
1261 | ((lcd.flags & LCD_FLAG_N) ? 8 : 0)); 1287 | ((lcd.flags & LCD_FLAG_F)
1288 ? LCD_CMD_TWO_LINES : 0)
1289 | ((lcd.flags & LCD_FLAG_N)
1290 ? LCD_CMD_FONT_5X10_DOTS
1291 : 0));
1262 /* check whether L flag was changed */ 1292 /* check whether L flag was changed */
1263 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) { 1293 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) {
1264 if (lcd.flags & (LCD_FLAG_L)) 1294 if (lcd.flags & (LCD_FLAG_L))
@@ -1297,13 +1327,13 @@ static void lcd_write_char(char c)
1297 end of the line */ 1327 end of the line */
1298 if (lcd.addr.x < lcd.bwidth) 1328 if (lcd.addr.x < lcd.bwidth)
1299 /* back one char */ 1329 /* back one char */
1300 lcd_write_cmd(0x10); 1330 lcd_write_cmd(LCD_CMD_SHIFT);
1301 lcd.addr.x--; 1331 lcd.addr.x--;
1302 } 1332 }
1303 /* replace with a space */ 1333 /* replace with a space */
1304 lcd_write_data(' '); 1334 lcd_write_data(' ');
1305 /* back one char again */ 1335 /* back one char again */
1306 lcd_write_cmd(0x10); 1336 lcd_write_cmd(LCD_CMD_SHIFT);
1307 break; 1337 break;
1308 case '\014': 1338 case '\014':
1309 /* quickly clear the display */ 1339 /* quickly clear the display */
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index d61842ed673e..da19145c49c5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -509,7 +509,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
509 tx_ra_bitmap |= ((raid<<28)&0xf0000000); 509 tx_ra_bitmap |= ((raid<<28)&0xf0000000);
510 510
511 DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n", 511 DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n",
512 __func__ , psta->mac_id, raid , tx_ra_bitmap, arg); 512 __func__, psta->mac_id, raid, tx_ra_bitmap, arg);
513 513
514 /* bitmap[0:27] = tx_rate_bitmap */ 514 /* bitmap[0:27] = tx_rate_bitmap */
515 /* bitmap[28:31]= Rate Adaptive id */ 515 /* bitmap[28:31]= Rate Adaptive id */
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index e4b7ee4c99d5..cd12dd70dd88 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -484,17 +484,8 @@ void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame)
484 /* fall through */ 484 /* fall through */
485 case WIFI_ASSOCREQ: 485 case WIFI_ASSOCREQ:
486 case WIFI_REASSOCREQ: 486 case WIFI_REASSOCREQ:
487 _mgt_dispatcher(padapter, ptable, precv_frame);
488 break;
489 case WIFI_PROBEREQ: 487 case WIFI_PROBEREQ:
490 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
491 _mgt_dispatcher(padapter, ptable, precv_frame);
492 else
493 _mgt_dispatcher(padapter, ptable, precv_frame);
494 break;
495 case WIFI_BEACON: 488 case WIFI_BEACON:
496 _mgt_dispatcher(padapter, ptable, precv_frame);
497 break;
498 case WIFI_ACTION: 489 case WIFI_ACTION:
499 _mgt_dispatcher(padapter, ptable, precv_frame); 490 _mgt_dispatcher(padapter, ptable, precv_frame);
500 break; 491 break;
@@ -577,13 +568,14 @@ unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
577 uint len = precv_frame->len; 568 uint len = precv_frame->len;
578 struct wlan_bssid_ex *pbss; 569 struct wlan_bssid_ex *pbss;
579 int ret = _SUCCESS; 570 int ret = _SUCCESS;
571 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
580 572
581 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 573 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
582 report_survey_event(padapter, precv_frame); 574 report_survey_event(padapter, precv_frame);
583 return _SUCCESS; 575 return _SUCCESS;
584 } 576 }
585 577
586 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { 578 if (!memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN)) {
587 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { 579 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
588 /* we should update current network before auth, or some IE is wrong */ 580 /* we should update current network before auth, or some IE is wrong */
589 pbss = (struct wlan_bssid_ex *)rtw_malloc(sizeof(struct wlan_bssid_ex)); 581 pbss = (struct wlan_bssid_ex *)rtw_malloc(sizeof(struct wlan_bssid_ex));
@@ -1445,10 +1437,10 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame)
1445 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1437 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1446 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1438 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1447 u8 *pframe = precv_frame->rx_data; 1439 u8 *pframe = precv_frame->rx_data;
1440 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1448 1441
1449 /* check A3 */ 1442 /* check A3 */
1450 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), 1443 if (memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN))
1451 ETH_ALEN))
1452 return _SUCCESS; 1444 return _SUCCESS;
1453 1445
1454 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1446 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
@@ -1499,10 +1491,10 @@ unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame
1499 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1491 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1500 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1492 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1501 u8 *pframe = precv_frame->rx_data; 1493 u8 *pframe = precv_frame->rx_data;
1494 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1502 1495
1503 /* check A3 */ 1496 /* check A3 */
1504 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), 1497 if (memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN))
1505 ETH_ALEN))
1506 return _SUCCESS; 1498 return _SUCCESS;
1507 1499
1508 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1500 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
@@ -2018,7 +2010,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
2018 2010
2019 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); 2011 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2020 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2012 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2021 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); 2013 memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
2022 2014
2023 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); 2015 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
2024 /* pmlmeext->mgnt_seq++; */ 2016 /* pmlmeext->mgnt_seq++; */
@@ -2422,6 +2414,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
2422 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2414 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2423 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2415 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2424 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2416 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2417 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2425 2418
2426 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2419 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2427 if (pmgntframe == NULL) 2420 if (pmgntframe == NULL)
@@ -2487,9 +2480,9 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
2487 } else { 2480 } else {
2488 __le32 le_tmp32; 2481 __le32 le_tmp32;
2489 __le16 le_tmp16; 2482 __le16 le_tmp16;
2490 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); 2483 memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
2491 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); 2484 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2492 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); 2485 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
2493 2486
2494 /* setting auth algo number */ 2487 /* setting auth algo number */
2495 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */ 2488 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */
@@ -2582,7 +2575,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
2582 2575
2583 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); 2576 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
2584 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN); 2577 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
2585 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2578 memcpy((void *)GetAddr3Ptr(pwlanhdr), pnetwork->MacAddress, ETH_ALEN);
2586 2579
2587 2580
2588 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2581 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
@@ -2687,6 +2680,7 @@ void issue_assocreq(struct adapter *padapter)
2687 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2680 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2688 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2681 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2689 int bssrate_len = 0, sta_bssrate_len = 0; 2682 int bssrate_len = 0, sta_bssrate_len = 0;
2683 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2690 2684
2691 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2685 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2692 if (pmgntframe == NULL) 2686 if (pmgntframe == NULL)
@@ -2702,9 +2696,9 @@ void issue_assocreq(struct adapter *padapter)
2702 2696
2703 fctrl = &(pwlanhdr->frame_ctl); 2697 fctrl = &(pwlanhdr->frame_ctl);
2704 *(fctrl) = 0; 2698 *(fctrl) = 0;
2705 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2699 memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
2706 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2700 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2707 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2701 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
2708 2702
2709 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2703 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2710 pmlmeext->mgnt_seq++; 2704 pmlmeext->mgnt_seq++;
@@ -2879,6 +2873,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
2879 struct xmit_priv *pxmitpriv; 2873 struct xmit_priv *pxmitpriv;
2880 struct mlme_ext_priv *pmlmeext; 2874 struct mlme_ext_priv *pmlmeext;
2881 struct mlme_ext_info *pmlmeinfo; 2875 struct mlme_ext_info *pmlmeinfo;
2876 struct wlan_bssid_ex *pnetwork;
2882 2877
2883 if (!padapter) 2878 if (!padapter)
2884 goto exit; 2879 goto exit;
@@ -2886,6 +2881,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
2886 pxmitpriv = &(padapter->xmitpriv); 2881 pxmitpriv = &(padapter->xmitpriv);
2887 pmlmeext = &(padapter->mlmeextpriv); 2882 pmlmeext = &(padapter->mlmeextpriv);
2888 pmlmeinfo = &(pmlmeext->mlmext_info); 2883 pmlmeinfo = &(pmlmeext->mlmext_info);
2884 pnetwork = &(pmlmeinfo->network);
2889 2885
2890 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2886 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2891 if (pmgntframe == NULL) 2887 if (pmgntframe == NULL)
@@ -2914,7 +2910,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
2914 2910
2915 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 2911 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2916 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2912 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2917 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2913 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
2918 2914
2919 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2915 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2920 pmlmeext->mgnt_seq++; 2916 pmlmeext->mgnt_seq++;
@@ -2946,10 +2942,11 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow
2946 u32 start = jiffies; 2942 u32 start = jiffies;
2947 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2943 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2948 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2944 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2945 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2949 2946
2950 /* da == NULL, assume it's null data for sta to ap*/ 2947 /* da == NULL, assume it's null data for sta to ap*/
2951 if (da == NULL) 2948 if (da == NULL)
2952 da = get_my_bssid(&(pmlmeinfo->network)); 2949 da = pnetwork->MacAddress;
2953 2950
2954 do { 2951 do {
2955 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? true : false); 2952 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? true : false);
@@ -2995,6 +2992,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
2995 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2992 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2996 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2993 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2997 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2994 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2995 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2998 2996
2999 DBG_88E("%s\n", __func__); 2997 DBG_88E("%s\n", __func__);
3000 2998
@@ -3038,7 +3036,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
3038 3036
3039 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3037 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3040 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3038 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3041 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3039 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
3042 3040
3043 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3041 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3044 pmlmeext->mgnt_seq++; 3042 pmlmeext->mgnt_seq++;
@@ -3069,10 +3067,11 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int
3069 u32 start = jiffies; 3067 u32 start = jiffies;
3070 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3068 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3071 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3069 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3070 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3072 3071
3073 /* da == NULL, assume it's null data for sta to ap*/ 3072 /* da == NULL, assume it's null data for sta to ap*/
3074 if (da == NULL) 3073 if (da == NULL)
3075 da = get_my_bssid(&(pmlmeinfo->network)); 3074 da = pnetwork->MacAddress;
3076 3075
3077 do { 3076 do {
3078 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0 ? true : false); 3077 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0 ? true : false);
@@ -3115,6 +3114,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
3115 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3114 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3116 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3115 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3117 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3116 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3117 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3118 int ret = _FAIL; 3118 int ret = _FAIL;
3119 __le16 le_tmp; 3119 __le16 le_tmp;
3120 3120
@@ -3137,7 +3137,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
3137 3137
3138 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3138 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3139 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3139 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3140 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3140 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
3141 3141
3142 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3142 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3143 pmlmeext->mgnt_seq++; 3143 pmlmeext->mgnt_seq++;
@@ -3288,6 +3288,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
3288 struct sta_info *psta; 3288 struct sta_info *psta;
3289 struct sta_priv *pstapriv = &padapter->stapriv; 3289 struct sta_priv *pstapriv = &padapter->stapriv;
3290 struct registry_priv *pregpriv = &padapter->registrypriv; 3290 struct registry_priv *pregpriv = &padapter->registrypriv;
3291 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3291 3292
3292 DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status); 3293 DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status);
3293 3294
@@ -3310,7 +3311,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
3310 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */ 3311 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
3311 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); 3312 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3312 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3313 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3313 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3314 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
3314 3315
3315 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3316 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3316 pmlmeext->mgnt_seq++; 3317 pmlmeext->mgnt_seq++;
@@ -3420,6 +3421,8 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
3420 struct __queue *queue = &(pmlmepriv->scanned_queue); 3421 struct __queue *queue = &(pmlmepriv->scanned_queue);
3421 u8 InfoContent[16] = {0}; 3422 u8 InfoContent[16] = {0};
3422 u8 ICS[8][15]; 3423 u8 ICS[8][15];
3424 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
3425
3423 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0)) 3426 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
3424 return; 3427 return;
3425 3428
@@ -3449,9 +3452,9 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
3449 fctrl = &(pwlanhdr->frame_ctl); 3452 fctrl = &(pwlanhdr->frame_ctl);
3450 *(fctrl) = 0; 3453 *(fctrl) = 0;
3451 3454
3452 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3455 memcpy(pwlanhdr->addr1, cur_network->MacAddress, ETH_ALEN);
3453 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3456 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3454 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3457 memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
3455 3458
3456 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3459 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3457 pmlmeext->mgnt_seq++; 3460 pmlmeext->mgnt_seq++;
@@ -4042,9 +4045,10 @@ unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr
4042{ 4045{
4043 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4046 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4044 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4047 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4048 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
4045 4049
4046 /* check A3 */ 4050 /* check A3 */
4047 if (memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) 4051 if (memcmp(MacAddr, pnetwork->MacAddress, ETH_ALEN))
4048 return _SUCCESS; 4052 return _SUCCESS;
4049 4053
4050 DBG_88E("%s\n", __func__); 4054 DBG_88E("%s\n", __func__);
@@ -4924,11 +4928,6 @@ void addba_timer_hdl(void *function_context)
4924 } 4928 }
4925} 4929}
4926 4930
4927u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
4928{
4929 return H2C_SUCCESS;
4930}
4931
4932u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) 4931u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
4933{ 4932{
4934 u8 type; 4933 u8 type;
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
index 324c1a7fd0bc..a3ffc691be9a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
@@ -405,11 +405,6 @@ int get_bsstype(unsigned short capability)
405 return 0; 405 return 0;
406} 406}
407 407
408__inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork)
409{
410 return pnetwork->MacAddress;
411}
412
413u16 get_beacon_interval(struct wlan_bssid_ex *bss) 408u16 get_beacon_interval(struct wlan_bssid_ex *bss)
414{ 409{
415 __le16 val; 410 __le16 val;
@@ -936,6 +931,8 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
936 } 931 }
937 932
938 bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); 933 bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
934 if (!bssid)
935 return _FAIL;
939 936
940 subtype = GetFrameSubType(pframe) >> 4; 937 subtype = GetFrameSubType(pframe) >> 4;
941 938
diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c
index 9873998011d2..06477e834653 100644
--- a/drivers/staging/rtl8188eu/hal/odm.c
+++ b/drivers/staging/rtl8188eu/hal/odm.c
@@ -534,13 +534,8 @@ void odm_DIGInit(struct odm_dm_struct *pDM_Odm)
534 pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; 534 pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH;
535 pDM_DigTable->FALowThresh = DM_false_ALARM_THRESH_LOW; 535 pDM_DigTable->FALowThresh = DM_false_ALARM_THRESH_LOW;
536 pDM_DigTable->FAHighThresh = DM_false_ALARM_THRESH_HIGH; 536 pDM_DigTable->FAHighThresh = DM_false_ALARM_THRESH_HIGH;
537 if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) { 537 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
538 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; 538 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
539 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
540 } else {
541 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
542 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
543 }
544 pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; 539 pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
545 pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; 540 pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
546 pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; 541 pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
@@ -1138,16 +1133,9 @@ static void FindMinimumRSSI(struct adapter *pAdapter)
1138{ 1133{
1139 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); 1134 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
1140 struct dm_priv *pdmpriv = &pHalData->dmpriv; 1135 struct dm_priv *pdmpriv = &pHalData->dmpriv;
1141 struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; 1136
1142 1137 /* 1 1.Unconditionally set RSSI */
1143 /* 1 1.Determine the minimum RSSI */ 1138 pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
1144 if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) &&
1145 (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0))
1146 pdmpriv->MinUndecoratedPWDBForDM = 0;
1147 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) /* Default port */
1148 pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
1149 else /* associated entry pwdb */
1150 pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
1151} 1139}
1152 1140
1153void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm) 1141void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm)
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 7f30dea1b53b..86347f2ccdfd 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -127,22 +127,6 @@ exit:
127 return ret; 127 return ret;
128} 128}
129 129
130u8 rtl8188e_set_rssi_cmd(struct adapter *adapt, u8 *param)
131{
132 u8 res = _SUCCESS;
133 struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
134
135 if (haldata->fw_ractrl) {
136 ;
137 } else {
138 DBG_88E("==>%s fw dont support RA\n", __func__);
139 res = _FAIL;
140 }
141
142
143 return res;
144}
145
146u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask) 130u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask)
147{ 131{
148 u8 buf[3]; 132 u8 buf[3];
@@ -276,7 +260,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
276 260
277 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); 261 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
278 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN); 262 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
279 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); 263 memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
280 264
281 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); 265 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
282 SetFrameSubType(pframe, WIFI_BEACON); 266 SetFrameSubType(pframe, WIFI_BEACON);
@@ -350,6 +334,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
350 struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); 334 struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
351 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 335 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
352 __le16 *fctrl; 336 __le16 *fctrl;
337 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
353 338
354 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; 339 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
355 340
@@ -363,7 +348,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
363 SetDuration(pframe, (pmlmeinfo->aid | 0xc000)); 348 SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
364 349
365 /* BSSID. */ 350 /* BSSID. */
366 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 351 memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
367 352
368 /* TA. */ 353 /* TA. */
369 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN); 354 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
@@ -386,6 +371,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
386 struct wlan_network *cur_network = &pmlmepriv->cur_network; 371 struct wlan_network *cur_network = &pmlmepriv->cur_network;
387 struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); 372 struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
388 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 373 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
374 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
389 375
390 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; 376 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
391 377
@@ -397,21 +383,21 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
397 switch (cur_network->network.InfrastructureMode) { 383 switch (cur_network->network.InfrastructureMode) {
398 case Ndis802_11Infrastructure: 384 case Ndis802_11Infrastructure:
399 SetToDs(fctrl); 385 SetToDs(fctrl);
400 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 386 memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
401 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN); 387 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
402 memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN); 388 memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
403 break; 389 break;
404 case Ndis802_11APMode: 390 case Ndis802_11APMode:
405 SetFrDs(fctrl); 391 SetFrDs(fctrl);
406 memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); 392 memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
407 memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 393 memcpy(pwlanhdr->addr2, pnetwork->MacAddress, ETH_ALEN);
408 memcpy(pwlanhdr->addr3, myid(&(adapt->eeprompriv)), ETH_ALEN); 394 memcpy(pwlanhdr->addr3, myid(&(adapt->eeprompriv)), ETH_ALEN);
409 break; 395 break;
410 case Ndis802_11IBSS: 396 case Ndis802_11IBSS:
411 default: 397 default:
412 memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); 398 memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
413 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN); 399 memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
414 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 400 memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
415 break; 401 break;
416 } 402 }
417 403
@@ -498,6 +484,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
498 u16 BufIndex; 484 u16 BufIndex;
499 u32 TotalPacketLen; 485 u32 TotalPacketLen;
500 struct rsvdpage_loc RsvdPageLoc; 486 struct rsvdpage_loc RsvdPageLoc;
487 struct wlan_bssid_ex *pnetwork;
501 488
502 DBG_88E("%s\n", __func__); 489 DBG_88E("%s\n", __func__);
503 ReservedPagePacket = kzalloc(1000, GFP_KERNEL); 490 ReservedPagePacket = kzalloc(1000, GFP_KERNEL);
@@ -510,6 +497,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
510 pxmitpriv = &adapt->xmitpriv; 497 pxmitpriv = &adapt->xmitpriv;
511 pmlmeext = &adapt->mlmeextpriv; 498 pmlmeext = &adapt->mlmeextpriv;
512 pmlmeinfo = &pmlmeext->mlmext_info; 499 pmlmeinfo = &pmlmeext->mlmext_info;
500 pnetwork = &(pmlmeinfo->network);
513 501
514 TxDescLen = TXDESC_SIZE; 502 TxDescLen = TXDESC_SIZE;
515 PageNum = 0; 503 PageNum = 0;
@@ -541,7 +529,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
541 529
542 /* 3 (3) null data * 1 page */ 530 /* 3 (3) null data * 1 page */
543 RsvdPageLoc.LocNullData = PageNum; 531 RsvdPageLoc.LocNullData = PageNum;
544 ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid(&pmlmeinfo->network), false, 0, 0, false); 532 ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, pnetwork->MacAddress, false, 0, 0, false);
545 rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false); 533 rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false);
546 534
547 PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); 535 PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);
@@ -551,7 +539,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
551 539
552 /* 3 (4) probe response * 1page */ 540 /* 3 (4) probe response * 1page */
553 RsvdPageLoc.LocProbeRsp = PageNum; 541 RsvdPageLoc.LocProbeRsp = PageNum;
554 ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&pmlmeinfo->network), false); 542 ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, pnetwork->MacAddress, false);
555 rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, false, false); 543 rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, false, false);
556 544
557 PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); 545 PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength);
@@ -562,7 +550,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
562 /* 3 (5) Qos null data */ 550 /* 3 (5) Qos null data */
563 RsvdPageLoc.LocQosNull = PageNum; 551 RsvdPageLoc.LocQosNull = PageNum;
564 ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], 552 ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex],
565 &QosNullLength, get_my_bssid(&pmlmeinfo->network), true, 0, 0, false); 553 &QosNullLength, pnetwork->MacAddress, true, 0, 0, false);
566 rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, false, false); 554 rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, false, false);
567 555
568 PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength); 556 PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength);
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
index 7d460eaafa35..3222d8d08b5b 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
@@ -242,20 +242,6 @@ void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
242 pHalFunc->hal_notch_filter = &hal_notch_filter_8188e; 242 pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
243} 243}
244 244
245u8 GetEEPROMSize8188E(struct adapter *padapter)
246{
247 u8 size = 0;
248 u32 cr;
249
250 cr = usb_read16(padapter, REG_9346CR);
251 /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
252 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
253
254 MSG_88E("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
255
256 return size;
257}
258
259/* */ 245/* */
260/* */ 246/* */
261/* LLT R/W/Init function */ 247/* LLT R/W/Init function */
diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h
index 82f58f87656a..3a274770364b 100644
--- a/drivers/staging/rtl8188eu/include/osdep_service.h
+++ b/drivers/staging/rtl8188eu/include/osdep_service.h
@@ -87,7 +87,7 @@ static inline void _init_timer(struct timer_list *ptimer,
87 87
88static inline void _set_timer(struct timer_list *ptimer, u32 delay_time) 88static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
89{ 89{
90 mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); 90 mod_timer(ptimer , (jiffies+msecs_to_jiffies(delay_time)));
91} 91}
92 92
93#define RTW_TIMER_HDL_ARGS void *FunctionContext 93#define RTW_TIMER_HDL_ARGS void *FunctionContext
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
index 0e78e2a357bd..42b1f22424eb 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
@@ -107,7 +107,6 @@ struct P2P_PS_CTWPeriod_t {
107/* host message to firmware cmd */ 107/* host message to firmware cmd */
108void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode); 108void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode);
109void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus); 109void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus);
110u8 rtl8188e_set_rssi_cmd(struct adapter *padapter, u8 *param);
111u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask); 110u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask);
112void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg, 111void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg,
113 u8 rssi_level); 112 u8 rssi_level);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
index 42ab1d288bdc..b8c42eed98c4 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
@@ -391,7 +391,6 @@ void rtl8188e_InitializeFirmwareVars(struct adapter *padapter);
391s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy); 391s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
392 392
393/* EFuse */ 393/* EFuse */
394u8 GetEEPROMSize8188E(struct adapter *padapter);
395void Hal_InitPGData88E(struct adapter *padapter); 394void Hal_InitPGData88E(struct adapter *padapter);
396void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo); 395void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
397void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo, 396void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
index 8d72ccf5f2a0..4f05aee93c9c 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
@@ -496,7 +496,6 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
496 struct adapter *adapter, bool update_ie); 496 struct adapter *adapter, bool update_ie);
497 497
498int get_bsstype(unsigned short capability); 498int get_bsstype(unsigned short capability);
499u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork);
500u16 get_beacon_interval(struct wlan_bssid_ex *bss); 499u16 get_beacon_interval(struct wlan_bssid_ex *bss);
501 500
502int is_client_associated_to_ap(struct adapter *padapter); 501int is_client_associated_to_ap(struct adapter *padapter);
@@ -516,7 +515,7 @@ void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE);
516void VCS_update(struct adapter *padapter, struct sta_info *psta); 515void VCS_update(struct adapter *padapter, struct sta_info *psta);
517 516
518void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len, 517void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len,
519 struct sta_info *psta); 518 struct sta_info *psta);
520int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len); 519int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len);
521void update_IOT_info(struct adapter *padapter); 520void update_IOT_info(struct adapter *padapter);
522void update_capinfo(struct adapter *adapter, u16 updatecap); 521void update_capinfo(struct adapter *adapter, u16 updatecap);
@@ -679,7 +678,6 @@ u8 read_bbreg_hdl(struct adapter *padapter, u8 *pbuf);
679u8 write_bbreg_hdl(struct adapter *padapter, u8 *pbuf); 678u8 write_bbreg_hdl(struct adapter *padapter, u8 *pbuf);
680u8 read_rfreg_hdl(struct adapter *padapter, u8 *pbuf); 679u8 read_rfreg_hdl(struct adapter *padapter, u8 *pbuf);
681u8 write_rfreg_hdl(struct adapter *padapter, u8 *pbuf); 680u8 write_rfreg_hdl(struct adapter *padapter, u8 *pbuf);
682u8 NULL_hdl(struct adapter *padapter, u8 *pbuf);
683u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf); 681u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf);
684u8 disconnect_hdl(struct adapter *padapter, u8 *pbuf); 682u8 disconnect_hdl(struct adapter *padapter, u8 *pbuf);
685u8 createbss_hdl(struct adapter *padapter, u8 *pbuf); 683u8 createbss_hdl(struct adapter *padapter, u8 *pbuf);
diff --git a/drivers/staging/rtl8188eu/include/usb_ops_linux.h b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
index 01b3810379ec..4fdc536cba79 100644
--- a/drivers/staging/rtl8188eu/include/usb_ops_linux.h
+++ b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
@@ -79,7 +79,6 @@ void usb_read_port_cancel(struct adapter *adapter);
79int usb_write8(struct adapter *adapter, u32 addr, u8 val); 79int usb_write8(struct adapter *adapter, u32 addr, u8 val);
80int usb_write16(struct adapter *adapter, u32 addr, u16 val); 80int usb_write16(struct adapter *adapter, u32 addr, u16 val);
81int usb_write32(struct adapter *adapter, u32 addr, u32 val); 81int usb_write32(struct adapter *adapter, u32 addr, u32 val);
82int usb_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata);
83 82
84u32 usb_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); 83u32 usb_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
85void usb_write_port_cancel(struct adapter *adapter); 84void usb_write_port_cancel(struct adapter *adapter);
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
index d2efa9dfc8c0..80e7ef96d807 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
@@ -615,33 +615,6 @@ int usb_write32(struct adapter *adapter, u32 addr, u32 val)
615 return ret; 615 return ret;
616} 616}
617 617
618int usb_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata)
619{
620 u8 request;
621 u8 requesttype;
622 u16 wvalue;
623 u16 index;
624 u16 len;
625 u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
626 int ret;
627
628
629 request = 0x05;
630 requesttype = 0x00;/* write_out */
631 index = 0;/* n/a */
632
633 wvalue = (u16)(addr&0x0000ffff);
634 len = length;
635 memcpy(buf, pdata, len);
636
637 ret = usbctrl_vendorreq(adapter, request, wvalue, index, buf, len, requesttype);
638
639
640 return RTW_STATUS_CODE(ret);
641}
642
643
644
645static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs) 618static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
646{ 619{
647 struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context; 620 struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
index 6c64e0899ffd..89ea70b0d3aa 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
@@ -167,35 +167,6 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
167 RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig); 167 RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig);
168} 168}
169 169
170void CAM_read_entry(struct net_device *dev, u32 iIndex)
171{
172 u32 target_command = 0;
173 u32 target_content = 0;
174 u8 entry_i = 0;
175 u32 ulStatus;
176 s32 i = 100;
177
178 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
179 target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
180 target_command = target_command | BIT31;
181
182 while ((i--) >= 0) {
183 ulStatus = read_nic_dword(dev, RWCAM);
184 if (ulStatus & BIT31)
185 continue;
186 else
187 break;
188 }
189 write_nic_dword(dev, RWCAM, target_command);
190 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x\n",
191 target_command);
192 target_content = read_nic_dword(dev, RCAMO);
193 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x\n",
194 target_content);
195 }
196 printk(KERN_INFO "\n");
197}
198
199void CamRestoreAllEntry(struct net_device *dev) 170void CamRestoreAllEntry(struct net_device *dev)
200{ 171{
201 u8 EntryId = 0; 172 u8 EntryId = 0;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
index 7d075d3cbe62..3c4c0e61c181 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
@@ -41,6 +41,4 @@ void write_cam(struct net_device *dev, u8 addr, u32 data);
41 41
42void CamRestoreAllEntry(struct net_device *dev); 42void CamRestoreAllEntry(struct net_device *dev);
43 43
44void CAM_read_entry(struct net_device *dev, u32 iIndex);
45
46#endif 44#endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
index 885315cac3a4..b8891c62af3e 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
@@ -1661,8 +1661,8 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev,
1661 dm_digtable.rssi_low_thresh = dm_value; 1661 dm_digtable.rssi_low_thresh = dm_value;
1662 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { 1662 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1663 dm_digtable.rssi_high_power_highthresh = dm_value; 1663 dm_digtable.rssi_high_power_highthresh = dm_value;
1664 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { 1664 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW) {
1665 dm_digtable.rssi_high_power_highthresh = dm_value; 1665 dm_digtable.rssi_high_power_lowthresh = dm_value;
1666 } else if (dm_type == DIG_TYPE_ENABLE) { 1666 } else if (dm_type == DIG_TYPE_ENABLE) {
1667 dm_digtable.dig_state = DM_STA_DIG_MAX; 1667 dm_digtable.dig_state = DM_STA_DIG_MAX;
1668 dm_digtable.dig_enable_flag = true; 1668 dm_digtable.dig_enable_flag = true;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
index 8e1a5d55dce8..0b4f76481bf4 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
@@ -22,12 +22,6 @@
22#include "r8190P_rtl8256.h" 22#include "r8190P_rtl8256.h"
23#include "rtl_pm.h" 23#include "rtl_pm.h"
24 24
25int rtl8192E_save_state(struct pci_dev *dev, pm_message_t state)
26{
27 printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event);
28 return -EAGAIN;
29}
30
31 25
32int rtl8192E_suspend(struct pci_dev *pdev, pm_message_t state) 26int rtl8192E_suspend(struct pci_dev *pdev, pm_message_t state)
33{ 27{
@@ -124,11 +118,3 @@ out:
124 return 0; 118 return 0;
125} 119}
126 120
127
128int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable)
129{
130 printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n",
131 state.event, enable);
132 return -EAGAIN;
133}
134
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
index e5299fc3b34a..7bfe44817f23 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
@@ -23,9 +23,7 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25 25
26int rtl8192E_save_state(struct pci_dev *dev, pm_message_t state);
27int rtl8192E_suspend(struct pci_dev *dev, pm_message_t state); 26int rtl8192E_suspend(struct pci_dev *dev, pm_message_t state);
28int rtl8192E_resume(struct pci_dev *dev); 27int rtl8192E_resume(struct pci_dev *dev);
29int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable);
30 28
31#endif 29#endif
diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c
index c7f45080061f..1ea426b7b7ac 100644
--- a/drivers/staging/rtl8192e/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c
@@ -34,13 +34,13 @@ u16 MCS_DATA_RATE[2][2][77] = {
34 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 34 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
35 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156, 35 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
36 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273, 36 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
37 312, 351, 312, 351, 390, 390, 429} , 37 312, 351, 312, 351, 390, 390, 429},
38 {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, 38 {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
39 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 39 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
40 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 40 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
41 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 41 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
42 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 42 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
43 433, 433, 477} } , 43 433, 433, 477} },
44 {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 44 {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
45 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 45 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
46 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 46 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c
index 91e98e8e5bfc..0cf38091f8c5 100644
--- a/drivers/staging/rtl8192e/rtllib_module.c
+++ b/drivers/staging/rtl8192e/rtllib_module.c
@@ -202,9 +202,7 @@ void free_rtllib(struct net_device *dev)
202EXPORT_SYMBOL(free_rtllib); 202EXPORT_SYMBOL(free_rtllib);
203 203
204u32 rtllib_debug_level; 204u32 rtllib_debug_level;
205static int debug = \ 205static int debug = RTLLIB_DL_ERR;
206 RTLLIB_DL_ERR
207 ;
208static struct proc_dir_entry *rtllib_proc; 206static struct proc_dir_entry *rtllib_proc;
209 207
210static int show_debug_level(struct seq_file *m, void *v) 208static int show_debug_level(struct seq_file *m, void *v)
diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
index cf11b042b93a..1664040efdab 100644
--- a/drivers/staging/rtl8192e/rtllib_rx.c
+++ b/drivers/staging/rtl8192e/rtllib_rx.c
@@ -70,8 +70,7 @@ rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq,
70 if (entry->skb != NULL && 70 if (entry->skb != NULL &&
71 time_after(jiffies, entry->first_frag_time + 2 * HZ)) { 71 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
72 RTLLIB_DEBUG_FRAG( 72 RTLLIB_DEBUG_FRAG(
73 "expiring fragment cache entry " 73 "expiring fragment cache entry seq=%u last_frag=%u\n",
74 "seq=%u last_frag=%u\n",
75 entry->seq, entry->last_frag); 74 entry->seq, entry->last_frag);
76 dev_kfree_skb_any(entry->skb); 75 dev_kfree_skb_any(entry->skb);
77 entry->skb = NULL; 76 entry->skb = NULL;
@@ -188,8 +187,7 @@ static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee,
188 187
189 if (entry == NULL) { 188 if (entry == NULL) {
190 RTLLIB_DEBUG_FRAG( 189 RTLLIB_DEBUG_FRAG(
191 "could not invalidate fragment cache " 190 "could not invalidate fragment cache entry (seq=%u)\n", seq);
192 "entry (seq=%u)\n", seq);
193 return -1; 191 return -1;
194 } 192 }
195 193
@@ -305,11 +303,9 @@ rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
305 atomic_dec(&crypt->refcnt); 303 atomic_dec(&crypt->refcnt);
306 if (res < 0) { 304 if (res < 0) {
307 RTLLIB_DEBUG_DROP( 305 RTLLIB_DEBUG_DROP(
308 "decryption failed (SA= %pM" 306 "decryption failed (SA= %pM) res=%d\n", hdr->addr2, res);
309 ") res=%d\n", hdr->addr2, res);
310 if (res == -2) 307 if (res == -2)
311 RTLLIB_DEBUG_DROP("Decryption failed ICV " 308 RTLLIB_DEBUG_DROP("Decryption failed ICV mismatch (key %d)\n",
312 "mismatch (key %d)\n",
313 skb->data[hdrlen + 3] >> 6); 309 skb->data[hdrlen + 3] >> 6);
314 ieee->ieee_stats.rx_discards_undecryptable++; 310 ieee->ieee_stats.rx_discards_undecryptable++;
315 return -1; 311 return -1;
@@ -345,8 +341,7 @@ rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb,
345 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); 341 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
346 atomic_dec(&crypt->refcnt); 342 atomic_dec(&crypt->refcnt);
347 if (res < 0) { 343 if (res < 0) {
348 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" 344 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed (SA= %pM keyidx=%d)\n",
349 " (SA= %pM keyidx=%d)\n",
350 ieee->dev->name, hdr->addr2, keyidx); 345 ieee->dev->name, hdr->addr2, keyidx);
351 return -1; 346 return -1;
352 } 347 }
@@ -559,8 +554,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
559 bool bMatchWinStart = false, bPktInBuf = false; 554 bool bMatchWinStart = false, bPktInBuf = false;
560 unsigned long flags; 555 unsigned long flags;
561 556
562 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Seq is %d, pTS->RxIndicateSeq" 557 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Seq is %d, pTS->RxIndicateSeq is %d, WinSize is %d\n", __func__, SeqNum,
563 " is %d, WinSize is %d\n", __func__, SeqNum,
564 pTS->RxIndicateSeq, WinSize); 558 pTS->RxIndicateSeq, WinSize);
565 559
566 spin_lock_irqsave(&(ieee->reorder_spinlock), flags); 560 spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
@@ -600,8 +594,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
600 pTS->RxIndicateSeq = SeqNum + 1 - WinSize; 594 pTS->RxIndicateSeq = SeqNum + 1 - WinSize;
601 else 595 else
602 pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum + 1)) + 1; 596 pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum + 1)) + 1;
603 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d," 597 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum);
604 " NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum);
605 } 598 }
606 599
607 /* 600 /*
@@ -617,8 +610,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
617 */ 610 */
618 if (bMatchWinStart) { 611 if (bMatchWinStart) {
619 /* Current packet is going to be indicated.*/ 612 /* Current packet is going to be indicated.*/
620 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! " 613 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",
621 "IndicateSeq: %d, NewSeq: %d\n",
622 pTS->RxIndicateSeq, SeqNum); 614 pTS->RxIndicateSeq, SeqNum);
623 ieee->prxbIndicateArray[0] = prxb; 615 ieee->prxbIndicateArray[0] = prxb;
624 index = 1; 616 index = 1;
@@ -636,9 +628,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
636 628
637 if (!AddReorderEntry(pTS, pReorderEntry)) { 629 if (!AddReorderEntry(pTS, pReorderEntry)) {
638 RTLLIB_DEBUG(RTLLIB_DL_REORDER, 630 RTLLIB_DEBUG(RTLLIB_DL_REORDER,
639 "%s(): Duplicate packet is " 631 "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
640 "dropped!! IndicateSeq: %d, "
641 "NewSeq: %d\n",
642 __func__, pTS->RxIndicateSeq, 632 __func__, pTS->RxIndicateSeq,
643 SeqNum); 633 SeqNum);
644 list_add_tail(&pReorderEntry->List, 634 list_add_tail(&pReorderEntry->List,
@@ -652,8 +642,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
652 } 642 }
653 } else { 643 } else {
654 RTLLIB_DEBUG(RTLLIB_DL_REORDER, 644 RTLLIB_DEBUG(RTLLIB_DL_REORDER,
655 "Pkt insert into struct buffer!! " 645 "Pkt insert into struct buffer!! IndicateSeq: %d, NewSeq: %d\n",
656 "IndicateSeq: %d, NewSeq: %d\n",
657 pTS->RxIndicateSeq, SeqNum); 646 pTS->RxIndicateSeq, SeqNum);
658 } 647 }
659 } else { 648 } else {
@@ -663,9 +652,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
663 * indicate all the packets in struct buffer and get 652 * indicate all the packets in struct buffer and get
664 * reorder entries. 653 * reorder entries.
665 */ 654 */
666 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():" 655 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
667 " There is no reorder entry!! Packet is "
668 "dropped!!\n");
669 { 656 {
670 int i; 657 int i;
671 658
@@ -687,8 +674,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
687 SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) { 674 SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) {
688 /* This protect struct buffer from overflow. */ 675 /* This protect struct buffer from overflow. */
689 if (index >= REORDER_WIN_SIZE) { 676 if (index >= REORDER_WIN_SIZE) {
690 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicate" 677 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!!\n");
691 "Packet(): Buffer overflow!!\n");
692 bPktInBuf = true; 678 bPktInBuf = true;
693 break; 679 break;
694 } 680 }
@@ -699,8 +685,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
699 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; 685 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
700 686
701 ieee->prxbIndicateArray[index] = pReorderEntry->prxb; 687 ieee->prxbIndicateArray[index] = pReorderEntry->prxb;
702 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum" 688 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum %d!\n", __func__, pReorderEntry->SeqNum);
703 " %d!\n", __func__, pReorderEntry->SeqNum);
704 index++; 689 index++;
705 690
706 list_add_tail(&pReorderEntry->List, 691 list_add_tail(&pReorderEntry->List,
@@ -719,8 +704,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
719 pTS->RxTimeoutIndicateSeq = 0xffff; 704 pTS->RxTimeoutIndicateSeq = 0xffff;
720 705
721 if (index > REORDER_WIN_SIZE) { 706 if (index > REORDER_WIN_SIZE) {
722 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():" 707 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder struct buffer full!!\n");
723 " Rx Reorder struct buffer full!!\n");
724 spin_unlock_irqrestore(&(ieee->reorder_spinlock), 708 spin_unlock_irqrestore(&(ieee->reorder_spinlock),
725 flags); 709 flags);
726 return; 710 return;
@@ -809,14 +793,11 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb,
809 (nSubframe_Length << 8); 793 (nSubframe_Length << 8);
810 794
811 if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { 795 if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
812 printk(KERN_INFO "%s: A-MSDU parse error!! " 796 printk(KERN_INFO "%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
813 "pRfd->nTotalSubframe : %d\n",\
814 __func__, rxb->nr_subframes); 797 __func__, rxb->nr_subframes);
815 printk(KERN_INFO "%s: A-MSDU parse error!! " 798 printk(KERN_INFO "%s: A-MSDU parse error!! Subframe Length: %d\n", __func__,
816 "Subframe Length: %d\n", __func__,
817 nSubframe_Length); 799 nSubframe_Length);
818 printk(KERN_INFO "nRemain_Length is %d and " 800 printk(KERN_INFO "nRemain_Length is %d and nSubframe_Length is : %d\n", skb->len,
819 "nSubframe_Length is : %d\n", skb->len,
820 nSubframe_Length); 801 nSubframe_Length);
821 printk(KERN_INFO "The Packet SeqNum is %d\n", SeqNum); 802 printk(KERN_INFO "The Packet SeqNum is %d\n", SeqNum);
822 return 0; 803 return 0;
@@ -844,8 +825,7 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb,
844 sub_skb->dev = ieee->dev; 825 sub_skb->dev = ieee->dev;
845 rxb->subframes[rxb->nr_subframes++] = sub_skb; 826 rxb->subframes[rxb->nr_subframes++] = sub_skb;
846 if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { 827 if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
847 RTLLIB_DEBUG_RX("ParseSubframe(): Too many " 828 RTLLIB_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
848 "Subframes! Packets dropped!\n");
849 break; 829 break;
850 } 830 }
851 skb_pull(skb, nSubframe_Length); 831 skb_pull(skb, nSubframe_Length);
@@ -922,8 +902,7 @@ static int rtllib_rx_check_duplicate(struct rtllib_device *ieee,
922 pRxTS->RxLastFragNum = frag; 902 pRxTS->RxLastFragNum = frag;
923 pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc); 903 pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
924 } else { 904 } else {
925 RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip" 905 RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip the check!!\n", __func__);
926 " the check!!\n", __func__);
927 return -1; 906 return -1;
928 } 907 }
929 } 908 }
@@ -996,9 +975,7 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc,
996 stype != RTLLIB_STYPE_QOS_DATA) { 975 stype != RTLLIB_STYPE_QOS_DATA) {
997 if (stype != RTLLIB_STYPE_NULLFUNC) 976 if (stype != RTLLIB_STYPE_NULLFUNC)
998 RTLLIB_DEBUG_DROP( 977 RTLLIB_DEBUG_DROP(
999 "RX: dropped data frame " 978 "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n",
1000 "with no data (type=0x%02x, "
1001 "subtype=0x%02x)\n",
1002 type, stype); 979 type, stype);
1003 return -1; 980 return -1;
1004 } 981 }
@@ -1041,8 +1018,7 @@ static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb,
1041 * frames from other than current BSS, so just drop the 1018 * frames from other than current BSS, so just drop the
1042 * frames silently instead of filling system log with 1019 * frames silently instead of filling system log with
1043 * these reports. */ 1020 * these reports. */
1044 RTLLIB_DEBUG_DROP("Decryption failed (not set)" 1021 RTLLIB_DEBUG_DROP("Decryption failed (not set) (SA= %pM)\n",
1045 " (SA= %pM)\n",
1046 hdr->addr2); 1022 hdr->addr2);
1047 ieee->ieee_stats.rx_discards_undecryptable++; 1023 ieee->ieee_stats.rx_discards_undecryptable++;
1048 return -1; 1024 return -1;
@@ -1086,8 +1062,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
1086 1062
1087 if (!frag_skb) { 1063 if (!frag_skb) {
1088 RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG, 1064 RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG,
1089 "Rx cannot get skb from fragment " 1065 "Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n",
1090 "cache (morefrag=%d seq=%u frag=%u)\n",
1091 (fc & RTLLIB_FCTL_MOREFRAGS) != 0, 1066 (fc & RTLLIB_FCTL_MOREFRAGS) != 0,
1092 WLAN_GET_SEQ_SEQ(sc), frag); 1067 WLAN_GET_SEQ_SEQ(sc), frag);
1093 return -1; 1068 return -1;
@@ -1097,8 +1072,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
1097 flen -= hdrlen; 1072 flen -= hdrlen;
1098 1073
1099 if (frag_skb->tail + flen > frag_skb->end) { 1074 if (frag_skb->tail + flen > frag_skb->end) {
1100 printk(KERN_WARNING "%s: host decrypted and " 1075 printk(KERN_WARNING "%s: host decrypted and reassembled frame did not fit skb\n",
1101 "reassembled frame did not fit skb\n",
1102 __func__); 1076 __func__);
1103 rtllib_frag_cache_invalidate(ieee, hdr); 1077 rtllib_frag_cache_invalidate(ieee, hdr);
1104 return -1; 1078 return -1;
@@ -1152,8 +1126,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
1152 eap_get_type(eap->type)); 1126 eap_get_type(eap->type));
1153 } else { 1127 } else {
1154 RTLLIB_DEBUG_DROP( 1128 RTLLIB_DEBUG_DROP(
1155 "encryption configured, but RX " 1129 "encryption configured, but RX frame not encrypted (SA= %pM)\n",
1156 "frame not encrypted (SA= %pM)\n",
1157 hdr->addr2); 1130 hdr->addr2);
1158 return -1; 1131 return -1;
1159 } 1132 }
@@ -1170,9 +1143,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
1170 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep && 1143 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep &&
1171 !rtllib_is_eapol_frame(ieee, skb, hdrlen)) { 1144 !rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1172 RTLLIB_DEBUG_DROP( 1145 RTLLIB_DEBUG_DROP(
1173 "dropped unencrypted RX data " 1146 "dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n",
1174 "frame from %pM"
1175 " (drop_unencrypted=1)\n",
1176 hdr->addr2); 1147 hdr->addr2);
1177 return -1; 1148 return -1;
1178 } 1149 }
@@ -1762,9 +1733,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee,
1762 1733
1763 while (length >= sizeof(*info_element)) { 1734 while (length >= sizeof(*info_element)) {
1764 if (sizeof(*info_element) + info_element->len > length) { 1735 if (sizeof(*info_element) + info_element->len > length) {
1765 RTLLIB_DEBUG_MGMT("Info elem: parse failed: " 1736 RTLLIB_DEBUG_MGMT("Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=%zd left=%d, id=%d.\n",
1766 "info_element->len + 2 > left : "
1767 "info_element->len+2=%zd left=%d, id=%d.\n",
1768 info_element->len + 1737 info_element->len +
1769 sizeof(*info_element), 1738 sizeof(*info_element),
1770 length, info_element->id); 1739 length, info_element->id);
@@ -2207,34 +2176,6 @@ int rtllib_parse_info_param(struct rtllib_device *ieee,
2207 return 0; 2176 return 0;
2208} 2177}
2209 2178
2210static inline u8 rtllib_SignalStrengthTranslate(u8 CurrSS)
2211{
2212 u8 RetSS;
2213
2214 if (CurrSS >= 71 && CurrSS <= 100)
2215 RetSS = 90 + ((CurrSS - 70) / 3);
2216 else if (CurrSS >= 41 && CurrSS <= 70)
2217 RetSS = 78 + ((CurrSS - 40) / 3);
2218 else if (CurrSS >= 31 && CurrSS <= 40)
2219 RetSS = 66 + (CurrSS - 30);
2220 else if (CurrSS >= 21 && CurrSS <= 30)
2221 RetSS = 54 + (CurrSS - 20);
2222 else if (CurrSS >= 5 && CurrSS <= 20)
2223 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
2224 else if (CurrSS == 4)
2225 RetSS = 36;
2226 else if (CurrSS == 3)
2227 RetSS = 27;
2228 else if (CurrSS == 2)
2229 RetSS = 18;
2230 else if (CurrSS == 1)
2231 RetSS = 9;
2232 else
2233 RetSS = CurrSS;
2234
2235 return RetSS;
2236}
2237
2238static long rtllib_translate_todbm(u8 signal_strength_index) 2179static long rtllib_translate_todbm(u8 signal_strength_index)
2239{ 2180{
2240 long signal_power; 2181 long signal_power;
@@ -2321,8 +2262,7 @@ static inline int rtllib_network_init(
2321 } 2262 }
2322 2263
2323 if (network->mode == 0) { 2264 if (network->mode == 0) {
2324 RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' " 2265 RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' network.\n",
2325 "network.\n",
2326 escape_essid(network->ssid, 2266 escape_essid(network->ssid,
2327 network->ssid_len), 2267 network->ssid_len),
2328 network->bssid); 2268 network->bssid);
@@ -2363,13 +2303,6 @@ static inline int is_same_network(struct rtllib_network *src,
2363 (dst->capability & WLAN_CAPABILITY_ESS))); 2303 (dst->capability & WLAN_CAPABILITY_ESS)));
2364} 2304}
2365 2305
2366static inline void update_ibss_network(struct rtllib_network *dst,
2367 struct rtllib_network *src)
2368{
2369 memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
2370 dst->last_scanned = jiffies;
2371}
2372
2373 2306
2374static inline void update_network(struct rtllib_network *dst, 2307static inline void update_network(struct rtllib_network *dst,
2375 struct rtllib_network *src) 2308 struct rtllib_network *src)
@@ -2568,8 +2501,7 @@ static inline void rtllib_process_probe_response(
2568 if (WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)) == 2501 if (WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)) ==
2569 RTLLIB_STYPE_PROBE_RESP) { 2502 RTLLIB_STYPE_PROBE_RESP) {
2570 if (IsPassiveChannel(ieee, network->channel)) { 2503 if (IsPassiveChannel(ieee, network->channel)) {
2571 printk(KERN_INFO "GetScanInfo(): For Global Domain, " 2504 printk(KERN_INFO "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n",
2572 "filter probe response at channel(%d).\n",
2573 network->channel); 2505 network->channel);
2574 goto free_network; 2506 goto free_network;
2575 } 2507 }
@@ -2618,8 +2550,7 @@ static inline void rtllib_process_probe_response(
2618 /* If there are no more slots, expire the oldest */ 2550 /* If there are no more slots, expire the oldest */
2619 list_del(&oldest->list); 2551 list_del(&oldest->list);
2620 target = oldest; 2552 target = oldest;
2621 RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from " 2553 RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from network list.\n",
2622 "network list.\n",
2623 escape_essid(target->ssid, 2554 escape_essid(target->ssid,
2624 target->ssid_len), 2555 target->ssid_len),
2625 target->bssid); 2556 target->bssid);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
index cd196cec0dd9..1b4623c3f95e 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -4,6 +4,8 @@
4 * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. 4 * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
5 * WB 2008-05-27 5 * WB 2008-05-27
6 * *****************************************************************************************************************************/ 6 * *****************************************************************************************************************************/
7#include <asm/byteorder.h>
8#include <asm/unaligned.h>
7#include "ieee80211.h" 9#include "ieee80211.h"
8#include "rtl819x_BA.h" 10#include "rtl819x_BA.h"
9 11
@@ -110,13 +112,12 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
110 struct sk_buff *skb = NULL; 112 struct sk_buff *skb = NULL;
111 struct ieee80211_hdr_3addr *BAReq = NULL; 113 struct ieee80211_hdr_3addr *BAReq = NULL;
112 u8 *tag = NULL; 114 u8 *tag = NULL;
113 __le16 tmp = 0;
114 u16 len = ieee->tx_headroom + 9; 115 u16 len = ieee->tx_headroom + 9;
115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) 116 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev); 117 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev);
117 if (pBA == NULL||ieee == NULL) 118 if (pBA == NULL)
118 { 119 {
119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); 120 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA is NULL\n");
120 return NULL; 121 return NULL;
121 } 122 }
122 skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME 123 skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
@@ -149,17 +150,17 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
149 { 150 {
150 // Status Code 151 // Status Code
151 printk("=====>to send ADDBARSP\n"); 152 printk("=====>to send ADDBARSP\n");
152 tmp = cpu_to_le16(StatusCode); 153
153 memcpy(tag, (u8 *)&tmp, 2); 154 put_unaligned_le16(StatusCode, tag);
154 tag += 2; 155 tag += 2;
155 } 156 }
156 // BA Parameter Set 157 // BA Parameter Set
157 tmp = cpu_to_le16(pBA->BaParamSet.shortData); 158
158 memcpy(tag, (u8 *)&tmp, 2); 159 put_unaligned_le16(pBA->BaParamSet.shortData, tag);
159 tag += 2; 160 tag += 2;
160 // BA Timeout Value 161 // BA Timeout Value
161 tmp = cpu_to_le16(pBA->BaTimeoutValue); 162
162 memcpy(tag, (u8 *)&tmp, 2); 163 put_unaligned_le16(pBA->BaTimeoutValue, tag);
163 tag += 2; 164 tag += 2;
164 165
165 if (ACT_ADDBAREQ == type) 166 if (ACT_ADDBAREQ == type)
@@ -196,7 +197,6 @@ static struct sk_buff *ieee80211_DELBA(
196 struct sk_buff *skb = NULL; 197 struct sk_buff *skb = NULL;
197 struct ieee80211_hdr_3addr *Delba = NULL; 198 struct ieee80211_hdr_3addr *Delba = NULL;
198 u8 *tag = NULL; 199 u8 *tag = NULL;
199 __le16 tmp = 0;
200 //len = head len + DELBA Parameter Set(2) + Reason Code(2) 200 //len = head len + DELBA Parameter Set(2) + Reason Code(2)
201 u16 len = 6 + ieee->tx_headroom; 201 u16 len = 6 + ieee->tx_headroom;
202 202
@@ -230,12 +230,12 @@ static struct sk_buff *ieee80211_DELBA(
230 *tag ++= ACT_DELBA; 230 *tag ++= ACT_DELBA;
231 231
232 // DELBA Parameter Set 232 // DELBA Parameter Set
233 tmp = cpu_to_le16(DelbaParamSet.shortData); 233
234 memcpy(tag, (u8 *)&tmp, 2); 234 put_unaligned_le16(DelbaParamSet.shortData, tag);
235 tag += 2; 235 tag += 2;
236 // Reason Code 236 // Reason Code
237 tmp = cpu_to_le16(ReasonCode); 237
238 memcpy(tag, (u8 *)&tmp, 2); 238 put_unaligned_le16(ReasonCode, tag);
239 tag += 2; 239 tag += 2;
240 240
241 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); 241 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
index c4514109d0ee..acaa723817e7 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
@@ -241,7 +241,7 @@ static PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee,
241{ 241{
242 //DIRECTION_VALUE dir; 242 //DIRECTION_VALUE dir;
243 u8 dir; 243 u8 dir;
244 bool search_dir[4] = {0, 0, 0, 0}; 244 bool search_dir[4] = {0};
245 struct list_head *psearch_list; //FIXME 245 struct list_head *psearch_list; //FIXME
246 PTS_COMMON_INFO pRet = NULL; 246 PTS_COMMON_INFO pRet = NULL;
247 if(ieee->iw_mode == IW_MODE_MASTER) //ap mode 247 if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c
index 45514aa97698..1868352d3789 100644
--- a/drivers/staging/rtl8192u/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.c
@@ -23,7 +23,7 @@
23 * Return: NONE 23 * Return: NONE
24 * Note: 8226 support both 20M and 40 MHz 24 * Note: 8226 support both 20M and 40 MHz
25 *---------------------------------------------------------------------------*/ 25 *---------------------------------------------------------------------------*/
26void PHY_SetRF8256Bandwidth(struct net_device *dev , HT_CHANNEL_WIDTH Bandwidth) 26void PHY_SetRF8256Bandwidth(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth)
27{ 27{
28 u8 eRFPath; 28 u8 eRFPath;
29 struct r8192_priv *priv = ieee80211_priv(dev); 29 struct r8192_priv *priv = ieee80211_priv(dev);
diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
index 936565d46014..ee6b936efef2 100644
--- a/drivers/staging/rtl8192u/r8192U_dm.c
+++ b/drivers/staging/rtl8192u/r8192U_dm.c
@@ -21,14 +21,13 @@ Major Change History:
21#include "r8190_rtl8256.h" 21#include "r8190_rtl8256.h"
22#include "r819xU_cmdpkt.h" 22#include "r819xU_cmdpkt.h"
23/*---------------------------Define Local Constant---------------------------*/ 23/*---------------------------Define Local Constant---------------------------*/
24// 24/* Indicate different AP vendor for IOT issue. */
25// Indicate different AP vendor for IOT issue. 25static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
26// 26 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f
27static u32 edca_setting_DL[HT_IOT_PEER_MAX] = 27};
28 { 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f}; 28static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
29static u32 edca_setting_UL[HT_IOT_PEER_MAX] = 29 0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f
30 { 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f}; 30};
31
32 31
33#define RTK_UL_EDCA 0xa44f 32#define RTK_UL_EDCA 0xa44f
34#define RTK_DL_EDCA 0x5e4322 33#define RTK_DL_EDCA 0x5e4322
@@ -36,11 +35,11 @@ static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
36 35
37 36
38/*------------------------Define global variable-----------------------------*/ 37/*------------------------Define global variable-----------------------------*/
39// Debug variable ? 38/* Debug variable ? */
40dig_t dm_digtable; 39dig_t dm_digtable;
41// Store current software write register content for MAC PHY. 40/* Store current software write register content for MAC PHY. */
42u8 dm_shadow[16][256] = {{0}}; 41u8 dm_shadow[16][256] = { {0} };
43// For Dynamic Rx Path Selection by Signal Strength 42/* For Dynamic Rx Path Selection by Signal Strength */
44DRxPathSel DM_RxPathSelTable; 43DRxPathSel DM_RxPathSelTable;
45/*------------------------Define global variable-----------------------------*/ 44/*------------------------Define global variable-----------------------------*/
46 45
@@ -56,24 +55,21 @@ extern void dm_check_fsync(struct net_device *dev);
56 55
57 56
58/*---------------------Define local function prototype-----------------------*/ 57/*---------------------Define local function prototype-----------------------*/
59// DM --> Rate Adaptive 58/* DM --> Rate Adaptive */
60static void dm_check_rate_adaptive(struct net_device *dev); 59static void dm_check_rate_adaptive(struct net_device *dev);
61 60
62// DM --> Bandwidth switch 61/* DM --> Bandwidth switch */
63static void dm_init_bandwidth_autoswitch(struct net_device *dev); 62static void dm_init_bandwidth_autoswitch(struct net_device *dev);
64static void dm_bandwidth_autoswitch(struct net_device *dev); 63static void dm_bandwidth_autoswitch(struct net_device *dev);
65 64
66// DM --> TX power control 65/* DM --> TX power control */
67//static void dm_initialize_txpower_tracking(struct net_device *dev); 66/*static void dm_initialize_txpower_tracking(struct net_device *dev);*/
68 67
69static void dm_check_txpower_tracking(struct net_device *dev); 68static void dm_check_txpower_tracking(struct net_device *dev);
70 69
70/*static void dm_txpower_reset_recovery(struct net_device *dev);*/
71 71
72 72/* DM --> Dynamic Init Gain by RSSI */
73//static void dm_txpower_reset_recovery(struct net_device *dev);
74
75
76// DM --> Dynamic Init Gain by RSSI
77static void dm_dig_init(struct net_device *dev); 73static void dm_dig_init(struct net_device *dev);
78static void dm_ctrl_initgain_byrssi(struct net_device *dev); 74static void dm_ctrl_initgain_byrssi(struct net_device *dev);
79static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); 75static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
@@ -84,61 +80,58 @@ static void dm_pd_th(struct net_device *dev);
84static void dm_cs_ratio(struct net_device *dev); 80static void dm_cs_ratio(struct net_device *dev);
85 81
86static void dm_init_ctstoself(struct net_device *dev); 82static void dm_init_ctstoself(struct net_device *dev);
87// DM --> EDCA turbo mode control 83/* DM --> EDCA turbo mode control */
88static void dm_check_edca_turbo(struct net_device *dev); 84static void dm_check_edca_turbo(struct net_device *dev);
89 85
90//static void dm_gpio_change_rf(struct net_device *dev); 86/*static void dm_gpio_change_rf(struct net_device *dev);*/
91// DM --> Check PBC 87/* DM --> Check PBC */
92static void dm_check_pbc_gpio(struct net_device *dev); 88static void dm_check_pbc_gpio(struct net_device *dev);
93 89
94 90/* DM --> Check current RX RF path state */
95// DM --> Check current RX RF path state
96static void dm_check_rx_path_selection(struct net_device *dev); 91static void dm_check_rx_path_selection(struct net_device *dev);
97static void dm_init_rxpath_selection(struct net_device *dev); 92static void dm_init_rxpath_selection(struct net_device *dev);
98static void dm_rxpath_sel_byrssi(struct net_device *dev); 93static void dm_rxpath_sel_byrssi(struct net_device *dev);
99 94
100 95/* DM --> Fsync for broadcom ap */
101// DM --> Fsync for broadcom ap
102static void dm_init_fsync(struct net_device *dev); 96static void dm_init_fsync(struct net_device *dev);
103static void dm_deInit_fsync(struct net_device *dev); 97static void dm_deInit_fsync(struct net_device *dev);
104 98
105//Added by vivi, 20080522 99/* Added by vivi, 20080522 */
106static void dm_check_txrateandretrycount(struct net_device *dev); 100static void dm_check_txrateandretrycount(struct net_device *dev);
107 101
108/*---------------------Define local function prototype-----------------------*/ 102/*---------------------Define local function prototype-----------------------*/
109 103
110/*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18 104/*---------------------Define of Tx Power Control For Near/Far Range --------*/ /*Add by Jacken 2008/02/18 */
111static void dm_init_dynamic_txpower(struct net_device *dev); 105static void dm_init_dynamic_txpower(struct net_device *dev);
112static void dm_dynamic_txpower(struct net_device *dev); 106static void dm_dynamic_txpower(struct net_device *dev);
113 107
114 108/* DM --> For rate adaptive and DIG, we must send RSSI to firmware */
115// DM --> For rate adaptive and DIG, we must send RSSI to firmware
116static void dm_send_rssi_tofw(struct net_device *dev); 109static void dm_send_rssi_tofw(struct net_device *dev);
117static void dm_ctstoself(struct net_device *dev); 110static void dm_ctstoself(struct net_device *dev);
118/*---------------------------Define function prototype------------------------*/ 111/*---------------------------Define function prototype------------------------*/
119//================================================================================ 112/*
120// HW Dynamic mechanism interface. 113 * ================================================================================
121//================================================================================ 114 * HW Dynamic mechanism interface.
122 115 * ================================================================================
123// 116 *
124// Description: 117 *
125// Prepare SW resource for HW dynamic mechanism. 118 * Description:
126// 119 * Prepare SW resource for HW dynamic mechanism.
127// Assumption: 120 *
128// This function is only invoked at driver intialization once. 121 * Assumption:
129// 122 * This function is only invoked at driver intialization once.
130// 123 */
131void init_hal_dm(struct net_device *dev) 124void init_hal_dm(struct net_device *dev)
132{ 125{
133 struct r8192_priv *priv = ieee80211_priv(dev); 126 struct r8192_priv *priv = ieee80211_priv(dev);
134 127
135 // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. 128 /* Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. */
136 priv->undecorated_smoothed_pwdb = -1; 129 priv->undecorated_smoothed_pwdb = -1;
137 130
138 //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. 131 /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
139 dm_init_dynamic_txpower(dev); 132 dm_init_dynamic_txpower(dev);
140 init_rate_adaptive(dev); 133 init_rate_adaptive(dev);
141 //dm_initialize_txpower_tracking(dev); 134 /*dm_initialize_txpower_tracking(dev);*/
142 dm_dig_init(dev); 135 dm_dig_init(dev);
143 dm_init_edca_turbo(dev); 136 dm_init_edca_turbo(dev);
144 dm_init_bandwidth_autoswitch(dev); 137 dm_init_bandwidth_autoswitch(dev);
@@ -146,18 +139,16 @@ void init_hal_dm(struct net_device *dev)
146 dm_init_rxpath_selection(dev); 139 dm_init_rxpath_selection(dev);
147 dm_init_ctstoself(dev); 140 dm_init_ctstoself(dev);
148 141
149} // InitHalDm 142} /* InitHalDm */
150 143
151void deinit_hal_dm(struct net_device *dev) 144void deinit_hal_dm(struct net_device *dev)
152{ 145{
153
154 dm_deInit_fsync(dev); 146 dm_deInit_fsync(dev);
155
156} 147}
157 148
158
159#ifdef USB_RX_AGGREGATION_SUPPORT 149#ifdef USB_RX_AGGREGATION_SUPPORT
160void dm_CheckRxAggregation(struct net_device *dev) { 150void dm_CheckRxAggregation(struct net_device *dev)
151{
161 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); 152 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
162 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; 153 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
163 static unsigned long lastTxOkCnt; 154 static unsigned long lastTxOkCnt;
@@ -186,14 +177,15 @@ void dm_CheckRxAggregation(struct net_device *dev) {
186 if ((curTxOkCnt + curRxOkCnt) < 15000000) 177 if ((curTxOkCnt + curRxOkCnt) < 15000000)
187 return; 178 return;
188 179
189 if(curTxOkCnt > 4*curRxOkCnt) { 180 if (curTxOkCnt > 4*curRxOkCnt) {
190 if (priv->bCurrentRxAggrEnable) { 181 if (priv->bCurrentRxAggrEnable) {
191 write_nic_dword(dev, 0x1a8, 0); 182 write_nic_dword(dev, 0x1a8, 0);
192 priv->bCurrentRxAggrEnable = false; 183 priv->bCurrentRxAggrEnable = false;
193 } 184 }
194 }else{ 185 } else {
195 if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) { 186 if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
196 u32 ulValue; 187 u32 ulValue;
188
197 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) | 189 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
198 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout); 190 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
199 /* 191 /*
@@ -208,16 +200,14 @@ void dm_CheckRxAggregation(struct net_device *dev) {
208 200
209 lastTxOkCnt = priv->stats.txbytesunicast; 201 lastTxOkCnt = priv->stats.txbytesunicast;
210 lastRxOkCnt = priv->stats.rxbytesunicast; 202 lastRxOkCnt = priv->stats.rxbytesunicast;
211} // dm_CheckEdcaTurbo 203} /* dm_CheckEdcaTurbo */
212#endif 204#endif
213 205
214
215
216void hal_dm_watchdog(struct net_device *dev) 206void hal_dm_watchdog(struct net_device *dev)
217{ 207{
218 //struct r8192_priv *priv = ieee80211_priv(dev); 208 /*struct r8192_priv *priv = ieee80211_priv(dev);*/
219 209
220 //static u8 previous_bssid[6] ={0}; 210 /*static u8 previous_bssid[6] ={0};*/
221 211
222 /*Add by amy 2008/05/15 ,porting from windows code.*/ 212 /*Add by amy 2008/05/15 ,porting from windows code.*/
223 dm_check_rate_adaptive(dev); 213 dm_check_rate_adaptive(dev);
@@ -230,25 +220,23 @@ void hal_dm_watchdog(struct net_device *dev)
230 dm_check_rx_path_selection(dev); 220 dm_check_rx_path_selection(dev);
231 dm_check_fsync(dev); 221 dm_check_fsync(dev);
232 222
233 // Add by amy 2008-05-15 porting from windows code. 223 /* Add by amy 2008-05-15 porting from windows code. */
234 dm_check_pbc_gpio(dev); 224 dm_check_pbc_gpio(dev);
235 dm_send_rssi_tofw(dev); 225 dm_send_rssi_tofw(dev);
236 dm_ctstoself(dev); 226 dm_ctstoself(dev);
237#ifdef USB_RX_AGGREGATION_SUPPORT 227#ifdef USB_RX_AGGREGATION_SUPPORT
238 dm_CheckRxAggregation(dev); 228 dm_CheckRxAggregation(dev);
239#endif 229#endif
240} //HalDmWatchDog 230} /* HalDmWatchDog */
241
242 231
243/* 232/*
244 * Decide Rate Adaptive Set according to distance (signal strength) 233 * Decide Rate Adaptive Set according to distance (signal strength)
245 * 01/11/2008 MHC Modify input arguments and RATR table level. 234 * 01/11/2008 MHC Modify input arguments and RATR table level.
246 * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call 235 * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call
247 * the function after making sure RF_Type. 236 * the function after making sure RF_Type.
248 */ 237 */
249void init_rate_adaptive(struct net_device *dev) 238void init_rate_adaptive(struct net_device *dev)
250{ 239{
251
252 struct r8192_priv *priv = ieee80211_priv(dev); 240 struct r8192_priv *priv = ieee80211_priv(dev);
253 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; 241 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
254 242
@@ -261,36 +249,33 @@ void init_rate_adaptive(struct net_device *dev)
261 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M; 249 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
262 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M; 250 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
263 251
264 if(priv->CustomerID == RT_CID_819x_Netcore) 252 if (priv->CustomerID == RT_CID_819x_Netcore)
265 pra->ping_rssi_enable = 1; 253 pra->ping_rssi_enable = 1;
266 else 254 else
267 pra->ping_rssi_enable = 0; 255 pra->ping_rssi_enable = 0;
268 pra->ping_rssi_thresh_for_ra = 15; 256 pra->ping_rssi_thresh_for_ra = 15;
269 257
270 258 if (priv->rf_type == RF_2T4R) {
271 if (priv->rf_type == RF_2T4R) 259 /*
272 { 260 * 07/10/08 MH Modify for RA smooth scheme.
273 // 07/10/08 MH Modify for RA smooth scheme. 261 * 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.
274 /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/ 262 */
275 pra->upper_rssi_threshold_ratr = 0x8f0f0000; 263 pra->upper_rssi_threshold_ratr = 0x8f0f0000;
276 pra->middle_rssi_threshold_ratr = 0x8f0ff000; 264 pra->middle_rssi_threshold_ratr = 0x8f0ff000;
277 pra->low_rssi_threshold_ratr = 0x8f0ff001; 265 pra->low_rssi_threshold_ratr = 0x8f0ff001;
278 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005; 266 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
279 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001; 267 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
280 pra->ping_rssi_ratr = 0x0000000d;//cosa add for test 268 pra->ping_rssi_ratr = 0x0000000d;/* cosa add for test */
281 } 269 } else if (priv->rf_type == RF_1T2R) {
282 else if (priv->rf_type == RF_1T2R)
283 {
284 pra->upper_rssi_threshold_ratr = 0x000f0000; 270 pra->upper_rssi_threshold_ratr = 0x000f0000;
285 pra->middle_rssi_threshold_ratr = 0x000ff000; 271 pra->middle_rssi_threshold_ratr = 0x000ff000;
286 pra->low_rssi_threshold_ratr = 0x000ff001; 272 pra->low_rssi_threshold_ratr = 0x000ff001;
287 pra->low_rssi_threshold_ratr_40M = 0x000ff005; 273 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
288 pra->low_rssi_threshold_ratr_20M = 0x000ff001; 274 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
289 pra->ping_rssi_ratr = 0x0000000d;//cosa add for test 275 pra->ping_rssi_ratr = 0x0000000d;/* cosa add for test */
290 } 276 }
291 277
292} // InitRateAdaptive 278} /* InitRateAdaptive */
293
294 279
295/*----------------------------------------------------------------------------- 280/*-----------------------------------------------------------------------------
296 * Function: dm_check_rate_adaptive() 281 * Function: dm_check_rate_adaptive()
@@ -318,149 +303,122 @@ static void dm_check_rate_adaptive(struct net_device *dev)
318 bool bshort_gi_enabled = false; 303 bool bshort_gi_enabled = false;
319 static u8 ping_rssi_state; 304 static u8 ping_rssi_state;
320 305
321 306 if (!priv->up) {
322 if(!priv->up)
323 {
324 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); 307 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
325 return; 308 return;
326 } 309 }
327 310
328 if(pra->rate_adaptive_disabled)//this variable is set by ioctl. 311 if (pra->rate_adaptive_disabled) /* this variable is set by ioctl. */
329 return; 312 return;
330 313
331 // TODO: Only 11n mode is implemented currently, 314 /* TODO: Only 11n mode is implemented currently, */
332 if(!(priv->ieee80211->mode == WIRELESS_MODE_N_24G || 315 if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
333 priv->ieee80211->mode == WIRELESS_MODE_N_5G)) 316 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
334 return; 317 return;
335 318
336 if(priv->ieee80211->state == IEEE80211_LINKED) 319 if (priv->ieee80211->state == IEEE80211_LINKED) {
337 { 320 /*RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");*/
338 // RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
339 321
340 // 322 /* Check whether Short GI is enabled */
341 // Check whether Short GI is enabled
342 //
343 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) || 323 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
344 (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz); 324 (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
345 325
346
347 pra->upper_rssi_threshold_ratr = 326 pra->upper_rssi_threshold_ratr =
348 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; 327 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
349 328
350 pra->middle_rssi_threshold_ratr = 329 pra->middle_rssi_threshold_ratr =
351 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; 330 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
352 331
353 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) 332 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
354 {
355 pra->low_rssi_threshold_ratr = 333 pra->low_rssi_threshold_ratr =
356 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; 334 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
357 } 335 } else {
358 else
359 {
360 pra->low_rssi_threshold_ratr = 336 pra->low_rssi_threshold_ratr =
361 (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; 337 (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
362 } 338 }
363 //cosa add for test 339 /* cosa add for test */
364 pra->ping_rssi_ratr = 340 pra->ping_rssi_ratr =
365 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; 341 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
366 342
367 /* 2007/10/08 MH We support RA smooth scheme now. When it is the first 343 /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
368 time to link with AP. We will not change upper/lower threshold. If 344 time to link with AP. We will not change upper/lower threshold. If
369 STA stay in high or low level, we must change two different threshold 345 STA stay in high or low level, we must change two different threshold
370 to prevent jumping frequently. */ 346 to prevent jumping frequently. */
371 if (pra->ratr_state == DM_RATR_STA_HIGH) 347 if (pra->ratr_state == DM_RATR_STA_HIGH) {
372 {
373 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; 348 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
374 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? 349 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
375 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); 350 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
376 } 351 } else if (pra->ratr_state == DM_RATR_STA_LOW) {
377 else if (pra->ratr_state == DM_RATR_STA_LOW)
378 {
379 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; 352 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
380 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? 353 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
381 (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M); 354 (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
382 } 355 } else {
383 else
384 {
385 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; 356 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
386 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? 357 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
387 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); 358 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
388 } 359 }
389 360
390 //DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA); 361 /*DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);*/
391 if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) 362 if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
392 { 363 /*DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);*/
393 //DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
394 pra->ratr_state = DM_RATR_STA_HIGH; 364 pra->ratr_state = DM_RATR_STA_HIGH;
395 targetRATR = pra->upper_rssi_threshold_ratr; 365 targetRATR = pra->upper_rssi_threshold_ratr;
396 }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) 366 } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
397 { 367 /*DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);*/
398 //DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
399 pra->ratr_state = DM_RATR_STA_MIDDLE; 368 pra->ratr_state = DM_RATR_STA_MIDDLE;
400 targetRATR = pra->middle_rssi_threshold_ratr; 369 targetRATR = pra->middle_rssi_threshold_ratr;
401 }else 370 } else {
402 { 371 /*DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);*/
403 //DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
404 pra->ratr_state = DM_RATR_STA_LOW; 372 pra->ratr_state = DM_RATR_STA_LOW;
405 targetRATR = pra->low_rssi_threshold_ratr; 373 targetRATR = pra->low_rssi_threshold_ratr;
406 } 374 }
407 375
408 //cosa add for test 376 /* cosa add for test */
409 if(pra->ping_rssi_enable) 377 if (pra->ping_rssi_enable) {
410 { 378 /*pHalData->UndecoratedSmoothedPWDB = 19;*/
411 //pHalData->UndecoratedSmoothedPWDB = 19; 379 if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
412 if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) 380 if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
413 { 381 ping_rssi_state) {
414 if((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || 382 /*DbgPrint("TestRSSI = %d, set RATR to 0x%x\n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);*/
415 ping_rssi_state)
416 {
417 //DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
418 pra->ratr_state = DM_RATR_STA_LOW; 383 pra->ratr_state = DM_RATR_STA_LOW;
419 targetRATR = pra->ping_rssi_ratr; 384 targetRATR = pra->ping_rssi_ratr;
420 ping_rssi_state = 1; 385 ping_rssi_state = 1;
421 } 386 }
422 //else 387 /*else
423 // DbgPrint("TestRSSI is between the range. \n"); 388 DbgPrint("TestRSSI is between the range.\n");*/
424 } 389 } else {
425 else 390 /*DbgPrint("TestRSSI Recover to 0x%x\n", targetRATR);*/
426 {
427 //DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
428 ping_rssi_state = 0; 391 ping_rssi_state = 0;
429 } 392 }
430 } 393 }
431 394
432 // 2008.04.01 395 /*
433 // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. 396 * 2008.04.01
434 if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev)) 397 * For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
435 targetRATR &= 0xf00fffff; 398 */
399 if (priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
400 targetRATR &= 0xf00fffff;
436 401
437 // 402 /* Check whether updating of RATR0 is required */
438 // Check whether updating of RATR0 is required
439 //
440 read_nic_dword(dev, RATR0, &currentRATR); 403 read_nic_dword(dev, RATR0, &currentRATR);
441 if(targetRATR != currentRATR) 404 if (targetRATR != currentRATR) {
442 {
443 u32 ratr_value; 405 u32 ratr_value;
406
444 ratr_value = targetRATR; 407 ratr_value = targetRATR;
445 RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR); 408 RT_TRACE(COMP_RATE, "currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
446 if(priv->rf_type == RF_1T2R) 409 if (priv->rf_type == RF_1T2R)
447 {
448 ratr_value &= ~(RATE_ALL_OFDM_2SS); 410 ratr_value &= ~(RATE_ALL_OFDM_2SS);
449 }
450 write_nic_dword(dev, RATR0, ratr_value); 411 write_nic_dword(dev, RATR0, ratr_value);
451 write_nic_byte(dev, UFWP, 1); 412 write_nic_byte(dev, UFWP, 1);
452 413
453 pra->last_ratr = targetRATR; 414 pra->last_ratr = targetRATR;
454 } 415 }
455 416
456 } 417 } else {
457 else
458 {
459 pra->ratr_state = DM_RATR_STA_MAX; 418 pra->ratr_state = DM_RATR_STA_MAX;
460 } 419 }
461 420
462} // dm_CheckRateAdaptive 421} /* dm_CheckRateAdaptive */
463
464 422
465static void dm_init_bandwidth_autoswitch(struct net_device *dev) 423static void dm_init_bandwidth_autoswitch(struct net_device *dev)
466{ 424{
@@ -471,78 +429,74 @@ static void dm_init_bandwidth_autoswitch(struct net_device *dev)
471 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; 429 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
472 priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false; 430 priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
473 431
474} // dm_init_bandwidth_autoswitch 432} /* dm_init_bandwidth_autoswitch */
475
476 433
477static void dm_bandwidth_autoswitch(struct net_device *dev) 434static void dm_bandwidth_autoswitch(struct net_device *dev)
478{ 435{
479 struct r8192_priv *priv = ieee80211_priv(dev); 436 struct r8192_priv *priv = ieee80211_priv(dev);
480 437
481 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){ 438 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || !priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable)
482 return; 439 return;
483 }else{ 440 if (priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false) { /* If send packets in 40 Mhz in 20/40 */
484 if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40 441 if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
485 if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz) 442 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
486 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true; 443 } else { /* in force send packets in 20 Mhz in 20/40 */
487 }else{//in force send packets in 20 Mhz in 20/40 444 if (priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
488 if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz) 445 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
489 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
490
491 }
492 } 446 }
493} // dm_BandwidthAutoSwitch 447} /* dm_BandwidthAutoSwitch */
494 448
495//OFDM default at 0db, index=6. 449/* OFDM default at 0db, index=6. */
496static u32 OFDMSwingTable[OFDM_Table_Length] = { 450static u32 OFDMSwingTable[OFDM_Table_Length] = {
497 0x7f8001fe, // 0, +6db 451 0x7f8001fe, /* 0, +6db */
498 0x71c001c7, // 1, +5db 452 0x71c001c7, /* 1, +5db */
499 0x65400195, // 2, +4db 453 0x65400195, /* 2, +4db */
500 0x5a400169, // 3, +3db 454 0x5a400169, /* 3, +3db */
501 0x50800142, // 4, +2db 455 0x50800142, /* 4, +2db */
502 0x47c0011f, // 5, +1db 456 0x47c0011f, /* 5, +1db */
503 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature 457 0x40000100, /* 6, +0db ===> default, upper for higher temperature, lower for low temperature */
504 0x390000e4, // 7, -1db 458 0x390000e4, /* 7, -1db */
505 0x32c000cb, // 8, -2db 459 0x32c000cb, /* 8, -2db */
506 0x2d4000b5, // 9, -3db 460 0x2d4000b5, /* 9, -3db */
507 0x288000a2, // 10, -4db 461 0x288000a2, /* 10, -4db */
508 0x24000090, // 11, -5db 462 0x24000090, /* 11, -5db */
509 0x20000080, // 12, -6db 463 0x20000080, /* 12, -6db */
510 0x1c800072, // 13, -7db 464 0x1c800072, /* 13, -7db */
511 0x19800066, // 14, -8db 465 0x19800066, /* 14, -8db */
512 0x26c0005b, // 15, -9db 466 0x26c0005b, /* 15, -9db */
513 0x24400051, // 16, -10db 467 0x24400051, /* 16, -10db */
514 0x12000048, // 17, -11db 468 0x12000048, /* 17, -11db */
515 0x10000040 // 18, -12db 469 0x10000040 /* 18, -12db */
516}; 470};
517 471
518static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = { 472static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
519 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0db ===> CCK40M default 473 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0db ===> CCK40M default */
520 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 1, -1db 474 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 1, -1db */
521 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 2, -2db 475 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 2, -2db */
522 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 3, -3db 476 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 3, -3db */
523 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 4, -4db 477 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 4, -4db */
524 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 5, -5db 478 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 5, -5db */
525 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 6, -6db ===> CCK20M default 479 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 6, -6db ===> CCK20M default */
526 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 7, -7db 480 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 7, -7db */
527 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 8, -8db 481 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 8, -8db */
528 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 9, -9db 482 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 9, -9db */
529 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 10, -10db 483 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 10, -10db */
530 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} // 11, -11db 484 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} /* 11, -11db */
531}; 485};
532 486
533static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { 487static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
534 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0db ===> CCK40M default 488 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0db ===> CCK40M default */
535 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 1, -1db 489 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 1, -1db */
536 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 2, -2db 490 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 2, -2db */
537 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 3, -3db 491 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 3, -3db */
538 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 4, -4db 492 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 4, -4db */
539 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 5, -5db 493 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 5, -5db */
540 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 6, -6db ===> CCK20M default 494 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 6, -6db ===> CCK20M default */
541 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 7, -7db 495 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 7, -7db */
542 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 8, -8db 496 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 8, -8db */
543 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 9, -9db 497 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 9, -9db */
544 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db 498 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 10, -10db */
545 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db 499 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} /* 11, -11db */
546}; 500};
547 501
548static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) 502static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
@@ -551,14 +505,14 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
551 bool bHighpowerstate, viviflag = FALSE; 505 bool bHighpowerstate, viviflag = FALSE;
552 DCMD_TXCMD_T tx_cmd; 506 DCMD_TXCMD_T tx_cmd;
553 u8 powerlevelOFDM24G; 507 u8 powerlevelOFDM24G;
554 int i =0, j = 0, k = 0; 508 int i = 0, j = 0, k = 0;
555 u8 RF_Type, tmp_report[5]={0, 0, 0, 0, 0}; 509 u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
556 u32 Value; 510 u32 Value;
557 u8 Pwr_Flag; 511 u8 Pwr_Flag;
558 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0; 512 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
559 //RT_STATUS rtStatus = RT_STATUS_SUCCESS; 513 /*RT_STATUS rtStatus = RT_STATUS_SUCCESS;*/
560 bool rtStatus = true; 514 bool rtStatus = true;
561 u32 delta=0; 515 u32 delta = 0;
562 516
563 write_nic_byte(dev, 0x1ba, 0); 517 write_nic_byte(dev, 0x1ba, 0);
564 518
@@ -571,109 +525,87 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
571 525
572 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G); 526 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
573 527
574 for(j = 0; j<=30; j++) 528 for (j = 0; j <= 30; j++) { /* fill tx_cmd */
575{ //fill tx_cmd 529 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
576 530 tx_cmd.Length = 4;
577 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; 531 tx_cmd.Value = Value;
578 tx_cmd.Length = 4; 532 rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
579 tx_cmd.Value = Value; 533 if (rtStatus == RT_STATUS_FAILURE)
580 rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12); 534 RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
581 if (rtStatus == RT_STATUS_FAILURE) 535 mdelay(1);
582 { 536 /*DbgPrint("hi, vivi, strange\n");*/
583 RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n"); 537 for (i = 0; i <= 30; i++) {
584 } 538 read_nic_byte(dev, 0x1ba, &Pwr_Flag);
585 mdelay(1); 539
586 //DbgPrint("hi, vivi, strange\n"); 540 if (Pwr_Flag == 0) {
587 for(i = 0;i <= 30; i++) 541 mdelay(1);
588 { 542 continue;
589 read_nic_byte(dev, 0x1ba, &Pwr_Flag); 543 }
590 544 read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
591 if (Pwr_Flag == 0) 545 if (Avg_TSSI_Meas == 0) {
592 { 546 write_nic_byte(dev, 0x1ba, 0);
593 mdelay(1); 547 break;
594 continue; 548 }
595 }
596 read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
597 if(Avg_TSSI_Meas == 0)
598 {
599 write_nic_byte(dev, 0x1ba, 0);
600 break;
601 }
602 549
603 for(k = 0;k < 5; k++) 550 for (k = 0; k < 5; k++) {
604 { 551 if (k != 4)
605 if(k !=4) 552 read_nic_byte(dev, 0x134+k, &tmp_report[k]);
606 read_nic_byte(dev, 0x134+k, &tmp_report[k]); 553 else
607 else 554 read_nic_byte(dev, 0x13e, &tmp_report[k]);
608 read_nic_byte(dev, 0x13e, &tmp_report[k]); 555 RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
609 RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]); 556 }
610 }
611 557
612 //check if the report value is right 558 /* check if the report value is right */
613 for(k = 0;k < 5; k++) 559 for (k = 0; k < 5; k++) {
614 { 560 if (tmp_report[k] <= 20) {
615 if(tmp_report[k] <= 20) 561 viviflag = TRUE;
616 { 562 break;
617 viviflag =TRUE; 563 }
564 }
565 if (viviflag == TRUE) {
566 write_nic_byte(dev, 0x1ba, 0);
567 viviflag = FALSE;
568 RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
569 for (k = 0; k < 5; k++)
570 tmp_report[k] = 0;
618 break; 571 break;
619 } 572 }
620 }
621 if(viviflag ==TRUE)
622 {
623 write_nic_byte(dev, 0x1ba, 0);
624 viviflag = FALSE;
625 RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
626 for(k = 0;k < 5; k++)
627 tmp_report[k] = 0;
628 break;
629 }
630 573
631 for(k = 0;k < 5; k++) 574 for (k = 0; k < 5; k++)
632 { 575 Avg_TSSI_Meas_from_driver += tmp_report[k];
633 Avg_TSSI_Meas_from_driver += tmp_report[k];
634 }
635
636 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
637 RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
638 TSSI_13dBm = priv->TSSI_13dBm;
639 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
640 576
641 //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK) 577 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
642 // For MacOS-compatible 578 RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
643 if(Avg_TSSI_Meas_from_driver > TSSI_13dBm) 579 TSSI_13dBm = priv->TSSI_13dBm;
644 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; 580 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
645 else
646 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
647 581
648 if(delta <= E_FOR_TX_POWER_TRACK) 582 /*if (abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)*/
649 { 583 /* For MacOS-compatible */
650 priv->ieee80211->bdynamic_txpower_enable = TRUE; 584 if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
651 write_nic_byte(dev, 0x1ba, 0); 585 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
652 RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n"); 586 else
653 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); 587 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
654 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); 588
655 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference); 589 if (delta <= E_FOR_TX_POWER_TRACK) {
656 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation); 590 priv->ieee80211->bdynamic_txpower_enable = TRUE;
657 return; 591 write_nic_byte(dev, 0x1ba, 0);
658 } 592 RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
659 else 593 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
660 { 594 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
661 if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) 595 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
662 { 596 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
663 if (priv->rfa_txpowertrackingindex > 0) 597 return;
664 { 598 }
599 if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
600 if (priv->rfa_txpowertrackingindex > 0) {
665 priv->rfa_txpowertrackingindex--; 601 priv->rfa_txpowertrackingindex--;
666 if(priv->rfa_txpowertrackingindex_real > 4) 602 if (priv->rfa_txpowertrackingindex_real > 4) {
667 {
668 priv->rfa_txpowertrackingindex_real--; 603 priv->rfa_txpowertrackingindex_real--;
669 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); 604 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
670 } 605 }
671 } 606 }
672 } 607 } else {
673 else 608 if (priv->rfa_txpowertrackingindex < 36) {
674 {
675 if (priv->rfa_txpowertrackingindex < 36)
676 {
677 priv->rfa_txpowertrackingindex++; 609 priv->rfa_txpowertrackingindex++;
678 priv->rfa_txpowertrackingindex_real++; 610 priv->rfa_txpowertrackingindex_real++;
679 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); 611 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
@@ -683,52 +615,44 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
683 priv->cck_present_attentuation_difference 615 priv->cck_present_attentuation_difference
684 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default; 616 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
685 617
686 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) 618 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
687 priv->cck_present_attentuation 619 priv->cck_present_attentuation
688 = priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference; 620 = priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
689 else 621 else
690 priv->cck_present_attentuation 622 priv->cck_present_attentuation
691 = priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference; 623 = priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
692 624
693 if(priv->cck_present_attentuation > -1&&priv->cck_present_attentuation <23) 625 if (priv->cck_present_attentuation > -1 && priv->cck_present_attentuation < 23) {
694 { 626 if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
695 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
696 {
697 priv->bcck_in_ch14 = TRUE; 627 priv->bcck_in_ch14 = TRUE;
698 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); 628 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
699 } 629 } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
700 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
701 {
702 priv->bcck_in_ch14 = FALSE; 630 priv->bcck_in_ch14 = FALSE;
703 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); 631 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
704 } 632 } else
705 else 633 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
706 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
707 } 634 }
708 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); 635 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
709 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); 636 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
710 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference); 637 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
711 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation); 638 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
712
713 if (priv->cck_present_attentuation_difference <= -12||priv->cck_present_attentuation_difference >= 24)
714 {
715 priv->ieee80211->bdynamic_txpower_enable = TRUE;
716 write_nic_byte(dev, 0x1ba, 0);
717 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
718 return;
719 }
720 639
640 if (priv->cck_present_attentuation_difference <= -12 || priv->cck_present_attentuation_difference >= 24) {
641 priv->ieee80211->bdynamic_txpower_enable = TRUE;
642 write_nic_byte(dev, 0x1ba, 0);
643 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
644 return;
645 }
721 646
647 write_nic_byte(dev, 0x1ba, 0);
648 Avg_TSSI_Meas_from_driver = 0;
649 for (k = 0; k < 5; k++)
650 tmp_report[k] = 0;
651 break;
652 }
722 } 653 }
723 write_nic_byte(dev, 0x1ba, 0); 654 priv->ieee80211->bdynamic_txpower_enable = TRUE;
724 Avg_TSSI_Meas_from_driver = 0; 655 write_nic_byte(dev, 0x1ba, 0);
725 for(k = 0;k < 5; k++)
726 tmp_report[k] = 0;
727 break;
728 }
729}
730 priv->ieee80211->bdynamic_txpower_enable = TRUE;
731 write_nic_byte(dev, 0x1ba, 0);
732} 656}
733 657
734static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev) 658static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
@@ -737,107 +661,96 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
737 struct r8192_priv *priv = ieee80211_priv(dev); 661 struct r8192_priv *priv = ieee80211_priv(dev);
738 u32 tmpRegA, TempCCk; 662 u32 tmpRegA, TempCCk;
739 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; 663 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
740 int i =0, CCKSwingNeedUpdate=0; 664 int i = 0, CCKSwingNeedUpdate = 0;
741 665
742 if(!priv->btxpower_trackingInit) 666 if (!priv->btxpower_trackingInit) {
743 { 667 /* Query OFDM default setting */
744 //Query OFDM default setting 668 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
745 tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); 669 for (i = 0; i < OFDM_Table_Length; i++) { /* find the index */
746 for(i=0; i<OFDM_Table_Length; i++) //find the index 670 if (tmpRegA == OFDMSwingTable[i]) {
747 { 671 priv->OFDM_index = (u8)i;
748 if(tmpRegA == OFDMSwingTable[i])
749 {
750 priv->OFDM_index= (u8)i;
751 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n", 672 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
752 rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index); 673 rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
753 } 674 }
754 } 675 }
755 676
756 //Query CCK default setting From 0xa22 677 /* Query CCK default setting From 0xa22 */
757 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); 678 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
758 for(i=0 ; i<CCK_Table_length ; i++) 679 for (i = 0; i < CCK_Table_length; i++) {
759 { 680 if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
760 if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) 681 priv->CCK_index = (u8) i;
761 {
762 priv->CCK_index =(u8) i;
763 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n", 682 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
764 rCCK0_TxFilter1, TempCCk, priv->CCK_index); 683 rCCK0_TxFilter1, TempCCk, priv->CCK_index);
765 break; 684 break;
766 } 685 }
767 } 686 }
768 priv->btxpower_trackingInit = TRUE; 687 priv->btxpower_trackingInit = TRUE;
769 //pHalData->TXPowercount = 0; 688 /*pHalData->TXPowercount = 0;*/
770 return; 689 return;
771 } 690 }
772 691
773 //========================== 692 /*
774 // this is only for test, should be masked 693 * ==========================
775 //========================== 694 * this is only for test, should be masked
776 695 * ==========================
777 // read and filter out unreasonable value 696 */
778 tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7] 697
779 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA); 698 /* read and filter out unreasonable value */
780 if(tmpRegA < 3 || tmpRegA > 13) 699 tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); /* 0x12: RF Reg[10:7] */
700 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
701 if (tmpRegA < 3 || tmpRegA > 13)
781 return; 702 return;
782 if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature 703 if (tmpRegA >= 12) /* if over 12, TP will be bad when high temperature */
783 tmpRegA = 12; 704 tmpRegA = 12;
784 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA); 705 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
785 priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion 706 priv->ThermalMeter[0] = ThermalMeterVal; /* We use fixed value by Bryant's suggestion */
786 priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion 707 priv->ThermalMeter[1] = ThermalMeterVal; /* We use fixed value by Bryant's suggestion */
787 708
788 //Get current RF-A temperature index 709 /* Get current RF-A temperature index */
789 if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature 710 if (priv->ThermalMeter[0] >= (u8)tmpRegA) { /* lower temperature */
790 {
791 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA); 711 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
792 tmpCCK40Mindex = tmpCCK20Mindex - 6; 712 tmpCCK40Mindex = tmpCCK20Mindex - 6;
793 if(tmpOFDMindex >= OFDM_Table_Length) 713 if (tmpOFDMindex >= OFDM_Table_Length)
794 tmpOFDMindex = OFDM_Table_Length-1; 714 tmpOFDMindex = OFDM_Table_Length-1;
795 if(tmpCCK20Mindex >= CCK_Table_length) 715 if (tmpCCK20Mindex >= CCK_Table_length)
796 tmpCCK20Mindex = CCK_Table_length-1; 716 tmpCCK20Mindex = CCK_Table_length-1;
797 if(tmpCCK40Mindex >= CCK_Table_length) 717 if (tmpCCK40Mindex >= CCK_Table_length)
798 tmpCCK40Mindex = CCK_Table_length-1; 718 tmpCCK40Mindex = CCK_Table_length-1;
799 } 719 } else {
800 else
801 {
802 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); 720 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
803 if(tmpval >= 6) // higher temperature 721
804 tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB 722 if (tmpval >= 6) /* higher temperature */
723 tmpOFDMindex = tmpCCK20Mindex = 0; /* max to +6dB */
805 else 724 else
806 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; 725 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
807 tmpCCK40Mindex = 0; 726 tmpCCK40Mindex = 0;
808 } 727 }
809 //DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d", 728 /*DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
810 //((u1Byte)tmpRegA - pHalData->ThermalMeter[0]), 729 ((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
811 //tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex); 730 tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);*/
812 if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M 731 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) /* 40M */
813 tmpCCKindex = tmpCCK40Mindex; 732 tmpCCKindex = tmpCCK40Mindex;
814 else 733 else
815 tmpCCKindex = tmpCCK20Mindex; 734 tmpCCKindex = tmpCCK20Mindex;
816 735
817 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) 736 if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
818 {
819 priv->bcck_in_ch14 = TRUE; 737 priv->bcck_in_ch14 = TRUE;
820 CCKSwingNeedUpdate = 1; 738 CCKSwingNeedUpdate = 1;
821 } 739 } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
822 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
823 {
824 priv->bcck_in_ch14 = FALSE; 740 priv->bcck_in_ch14 = FALSE;
825 CCKSwingNeedUpdate = 1; 741 CCKSwingNeedUpdate = 1;
826 } 742 }
827 743
828 if(priv->CCK_index != tmpCCKindex) 744 if (priv->CCK_index != tmpCCKindex) {
829 {
830 priv->CCK_index = tmpCCKindex; 745 priv->CCK_index = tmpCCKindex;
831 CCKSwingNeedUpdate = 1; 746 CCKSwingNeedUpdate = 1;
832 } 747 }
833 748
834 if(CCKSwingNeedUpdate) 749 if (CCKSwingNeedUpdate) {
835 { 750 /*DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);*/
836 //DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
837 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); 751 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
838 } 752 }
839 if(priv->OFDM_index != tmpOFDMindex) 753 if (priv->OFDM_index != tmpOFDMindex) {
840 {
841 priv->OFDM_index = tmpOFDMindex; 754 priv->OFDM_index = tmpOFDMindex;
842 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]); 755 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
843 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", 756 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
@@ -848,100 +761,100 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
848 761
849void dm_txpower_trackingcallback(struct work_struct *work) 762void dm_txpower_trackingcallback(struct work_struct *work)
850{ 763{
851 struct delayed_work *dwork = container_of(work,struct delayed_work,work); 764 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
852 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq); 765 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, txpower_tracking_wq);
853 struct net_device *dev = priv->ieee80211->dev; 766 struct net_device *dev = priv->ieee80211->dev;
854 767
855 if(priv->bDcut == TRUE) 768 if (priv->bDcut == TRUE)
856 dm_TXPowerTrackingCallback_TSSI(dev); 769 dm_TXPowerTrackingCallback_TSSI(dev);
857 else 770 else
858 dm_TXPowerTrackingCallback_ThermalMeter(dev); 771 dm_TXPowerTrackingCallback_ThermalMeter(dev);
859} 772}
860 773
861
862static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) 774static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
863{ 775{
864
865 struct r8192_priv *priv = ieee80211_priv(dev); 776 struct r8192_priv *priv = ieee80211_priv(dev);
866 777
867 //Initial the Tx BB index and mapping value 778 /* Initial the Tx BB index and mapping value */
868 priv->txbbgain_table[0].txbb_iq_amplifygain = 12; 779 priv->txbbgain_table[0].txbb_iq_amplifygain = 12;
869 priv->txbbgain_table[0].txbbgain_value=0x7f8001fe; 780 priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe;
870 priv->txbbgain_table[1].txbb_iq_amplifygain = 11; 781 priv->txbbgain_table[1].txbb_iq_amplifygain = 11;
871 priv->txbbgain_table[1].txbbgain_value=0x788001e2; 782 priv->txbbgain_table[1].txbbgain_value = 0x788001e2;
872 priv->txbbgain_table[2].txbb_iq_amplifygain = 10; 783 priv->txbbgain_table[2].txbb_iq_amplifygain = 10;
873 priv->txbbgain_table[2].txbbgain_value=0x71c001c7; 784 priv->txbbgain_table[2].txbbgain_value = 0x71c001c7;
874 priv->txbbgain_table[3].txbb_iq_amplifygain = 9; 785 priv->txbbgain_table[3].txbb_iq_amplifygain = 9;
875 priv->txbbgain_table[3].txbbgain_value=0x6b8001ae; 786 priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae;
876 priv->txbbgain_table[4].txbb_iq_amplifygain = 8; 787 priv->txbbgain_table[4].txbb_iq_amplifygain = 8;
877 priv->txbbgain_table[4].txbbgain_value=0x65400195; 788 priv->txbbgain_table[4].txbbgain_value = 0x65400195;
878 priv->txbbgain_table[5].txbb_iq_amplifygain = 7; 789 priv->txbbgain_table[5].txbb_iq_amplifygain = 7;
879 priv->txbbgain_table[5].txbbgain_value=0x5fc0017f; 790 priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f;
880 priv->txbbgain_table[6].txbb_iq_amplifygain = 6; 791 priv->txbbgain_table[6].txbb_iq_amplifygain = 6;
881 priv->txbbgain_table[6].txbbgain_value=0x5a400169; 792 priv->txbbgain_table[6].txbbgain_value = 0x5a400169;
882 priv->txbbgain_table[7].txbb_iq_amplifygain = 5; 793 priv->txbbgain_table[7].txbb_iq_amplifygain = 5;
883 priv->txbbgain_table[7].txbbgain_value=0x55400155; 794 priv->txbbgain_table[7].txbbgain_value = 0x55400155;
884 priv->txbbgain_table[8].txbb_iq_amplifygain = 4; 795 priv->txbbgain_table[8].txbb_iq_amplifygain = 4;
885 priv->txbbgain_table[8].txbbgain_value=0x50800142; 796 priv->txbbgain_table[8].txbbgain_value = 0x50800142;
886 priv->txbbgain_table[9].txbb_iq_amplifygain = 3; 797 priv->txbbgain_table[9].txbb_iq_amplifygain = 3;
887 priv->txbbgain_table[9].txbbgain_value=0x4c000130; 798 priv->txbbgain_table[9].txbbgain_value = 0x4c000130;
888 priv->txbbgain_table[10].txbb_iq_amplifygain = 2; 799 priv->txbbgain_table[10].txbb_iq_amplifygain = 2;
889 priv->txbbgain_table[10].txbbgain_value=0x47c0011f; 800 priv->txbbgain_table[10].txbbgain_value = 0x47c0011f;
890 priv->txbbgain_table[11].txbb_iq_amplifygain = 1; 801 priv->txbbgain_table[11].txbb_iq_amplifygain = 1;
891 priv->txbbgain_table[11].txbbgain_value=0x43c0010f; 802 priv->txbbgain_table[11].txbbgain_value = 0x43c0010f;
892 priv->txbbgain_table[12].txbb_iq_amplifygain = 0; 803 priv->txbbgain_table[12].txbb_iq_amplifygain = 0;
893 priv->txbbgain_table[12].txbbgain_value=0x40000100; 804 priv->txbbgain_table[12].txbbgain_value = 0x40000100;
894 priv->txbbgain_table[13].txbb_iq_amplifygain = -1; 805 priv->txbbgain_table[13].txbb_iq_amplifygain = -1;
895 priv->txbbgain_table[13].txbbgain_value=0x3c8000f2; 806 priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2;
896 priv->txbbgain_table[14].txbb_iq_amplifygain = -2; 807 priv->txbbgain_table[14].txbb_iq_amplifygain = -2;
897 priv->txbbgain_table[14].txbbgain_value=0x390000e4; 808 priv->txbbgain_table[14].txbbgain_value = 0x390000e4;
898 priv->txbbgain_table[15].txbb_iq_amplifygain = -3; 809 priv->txbbgain_table[15].txbb_iq_amplifygain = -3;
899 priv->txbbgain_table[15].txbbgain_value=0x35c000d7; 810 priv->txbbgain_table[15].txbbgain_value = 0x35c000d7;
900 priv->txbbgain_table[16].txbb_iq_amplifygain = -4; 811 priv->txbbgain_table[16].txbb_iq_amplifygain = -4;
901 priv->txbbgain_table[16].txbbgain_value=0x32c000cb; 812 priv->txbbgain_table[16].txbbgain_value = 0x32c000cb;
902 priv->txbbgain_table[17].txbb_iq_amplifygain = -5; 813 priv->txbbgain_table[17].txbb_iq_amplifygain = -5;
903 priv->txbbgain_table[17].txbbgain_value=0x300000c0; 814 priv->txbbgain_table[17].txbbgain_value = 0x300000c0;
904 priv->txbbgain_table[18].txbb_iq_amplifygain = -6; 815 priv->txbbgain_table[18].txbb_iq_amplifygain = -6;
905 priv->txbbgain_table[18].txbbgain_value=0x2d4000b5; 816 priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5;
906 priv->txbbgain_table[19].txbb_iq_amplifygain = -7; 817 priv->txbbgain_table[19].txbb_iq_amplifygain = -7;
907 priv->txbbgain_table[19].txbbgain_value=0x2ac000ab; 818 priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab;
908 priv->txbbgain_table[20].txbb_iq_amplifygain = -8; 819 priv->txbbgain_table[20].txbb_iq_amplifygain = -8;
909 priv->txbbgain_table[20].txbbgain_value=0x288000a2; 820 priv->txbbgain_table[20].txbbgain_value = 0x288000a2;
910 priv->txbbgain_table[21].txbb_iq_amplifygain = -9; 821 priv->txbbgain_table[21].txbb_iq_amplifygain = -9;
911 priv->txbbgain_table[21].txbbgain_value=0x26000098; 822 priv->txbbgain_table[21].txbbgain_value = 0x26000098;
912 priv->txbbgain_table[22].txbb_iq_amplifygain = -10; 823 priv->txbbgain_table[22].txbb_iq_amplifygain = -10;
913 priv->txbbgain_table[22].txbbgain_value=0x24000090; 824 priv->txbbgain_table[22].txbbgain_value = 0x24000090;
914 priv->txbbgain_table[23].txbb_iq_amplifygain = -11; 825 priv->txbbgain_table[23].txbb_iq_amplifygain = -11;
915 priv->txbbgain_table[23].txbbgain_value=0x22000088; 826 priv->txbbgain_table[23].txbbgain_value = 0x22000088;
916 priv->txbbgain_table[24].txbb_iq_amplifygain = -12; 827 priv->txbbgain_table[24].txbb_iq_amplifygain = -12;
917 priv->txbbgain_table[24].txbbgain_value=0x20000080; 828 priv->txbbgain_table[24].txbbgain_value = 0x20000080;
918 priv->txbbgain_table[25].txbb_iq_amplifygain = -13; 829 priv->txbbgain_table[25].txbb_iq_amplifygain = -13;
919 priv->txbbgain_table[25].txbbgain_value=0x1a00006c; 830 priv->txbbgain_table[25].txbbgain_value = 0x1a00006c;
920 priv->txbbgain_table[26].txbb_iq_amplifygain = -14; 831 priv->txbbgain_table[26].txbb_iq_amplifygain = -14;
921 priv->txbbgain_table[26].txbbgain_value=0x1c800072; 832 priv->txbbgain_table[26].txbbgain_value = 0x1c800072;
922 priv->txbbgain_table[27].txbb_iq_amplifygain = -15; 833 priv->txbbgain_table[27].txbb_iq_amplifygain = -15;
923 priv->txbbgain_table[27].txbbgain_value=0x18000060; 834 priv->txbbgain_table[27].txbbgain_value = 0x18000060;
924 priv->txbbgain_table[28].txbb_iq_amplifygain = -16; 835 priv->txbbgain_table[28].txbb_iq_amplifygain = -16;
925 priv->txbbgain_table[28].txbbgain_value=0x19800066; 836 priv->txbbgain_table[28].txbbgain_value = 0x19800066;
926 priv->txbbgain_table[29].txbb_iq_amplifygain = -17; 837 priv->txbbgain_table[29].txbb_iq_amplifygain = -17;
927 priv->txbbgain_table[29].txbbgain_value=0x15800056; 838 priv->txbbgain_table[29].txbbgain_value = 0x15800056;
928 priv->txbbgain_table[30].txbb_iq_amplifygain = -18; 839 priv->txbbgain_table[30].txbb_iq_amplifygain = -18;
929 priv->txbbgain_table[30].txbbgain_value=0x26c0005b; 840 priv->txbbgain_table[30].txbbgain_value = 0x26c0005b;
930 priv->txbbgain_table[31].txbb_iq_amplifygain = -19; 841 priv->txbbgain_table[31].txbb_iq_amplifygain = -19;
931 priv->txbbgain_table[31].txbbgain_value=0x14400051; 842 priv->txbbgain_table[31].txbbgain_value = 0x14400051;
932 priv->txbbgain_table[32].txbb_iq_amplifygain = -20; 843 priv->txbbgain_table[32].txbb_iq_amplifygain = -20;
933 priv->txbbgain_table[32].txbbgain_value=0x24400051; 844 priv->txbbgain_table[32].txbbgain_value = 0x24400051;
934 priv->txbbgain_table[33].txbb_iq_amplifygain = -21; 845 priv->txbbgain_table[33].txbb_iq_amplifygain = -21;
935 priv->txbbgain_table[33].txbbgain_value=0x1300004c; 846 priv->txbbgain_table[33].txbbgain_value = 0x1300004c;
936 priv->txbbgain_table[34].txbb_iq_amplifygain = -22; 847 priv->txbbgain_table[34].txbb_iq_amplifygain = -22;
937 priv->txbbgain_table[34].txbbgain_value=0x12000048; 848 priv->txbbgain_table[34].txbbgain_value = 0x12000048;
938 priv->txbbgain_table[35].txbb_iq_amplifygain = -23; 849 priv->txbbgain_table[35].txbb_iq_amplifygain = -23;
939 priv->txbbgain_table[35].txbbgain_value=0x11000044; 850 priv->txbbgain_table[35].txbbgain_value = 0x11000044;
940 priv->txbbgain_table[36].txbb_iq_amplifygain = -24; 851 priv->txbbgain_table[36].txbb_iq_amplifygain = -24;
941 priv->txbbgain_table[36].txbbgain_value=0x10000040; 852 priv->txbbgain_table[36].txbbgain_value = 0x10000040;
942 853
943 //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 854 /*
944 //This Table is for CH1~CH13 855 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
856 * This Table is for CH1~CH13
857 */
945 priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36; 858 priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
946 priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35; 859 priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
947 priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e; 860 priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
@@ -1149,8 +1062,10 @@ static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
1149 priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03; 1062 priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1150 priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01; 1063 priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1151 1064
1152 //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 1065 /*
1153 //This Table is for CH14 1066 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1067 * This Table is for CH14
1068 */
1154 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36; 1069 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1155 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35; 1070 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1156 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e; 1071 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
@@ -1368,10 +1283,12 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1368{ 1283{
1369 struct r8192_priv *priv = ieee80211_priv(dev); 1284 struct r8192_priv *priv = ieee80211_priv(dev);
1370 1285
1371 // Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism 1286 /*
1372 // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w 1287 * Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism
1373 // 3-wire by driver causes RF to go into a wrong state. 1288 * can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
1374 if(priv->ieee80211->FwRWRF) 1289 * 3-wire by driver causes RF to go into a wrong state.
1290 */
1291 if (priv->ieee80211->FwRWRF)
1375 priv->btxpower_tracking = TRUE; 1292 priv->btxpower_tracking = TRUE;
1376 else 1293 else
1377 priv->btxpower_tracking = FALSE; 1294 priv->btxpower_tracking = FALSE;
@@ -1379,57 +1296,46 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1379 priv->btxpower_trackingInit = FALSE; 1296 priv->btxpower_trackingInit = FALSE;
1380} 1297}
1381 1298
1382
1383void dm_initialize_txpower_tracking(struct net_device *dev) 1299void dm_initialize_txpower_tracking(struct net_device *dev)
1384{ 1300{
1385 struct r8192_priv *priv = ieee80211_priv(dev); 1301 struct r8192_priv *priv = ieee80211_priv(dev);
1386 if(priv->bDcut == TRUE) 1302
1303 if (priv->bDcut == TRUE)
1387 dm_InitializeTXPowerTracking_TSSI(dev); 1304 dm_InitializeTXPowerTracking_TSSI(dev);
1388 else 1305 else
1389 dm_InitializeTXPowerTracking_ThermalMeter(dev); 1306 dm_InitializeTXPowerTracking_ThermalMeter(dev);
1390}// dm_InitializeTXPowerTracking 1307} /* dm_InitializeTXPowerTracking */
1391
1392 1308
1393static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) 1309static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1394{ 1310{
1395 struct r8192_priv *priv = ieee80211_priv(dev); 1311 struct r8192_priv *priv = ieee80211_priv(dev);
1396 static u32 tx_power_track_counter; 1312 static u32 tx_power_track_counter;
1397 1313
1398 if(!priv->btxpower_tracking) 1314 if (!priv->btxpower_tracking)
1399 return; 1315 return;
1400 else 1316 if ((tx_power_track_counter % 30 == 0) && (tx_power_track_counter != 0))
1401 { 1317 queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1402 if((tx_power_track_counter % 30 == 0)&&(tx_power_track_counter != 0)) 1318 tx_power_track_counter++;
1403 {
1404 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
1405 }
1406 tx_power_track_counter++;
1407 }
1408
1409} 1319}
1410 1320
1411
1412static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) 1321static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1413{ 1322{
1414 struct r8192_priv *priv = ieee80211_priv(dev); 1323 struct r8192_priv *priv = ieee80211_priv(dev);
1415 static u8 TM_Trigger; 1324 static u8 TM_Trigger;
1416 //DbgPrint("dm_CheckTXPowerTracking() \n"); 1325 /*DbgPrint("dm_CheckTXPowerTracking()\n");*/
1417 if(!priv->btxpower_tracking) 1326 if (!priv->btxpower_tracking)
1327 return;
1328 if (priv->txpower_count <= 2) {
1329 priv->txpower_count++;
1418 return; 1330 return;
1419 else
1420 {
1421 if(priv->txpower_count <= 2)
1422 {
1423 priv->txpower_count++;
1424 return;
1425 }
1426 } 1331 }
1427 1332
1428 if(!TM_Trigger) 1333 if (!TM_Trigger) {
1429 { 1334 /*
1430 //Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash 1335 * Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash
1431 //actually write reg0x02 bit1=0, then bit1=1. 1336 * actually write reg0x02 bit1=0, then bit1=1.
1432 //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); 1337 * DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
1338 */
1433 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); 1339 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1434 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); 1340 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1435 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); 1341 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
@@ -1437,93 +1343,84 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1437 TM_Trigger = 1; 1343 TM_Trigger = 1;
1438 return; 1344 return;
1439 } 1345 }
1440 else 1346 /*DbgPrint("Schedule TxPowerTrackingWorkItem\n");*/
1441 { 1347 queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1442 //DbgPrint("Schedule TxPowerTrackingWorkItem\n"); 1348 TM_Trigger = 0;
1443 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
1444 TM_Trigger = 0;
1445 }
1446} 1349}
1447 1350
1448
1449static void dm_check_txpower_tracking(struct net_device *dev) 1351static void dm_check_txpower_tracking(struct net_device *dev)
1450{ 1352{
1451 struct r8192_priv *priv = ieee80211_priv(dev); 1353 struct r8192_priv *priv = ieee80211_priv(dev);
1452 //static u32 tx_power_track_counter = 0; 1354 /*static u32 tx_power_track_counter = 0;*/
1453 1355
1454#ifdef RTL8190P 1356#ifdef RTL8190P
1455 dm_CheckTXPowerTracking_TSSI(dev); 1357 dm_CheckTXPowerTracking_TSSI(dev);
1456#else 1358#else
1457 if(priv->bDcut == TRUE) 1359 if (priv->bDcut == TRUE)
1458 dm_CheckTXPowerTracking_TSSI(dev); 1360 dm_CheckTXPowerTracking_TSSI(dev);
1459 else 1361 else
1460 dm_CheckTXPowerTracking_ThermalMeter(dev); 1362 dm_CheckTXPowerTracking_ThermalMeter(dev);
1461#endif 1363#endif
1462 1364
1463} // dm_CheckTXPowerTracking 1365} /* dm_CheckTXPowerTracking */
1464
1465 1366
1466static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) 1367static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14)
1467{ 1368{
1468 u32 TempVal; 1369 u32 TempVal;
1469 struct r8192_priv *priv = ieee80211_priv(dev); 1370 struct r8192_priv *priv = ieee80211_priv(dev);
1470 //Write 0xa22 0xa23 1371
1372 /* Write 0xa22 0xa23 */
1471 TempVal = 0; 1373 TempVal = 0;
1472 if(!bInCH14){ 1374 if (!bInCH14) {
1473 //Write 0xa22 0xa23 1375 /* Write 0xa22 0xa23 */
1474 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] + 1376 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
1475 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ; 1377 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8);
1476 1378
1477 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); 1379 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1478 //Write 0xa24 ~ 0xa27 1380 /* Write 0xa24 ~ 0xa27 */
1479 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] + 1381 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
1480 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) + 1382 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
1481 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+ 1383 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+
1482 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24); 1384 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
1483 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); 1385 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1484 //Write 0xa28 0xa29 1386 /* Write 0xa28 0xa29 */
1485 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] + 1387 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
1486 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ; 1388 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8);
1487 1389
1488 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); 1390 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1489 } 1391 } else {
1490 else
1491 {
1492 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] + 1392 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
1493 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ; 1393 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8);
1494 1394
1495 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); 1395 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1496 //Write 0xa24 ~ 0xa27 1396 /* Write 0xa24 ~ 0xa27 */
1497 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] + 1397 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
1498 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) + 1398 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
1499 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+ 1399 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+
1500 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24); 1400 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
1501 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); 1401 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1502 //Write 0xa28 0xa29 1402 /* Write 0xa28 0xa29 */
1503 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] + 1403 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
1504 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ; 1404 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8);
1505 1405
1506 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); 1406 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1507 } 1407 }
1508
1509
1510} 1408}
1511 1409
1512static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) 1410static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14)
1513{ 1411{
1514 u32 TempVal; 1412 u32 TempVal;
1515 struct r8192_priv *priv = ieee80211_priv(dev); 1413 struct r8192_priv *priv = ieee80211_priv(dev);
1516 1414
1517 TempVal = 0; 1415 TempVal = 0;
1518 if(!bInCH14) 1416 if (!bInCH14) {
1519 { 1417 /* Write 0xa22 0xa23 */
1520 //Write 0xa22 0xa23
1521 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + 1418 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1522 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ; 1419 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8);
1523 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); 1420 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1524 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", 1421 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1525 rCCK0_TxFilter1, TempVal); 1422 rCCK0_TxFilter1, TempVal);
1526 //Write 0xa24 ~ 0xa27 1423 /* Write 0xa24 ~ 0xa27 */
1527 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + 1424 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1528 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + 1425 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1529 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ 1426 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
@@ -1531,25 +1428,23 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH
1531 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); 1428 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1532 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", 1429 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1533 rCCK0_TxFilter2, TempVal); 1430 rCCK0_TxFilter2, TempVal);
1534 //Write 0xa28 0xa29 1431 /* Write 0xa28 0xa29 */
1535 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + 1432 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1536 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; 1433 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8);
1537 1434
1538 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); 1435 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1539 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", 1436 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1540 rCCK0_DebugPort, TempVal); 1437 rCCK0_DebugPort, TempVal);
1541 } 1438 } else {
1542 else 1439 /*priv->CCKTxPowerAdjustCntNotCh14++; cosa add for debug.*/
1543 { 1440 /* Write 0xa22 0xa23 */
1544// priv->CCKTxPowerAdjustCntNotCh14++; //cosa add for debug.
1545 //Write 0xa22 0xa23
1546 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + 1441 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1547 (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ; 1442 (CCKSwingTable_Ch14[priv->CCK_index][1]<<8);
1548 1443
1549 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); 1444 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1550 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", 1445 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1551 rCCK0_TxFilter1, TempVal); 1446 rCCK0_TxFilter1, TempVal);
1552 //Write 0xa24 ~ 0xa27 1447 /* Write 0xa24 ~ 0xa27 */
1553 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + 1448 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1554 (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + 1449 (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1555 (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ 1450 (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
@@ -1557,9 +1452,9 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH
1557 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); 1452 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1558 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", 1453 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1559 rCCK0_TxFilter2, TempVal); 1454 rCCK0_TxFilter2, TempVal);
1560 //Write 0xa28 0xa29 1455 /* Write 0xa28 0xa29 */
1561 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + 1456 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1562 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; 1457 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1563 1458
1564 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); 1459 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1565 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", 1460 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
@@ -1567,20 +1462,17 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH
1567 } 1462 }
1568} 1463}
1569 1464
1570
1571
1572void dm_cck_txpower_adjust(struct net_device *dev, bool binch14) 1465void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1573{ // dm_CCKTxPowerAdjust 1466{ /* dm_CCKTxPowerAdjust */
1574
1575 struct r8192_priv *priv = ieee80211_priv(dev); 1467 struct r8192_priv *priv = ieee80211_priv(dev);
1576 if(priv->bDcut == TRUE) 1468
1469 if (priv->bDcut == TRUE)
1577 dm_CCKTxPowerAdjust_TSSI(dev, binch14); 1470 dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1578 else 1471 else
1579 dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); 1472 dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1580} 1473}
1581 1474
1582 1475#ifndef RTL8192U
1583#ifndef RTL8192U
1584static void dm_txpower_reset_recovery( 1476static void dm_txpower_reset_recovery(
1585 struct net_device *dev 1477 struct net_device *dev
1586) 1478)
@@ -1589,75 +1481,71 @@ static void dm_txpower_reset_recovery(
1589 1481
1590 RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n"); 1482 RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1591 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); 1483 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1592 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); 1484 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1593 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex); 1485 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", priv->rfa_txpowertrackingindex);
1594 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain); 1486 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
1595 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->cck_present_attentuation); 1487 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", priv->cck_present_attentuation);
1596 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); 1488 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1597 1489
1598 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); 1490 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1599 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); 1491 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1600 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex); 1492 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", priv->rfc_txpowertrackingindex);
1601 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain); 1493 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
1602 1494
1603} // dm_TXPowerResetRecovery 1495} /* dm_TXPowerResetRecovery */
1604 1496
1605void dm_restore_dynamic_mechanism_state(struct net_device *dev) 1497void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1606{ 1498{
1607 struct r8192_priv *priv = ieee80211_priv(dev); 1499 struct r8192_priv *priv = ieee80211_priv(dev);
1608 u32 reg_ratr = priv->rate_adaptive.last_ratr; 1500 u32 reg_ratr = priv->rate_adaptive.last_ratr;
1609 1501
1610 if(!priv->up) 1502 if (!priv->up) {
1611 {
1612 RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); 1503 RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1613 return; 1504 return;
1614 } 1505 }
1615 1506
1616 // 1507 /* Restore previous state for rate adaptive */
1617 // Restore previous state for rate adaptive 1508 if (priv->rate_adaptive.rate_adaptive_disabled)
1618 //
1619 if(priv->rate_adaptive.rate_adaptive_disabled)
1620 return; 1509 return;
1621 // TODO: Only 11n mode is implemented currently, 1510 /* TODO: Only 11n mode is implemented currently, */
1622 if(!(priv->ieee80211->mode==WIRELESS_MODE_N_24G || 1511 if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
1623 priv->ieee80211->mode==WIRELESS_MODE_N_5G)) 1512 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
1624 return; 1513 return;
1514
1625 { 1515 {
1626 /* 2007/11/15 MH Copy from 8190PCI. */ 1516 /* 2007/11/15 MH Copy from 8190PCI. */
1627 u32 ratr_value; 1517 u32 ratr_value;
1518
1628 ratr_value = reg_ratr; 1519 ratr_value = reg_ratr;
1629 if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled 1520 if (priv->rf_type == RF_1T2R) { /* 1T2R, Spatial Stream 2 should be disabled */
1630 {
1631 ratr_value &= ~(RATE_ALL_OFDM_2SS); 1521 ratr_value &= ~(RATE_ALL_OFDM_2SS);
1632 //DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value); 1522 /*DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);*/
1633 } 1523 }
1634 //DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value); 1524 /*DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);*/
1635 //cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]); 1525 /*cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);*/
1636 write_nic_dword(dev, RATR0, ratr_value); 1526 write_nic_dword(dev, RATR0, ratr_value);
1637 write_nic_byte(dev, UFWP, 1); 1527 write_nic_byte(dev, UFWP, 1);
1638 } 1528 }
1639 //Restore TX Power Tracking Index 1529 /* Restore TX Power Tracking Index */
1640 if (priv->btxpower_trackingInit && priv->btxpower_tracking) 1530 if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1641 dm_txpower_reset_recovery(dev); 1531 dm_txpower_reset_recovery(dev);
1642 1532
1643 // 1533 /* Restore BB Initial Gain */
1644 //Restore BB Initial Gain
1645 //
1646 dm_bb_initialgain_restore(dev); 1534 dm_bb_initialgain_restore(dev);
1647 1535
1648} // DM_RestoreDynamicMechanismState 1536} /* DM_RestoreDynamicMechanismState */
1649 1537
1650static void dm_bb_initialgain_restore(struct net_device *dev) 1538static void dm_bb_initialgain_restore(struct net_device *dev)
1651{ 1539{
1652 struct r8192_priv *priv = ieee80211_priv(dev); 1540 struct r8192_priv *priv = ieee80211_priv(dev);
1653 u32 bit_mask = 0x7f; //Bit0~ Bit6 1541 u32 bit_mask = 0x7f; /* Bit0~ Bit6 */
1654 1542
1655 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) 1543 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1656 return; 1544 return;
1657 1545
1658 //Disable Initial Gain 1546 /* Disable Initial Gain */
1659 //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800); 1547 /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1660 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. 1548 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
1661 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1); 1549 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1662 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1); 1550 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1663 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1); 1551 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
@@ -1665,41 +1553,39 @@ static void dm_bb_initialgain_restore(struct net_device *dev)
1665 bit_mask = bMaskByte2; 1553 bit_mask = bMaskByte2;
1666 rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca); 1554 rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1667 1555
1668 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1); 1556 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1669 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1); 1557 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1670 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1); 1558 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1671 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1); 1559 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1672 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca); 1560 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
1673 //Enable Initial Gain 1561 /* Enable Initial Gain */
1674 //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100); 1562 /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);*/
1675 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. 1563 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */
1676
1677} // dm_BBInitialGainRestore
1678 1564
1565} /* dm_BBInitialGainRestore */
1679 1566
1680void dm_backup_dynamic_mechanism_state(struct net_device *dev) 1567void dm_backup_dynamic_mechanism_state(struct net_device *dev)
1681{ 1568{
1682 struct r8192_priv *priv = ieee80211_priv(dev); 1569 struct r8192_priv *priv = ieee80211_priv(dev);
1683 1570
1684 // Fsync to avoid reset 1571 /* Fsync to avoid reset */
1685 priv->bswitch_fsync = false; 1572 priv->bswitch_fsync = false;
1686 priv->bfsync_processing = false; 1573 priv->bfsync_processing = false;
1687 //Backup BB InitialGain 1574 /* Backup BB InitialGain */
1688 dm_bb_initialgain_backup(dev); 1575 dm_bb_initialgain_backup(dev);
1689 1576
1690} // DM_BackupDynamicMechanismState 1577} /* DM_BackupDynamicMechanismState */
1691
1692 1578
1693static void dm_bb_initialgain_backup(struct net_device *dev) 1579static void dm_bb_initialgain_backup(struct net_device *dev)
1694{ 1580{
1695 struct r8192_priv *priv = ieee80211_priv(dev); 1581 struct r8192_priv *priv = ieee80211_priv(dev);
1696 u32 bit_mask = bMaskByte0; //Bit0~ Bit6 1582 u32 bit_mask = bMaskByte0; /* Bit0~ Bit6 */
1697 1583
1698 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) 1584 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1699 return; 1585 return;
1700 1586
1701 //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800); 1587 /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1702 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. 1588 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
1703 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask); 1589 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1704 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask); 1590 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1705 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask); 1591 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
@@ -1707,13 +1593,13 @@ static void dm_bb_initialgain_backup(struct net_device *dev)
1707 bit_mask = bMaskByte2; 1593 bit_mask = bMaskByte2;
1708 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask); 1594 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1709 1595
1710 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1); 1596 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1711 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1); 1597 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1712 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1); 1598 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1713 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1); 1599 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1714 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca); 1600 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
1715 1601
1716} // dm_BBInitialGainBakcup 1602} /* dm_BBInitialGainBakcup */
1717 1603
1718#endif 1604#endif
1719/*----------------------------------------------------------------------------- 1605/*-----------------------------------------------------------------------------
@@ -1736,67 +1622,44 @@ static void dm_bb_initialgain_backup(struct net_device *dev)
1736void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, 1622void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type,
1737 u32 dm_value) 1623 u32 dm_value)
1738{ 1624{
1739 if (dm_type == DIG_TYPE_THRESH_HIGH) 1625 if (dm_type == DIG_TYPE_THRESH_HIGH) {
1740 {
1741 dm_digtable.rssi_high_thresh = dm_value; 1626 dm_digtable.rssi_high_thresh = dm_value;
1742 } 1627 } else if (dm_type == DIG_TYPE_THRESH_LOW) {
1743 else if (dm_type == DIG_TYPE_THRESH_LOW)
1744 {
1745 dm_digtable.rssi_low_thresh = dm_value; 1628 dm_digtable.rssi_low_thresh = dm_value;
1746 } 1629 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1747 else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1748 {
1749 dm_digtable.rssi_high_power_highthresh = dm_value; 1630 dm_digtable.rssi_high_power_highthresh = dm_value;
1750 } 1631 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1751 else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1752 {
1753 dm_digtable.rssi_high_power_highthresh = dm_value; 1632 dm_digtable.rssi_high_power_highthresh = dm_value;
1754 } 1633 } else if (dm_type == DIG_TYPE_ENABLE) {
1755 else if (dm_type == DIG_TYPE_ENABLE)
1756 {
1757 dm_digtable.dig_state = DM_STA_DIG_MAX; 1634 dm_digtable.dig_state = DM_STA_DIG_MAX;
1758 dm_digtable.dig_enable_flag = true; 1635 dm_digtable.dig_enable_flag = true;
1759 } 1636 } else if (dm_type == DIG_TYPE_DISABLE) {
1760 else if (dm_type == DIG_TYPE_DISABLE)
1761 {
1762 dm_digtable.dig_state = DM_STA_DIG_MAX; 1637 dm_digtable.dig_state = DM_STA_DIG_MAX;
1763 dm_digtable.dig_enable_flag = false; 1638 dm_digtable.dig_enable_flag = false;
1764 } 1639 } else if (dm_type == DIG_TYPE_DBG_MODE) {
1765 else if (dm_type == DIG_TYPE_DBG_MODE) 1640 if (dm_value >= DM_DBG_MAX)
1766 {
1767 if(dm_value >= DM_DBG_MAX)
1768 dm_value = DM_DBG_OFF; 1641 dm_value = DM_DBG_OFF;
1769 dm_digtable.dbg_mode = (u8)dm_value; 1642 dm_digtable.dbg_mode = (u8)dm_value;
1770 } 1643 } else if (dm_type == DIG_TYPE_RSSI) {
1771 else if (dm_type == DIG_TYPE_RSSI) 1644 if (dm_value > 100)
1772 {
1773 if(dm_value > 100)
1774 dm_value = 30; 1645 dm_value = 30;
1775 dm_digtable.rssi_val = (long)dm_value; 1646 dm_digtable.rssi_val = (long)dm_value;
1776 } 1647 } else if (dm_type == DIG_TYPE_ALGORITHM) {
1777 else if (dm_type == DIG_TYPE_ALGORITHM)
1778 {
1779 if (dm_value >= DIG_ALGO_MAX) 1648 if (dm_value >= DIG_ALGO_MAX)
1780 dm_value = DIG_ALGO_BY_FALSE_ALARM; 1649 dm_value = DIG_ALGO_BY_FALSE_ALARM;
1781 if(dm_digtable.dig_algorithm != (u8)dm_value) 1650 if (dm_digtable.dig_algorithm != (u8)dm_value)
1782 dm_digtable.dig_algorithm_switch = 1; 1651 dm_digtable.dig_algorithm_switch = 1;
1783 dm_digtable.dig_algorithm = (u8)dm_value; 1652 dm_digtable.dig_algorithm = (u8)dm_value;
1784 } 1653 } else if (dm_type == DIG_TYPE_BACKOFF) {
1785 else if (dm_type == DIG_TYPE_BACKOFF) 1654 if (dm_value > 30)
1786 {
1787 if(dm_value > 30)
1788 dm_value = 30; 1655 dm_value = 30;
1789 dm_digtable.backoff_val = (u8)dm_value; 1656 dm_digtable.backoff_val = (u8)dm_value;
1790 } 1657 } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
1791 else if(dm_type == DIG_TYPE_RX_GAIN_MIN) 1658 if (dm_value == 0)
1792 {
1793 if(dm_value == 0)
1794 dm_value = 0x1; 1659 dm_value = 0x1;
1795 dm_digtable.rx_gain_range_min = (u8)dm_value; 1660 dm_digtable.rx_gain_range_min = (u8)dm_value;
1796 } 1661 } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
1797 else if(dm_type == DIG_TYPE_RX_GAIN_MAX) 1662 if (dm_value > 0x50)
1798 {
1799 if(dm_value > 0x50)
1800 dm_value = 0x50; 1663 dm_value = 0x50;
1801 dm_digtable.rx_gain_range_max = (u8)dm_value; 1664 dm_digtable.rx_gain_range_max = (u8)dm_value;
1802 } 1665 }
@@ -1824,7 +1687,7 @@ static void dm_dig_init(struct net_device *dev)
1824 /* 2007/10/05 MH Disable DIG scheme now. Not tested. */ 1687 /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1825 dm_digtable.dig_enable_flag = true; 1688 dm_digtable.dig_enable_flag = true;
1826 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; 1689 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1827 dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig 1690 dm_digtable.dbg_mode = DM_DBG_OFF; /* off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig */
1828 dm_digtable.dig_algorithm_switch = 0; 1691 dm_digtable.dig_algorithm_switch = 0;
1829 1692
1830 /* 2007/10/04 MH Define init gain threshold. */ 1693 /* 2007/10/04 MH Define init gain threshold. */
@@ -1838,17 +1701,16 @@ static void dm_dig_init(struct net_device *dev)
1838 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; 1701 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1839 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; 1702 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1840 1703
1841 dm_digtable.rssi_val = 50; //for new dig debug rssi value 1704 dm_digtable.rssi_val = 50; /* for new dig debug rssi value */
1842 dm_digtable.backoff_val = DM_DIG_BACKOFF; 1705 dm_digtable.backoff_val = DM_DIG_BACKOFF;
1843 dm_digtable.rx_gain_range_max = DM_DIG_MAX; 1706 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1844 if(priv->CustomerID == RT_CID_819x_Netcore) 1707 if (priv->CustomerID == RT_CID_819x_Netcore)
1845 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; 1708 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1846 else 1709 else
1847 dm_digtable.rx_gain_range_min = DM_DIG_MIN; 1710 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1848 1711
1849} /* dm_dig_init */ 1712} /* dm_dig_init */
1850 1713
1851
1852/*----------------------------------------------------------------------------- 1714/*-----------------------------------------------------------------------------
1853 * Function: dm_ctrl_initgain_byrssi() 1715 * Function: dm_ctrl_initgain_byrssi()
1854 * 1716 *
@@ -1868,20 +1730,18 @@ static void dm_dig_init(struct net_device *dev)
1868 *---------------------------------------------------------------------------*/ 1730 *---------------------------------------------------------------------------*/
1869static void dm_ctrl_initgain_byrssi(struct net_device *dev) 1731static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1870{ 1732{
1871
1872 if (dm_digtable.dig_enable_flag == false) 1733 if (dm_digtable.dig_enable_flag == false)
1873 return; 1734 return;
1874 1735
1875 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) 1736 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1876 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev); 1737 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1877 else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) 1738 else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1878 dm_ctrl_initgain_byrssi_by_driverrssi(dev); 1739 dm_ctrl_initgain_byrssi_by_driverrssi(dev);
1879// ; 1740 /* ; */
1880 else 1741 else
1881 return; 1742 return;
1882} 1743}
1883 1744
1884
1885static void dm_ctrl_initgain_byrssi_by_driverrssi( 1745static void dm_ctrl_initgain_byrssi_by_driverrssi(
1886 struct net_device *dev) 1746 struct net_device *dev)
1887{ 1747{
@@ -1892,32 +1752,33 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi(
1892 if (dm_digtable.dig_enable_flag == false) 1752 if (dm_digtable.dig_enable_flag == false)
1893 return; 1753 return;
1894 1754
1895 //DbgPrint("Dig by Sw Rssi \n"); 1755 /*DbgPrint("Dig by Sw Rssi\n");*/
1896 if(dm_digtable.dig_algorithm_switch) // if switched algorithm, we have to disable FW Dig. 1756 if (dm_digtable.dig_algorithm_switch) /* if switched algorithm, we have to disable FW Dig. */
1897 fw_dig = 0; 1757 fw_dig = 0;
1898 if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled 1758
1899 {// FW DIG Off 1759 if (fw_dig <= 3) { /* execute several times to make sure the FW Dig is disabled */
1900 for(i=0; i<3; i++) 1760 /* FW DIG Off */
1901 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. 1761 for (i = 0; i < 3; i++)
1762 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
1902 fw_dig++; 1763 fw_dig++;
1903 dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off. 1764 dm_digtable.dig_state = DM_STA_DIG_OFF; /* fw dig off. */
1904 } 1765 }
1905 1766
1906 if(priv->ieee80211->state == IEEE80211_LINKED) 1767 if (priv->ieee80211->state == IEEE80211_LINKED)
1907 dm_digtable.cur_connect_state = DIG_CONNECT; 1768 dm_digtable.cur_connect_state = DIG_CONNECT;
1908 else 1769 else
1909 dm_digtable.cur_connect_state = DIG_DISCONNECT; 1770 dm_digtable.cur_connect_state = DIG_DISCONNECT;
1910 1771
1911 //DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n", 1772 /*DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d\n",
1912 //DM_DigTable.PreConnectState, DM_DigTable.CurConnectState); 1773 DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);*/
1913 1774
1914 if(dm_digtable.dbg_mode == DM_DBG_OFF) 1775 if (dm_digtable.dbg_mode == DM_DBG_OFF)
1915 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; 1776 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1916 //DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val); 1777 /*DbgPrint("DM_DigTable.Rssi_val = %d\n", DM_DigTable.Rssi_val);*/
1917 dm_initial_gain(dev); 1778 dm_initial_gain(dev);
1918 dm_pd_th(dev); 1779 dm_pd_th(dev);
1919 dm_cs_ratio(dev); 1780 dm_cs_ratio(dev);
1920 if(dm_digtable.dig_algorithm_switch) 1781 if (dm_digtable.dig_algorithm_switch)
1921 dm_digtable.dig_algorithm_switch = 0; 1782 dm_digtable.dig_algorithm_switch = 0;
1922 dm_digtable.pre_connect_state = dm_digtable.cur_connect_state; 1783 dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1923 1784
@@ -1933,152 +1794,138 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1933 if (dm_digtable.dig_enable_flag == false) 1794 if (dm_digtable.dig_enable_flag == false)
1934 return; 1795 return;
1935 1796
1936 if(dm_digtable.dig_algorithm_switch) 1797 if (dm_digtable.dig_algorithm_switch) {
1937 {
1938 dm_digtable.dig_state = DM_STA_DIG_MAX; 1798 dm_digtable.dig_state = DM_STA_DIG_MAX;
1939 // Fw DIG On. 1799 /* Fw DIG On. */
1940 for(i=0; i<3; i++) 1800 for (i = 0; i < 3; i++)
1941 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. 1801 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite.*/
1942 dm_digtable.dig_algorithm_switch = 0; 1802 dm_digtable.dig_algorithm_switch = 0;
1943 } 1803 }
1944 1804
1945 if (priv->ieee80211->state != IEEE80211_LINKED) 1805 if (priv->ieee80211->state != IEEE80211_LINKED)
1946 return; 1806 return;
1947 1807
1948 // For smooth, we can not change DIG state. 1808 /* For smooth, we can not change DIG state. */
1949 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && 1809 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1950 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) 1810 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1951 {
1952 return; 1811 return;
1953 } 1812
1954 //DbgPrint("Dig by Fw False Alarm\n"); 1813 /*DbgPrint("Dig by Fw False Alarm\n");*/
1955 //if (DM_DigTable.Dig_State == DM_STA_DIG_OFF) 1814 /*if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)*/
1956 /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d", 1815 /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
1957 pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh, 1816 pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
1958 DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/ 1817 DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
1959 /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold 1818 /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
1960 and then execute the step below. */ 1819 and then execute the step below. */
1961 if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) 1820 if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1962 {
1963 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters 1821 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1964 will be reset to init value. We must prevent the condition. */ 1822 will be reset to init value. We must prevent the condition. */
1965 if (dm_digtable.dig_state == DM_STA_DIG_OFF && 1823 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1966 (priv->reset_count == reset_cnt)) 1824 (priv->reset_count == reset_cnt)) {
1967 {
1968 return; 1825 return;
1969 } 1826 }
1970 else 1827 reset_cnt = priv->reset_count;
1971 {
1972 reset_cnt = priv->reset_count;
1973 }
1974 1828
1975 // If DIG is off, DIG high power state must reset. 1829 /* If DIG is off, DIG high power state must reset. */
1976 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; 1830 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1977 dm_digtable.dig_state = DM_STA_DIG_OFF; 1831 dm_digtable.dig_state = DM_STA_DIG_OFF;
1978 1832
1979 // 1.1 DIG Off. 1833 /* 1.1 DIG Off. */
1980 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. 1834 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
1981 1835
1982 // 1.2 Set initial gain. 1836 /* 1.2 Set initial gain. */
1983 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17); 1837 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1984 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17); 1838 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1985 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17); 1839 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1986 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17); 1840 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1987 1841
1988 // 1.3 Lower PD_TH for OFDM. 1842 /* 1.3 Lower PD_TH for OFDM. */
1989 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) 1843 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1990 { 1844 /*
1991 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ 1845 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
1992 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. 1846 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1847 */
1993 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); 1848 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1994 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 1849 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1995 write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40); 1850 write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
1851 else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1852 else
1853 PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
1996 */ 1854 */
1997 //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E) 1855 } else
1998
1999
2000 //else
2001 //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2002 }
2003 else
2004 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); 1856 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2005 1857
2006 // 1.4 Lower CS ratio for CCK. 1858 /* 1.4 Lower CS ratio for CCK. */
2007 write_nic_byte(dev, 0xa0a, 0x08); 1859 write_nic_byte(dev, 0xa0a, 0x08);
2008 1860
2009 // 1.5 Higher EDCCA. 1861 /* 1.5 Higher EDCCA. */
2010 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325); 1862 /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);*/
2011 return; 1863 return;
2012 1864
2013 } 1865 }
2014 1866
2015 /* 2. When RSSI increase, We have to judge if it is larger than a threshold 1867 /* 2. When RSSI increase, We have to judge if it is larger than a threshold
2016 and then execute the step below. */ 1868 and then execute the step below. */
2017 if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)) 1869 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
2018 {
2019 u8 reset_flag = 0; 1870 u8 reset_flag = 0;
2020 1871
2021 if (dm_digtable.dig_state == DM_STA_DIG_ON && 1872 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
2022 (priv->reset_count == reset_cnt)) 1873 (priv->reset_count == reset_cnt)) {
2023 {
2024 dm_ctrl_initgain_byrssi_highpwr(dev); 1874 dm_ctrl_initgain_byrssi_highpwr(dev);
2025 return; 1875 return;
2026 } 1876 }
2027 else 1877 if (priv->reset_count != reset_cnt)
2028 { 1878 reset_flag = 1;
2029 if (priv->reset_count != reset_cnt)
2030 reset_flag = 1;
2031 1879
2032 reset_cnt = priv->reset_count; 1880 reset_cnt = priv->reset_count;
2033 }
2034 1881
2035 dm_digtable.dig_state = DM_STA_DIG_ON; 1882 dm_digtable.dig_state = DM_STA_DIG_ON;
2036 //DbgPrint("DIG ON\n\r"); 1883 /*DbgPrint("DIG ON\n\r");*/
2037 1884
2038 // 2.1 Set initial gain. 1885 /*
2039 // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment. 1886 * 2.1 Set initial gain.
2040 if (reset_flag == 1) 1887 * 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
2041 { 1888 */
1889 if (reset_flag == 1) {
2042 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c); 1890 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
2043 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c); 1891 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
2044 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c); 1892 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
2045 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c); 1893 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
2046 } 1894 } else {
2047 else
2048 {
2049 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20); 1895 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
2050 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20); 1896 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
2051 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20); 1897 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
2052 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20); 1898 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
2053 } 1899 }
2054 1900
2055 // 2.2 Higher PD_TH for OFDM. 1901 /* 2.2 Higher PD_TH for OFDM. */
2056 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) 1902 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2057 { 1903 /*
2058 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ 1904 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
2059 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. 1905 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1906 */
2060 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); 1907 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2061 /* 1908 /*
2062 else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 1909 else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2063 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); 1910 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1911 else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1912 else
1913 PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
2064 */ 1914 */
2065 //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E) 1915 } else
2066
2067 //else
2068 //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
2069 }
2070 else
2071 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); 1916 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2072 1917
2073 // 2.3 Higher CS ratio for CCK. 1918 /* 2.3 Higher CS ratio for CCK. */
2074 write_nic_byte(dev, 0xa0a, 0xcd); 1919 write_nic_byte(dev, 0xa0a, 0xcd);
2075 1920
2076 // 2.4 Lower EDCCA. 1921 /*
2077 /* 2008/01/11 MH 90/92 series are the same. */ 1922 * 2.4 Lower EDCCA.
2078 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346); 1923 * 2008/01/11 MH 90/92 series are the same.
1924 */
1925 /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);*/
2079 1926
2080 // 2.5 DIG On. 1927 /* 2.5 DIG On. */
2081 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. 1928 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */
2082 1929
2083 } 1930 }
2084 1931
@@ -2086,7 +1933,6 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
2086 1933
2087} /* dm_CtrlInitGainByRssi */ 1934} /* dm_CtrlInitGainByRssi */
2088 1935
2089
2090/*----------------------------------------------------------------------------- 1936/*-----------------------------------------------------------------------------
2091 * Function: dm_ctrl_initgain_byrssi_highpwr() 1937 * Function: dm_ctrl_initgain_byrssi_highpwr()
2092 * 1938 *
@@ -2109,58 +1955,49 @@ static void dm_ctrl_initgain_byrssi_highpwr(
2109 struct r8192_priv *priv = ieee80211_priv(dev); 1955 struct r8192_priv *priv = ieee80211_priv(dev);
2110 static u32 reset_cnt_highpwr; 1956 static u32 reset_cnt_highpwr;
2111 1957
2112 // For smooth, we can not change high power DIG state in the range. 1958 /* For smooth, we can not change high power DIG state in the range. */
2113 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) && 1959 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
2114 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh)) 1960 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
2115 {
2116 return; 1961 return;
2117 }
2118 1962
2119 /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if 1963 /*
2120 it is larger than a threshold and then execute the step below. */ 1964 * 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
2121 // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. 1965 * it is larger than a threshold and then execute the step below.
2122 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) 1966 *
2123 { 1967 * 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1968 */
1969 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
2124 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && 1970 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
2125 (priv->reset_count == reset_cnt_highpwr)) 1971 (priv->reset_count == reset_cnt_highpwr))
2126 return; 1972 return;
2127 else 1973 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
2128 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
2129 1974
2130 // 3.1 Higher PD_TH for OFDM for high power state. 1975 /* 3.1 Higher PD_TH for OFDM for high power state. */
2131 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) 1976 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2132 {
2133 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); 1977 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2134 1978
2135 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 1979 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2136 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); 1980 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2137 */ 1981 */
2138 1982
2139 } 1983 } else
2140 else
2141 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); 1984 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2142 } 1985 } else {
2143 else 1986 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
2144 {
2145 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
2146 (priv->reset_count == reset_cnt_highpwr)) 1987 (priv->reset_count == reset_cnt_highpwr))
2147 return; 1988 return;
2148 else 1989 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
2149 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
2150 1990
2151 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh && 1991 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
2152 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) 1992 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
2153 { 1993 /* 3.2 Recover PD_TH for OFDM for normal power region. */
2154 // 3.2 Recover PD_TH for OFDM for normal power region. 1994 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2155 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2156 {
2157 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); 1995 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2158 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 1996 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2159 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); 1997 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2160 */ 1998 */
2161 1999
2162 } 2000 } else
2163 else
2164 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); 2001 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2165 } 2002 }
2166 } 2003 }
@@ -2169,51 +2006,42 @@ static void dm_ctrl_initgain_byrssi_highpwr(
2169 2006
2170} /* dm_CtrlInitGainByRssiHighPwr */ 2007} /* dm_CtrlInitGainByRssiHighPwr */
2171 2008
2172
2173static void dm_initial_gain( 2009static void dm_initial_gain(
2174 struct net_device *dev) 2010 struct net_device *dev)
2175{ 2011{
2176 struct r8192_priv *priv = ieee80211_priv(dev); 2012 struct r8192_priv *priv = ieee80211_priv(dev);
2177 u8 initial_gain=0; 2013 u8 initial_gain = 0;
2178 static u8 initialized, force_write; 2014 static u8 initialized, force_write;
2179 static u32 reset_cnt; 2015 static u32 reset_cnt;
2180 u8 tmp; 2016 u8 tmp;
2181 2017
2182 if(dm_digtable.dig_algorithm_switch) 2018 if (dm_digtable.dig_algorithm_switch) {
2183 {
2184 initialized = 0; 2019 initialized = 0;
2185 reset_cnt = 0; 2020 reset_cnt = 0;
2186 } 2021 }
2187 2022
2188 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) 2023 if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2189 { 2024 if (dm_digtable.cur_connect_state == DIG_CONNECT) {
2190 if(dm_digtable.cur_connect_state == DIG_CONNECT) 2025 if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
2191 {
2192 if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
2193 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max; 2026 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
2194 else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) 2027 else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
2195 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min; 2028 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
2196 else 2029 else
2197 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val; 2030 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
2198 } 2031 } else { /* current state is disconnected */
2199 else //current state is disconnected 2032 if (dm_digtable.cur_ig_value == 0)
2200 {
2201 if(dm_digtable.cur_ig_value == 0)
2202 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; 2033 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2203 else 2034 else
2204 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; 2035 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
2205 } 2036 }
2206 } 2037 } else { /* disconnected -> connected or connected -> disconnected */
2207 else // disconnected -> connected or connected -> disconnected
2208 {
2209 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; 2038 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2210 dm_digtable.pre_ig_value = 0; 2039 dm_digtable.pre_ig_value = 0;
2211 } 2040 }
2212 //DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue); 2041 /*DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);*/
2213 2042
2214 // if silent reset happened, we should rewrite the values back 2043 /* if silent reset happened, we should rewrite the values back */
2215 if(priv->reset_count != reset_cnt) 2044 if (priv->reset_count != reset_cnt) {
2216 {
2217 force_write = 1; 2045 force_write = 1;
2218 reset_cnt = priv->reset_count; 2046 reset_cnt = priv->reset_count;
2219 } 2047 }
@@ -2223,12 +2051,11 @@ static void dm_initial_gain(
2223 force_write = 1; 2051 force_write = 1;
2224 2052
2225 { 2053 {
2226 if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) 2054 if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
2227 || !initialized || force_write) 2055 || !initialized || force_write) {
2228 {
2229 initial_gain = (u8)dm_digtable.cur_ig_value; 2056 initial_gain = (u8)dm_digtable.cur_ig_value;
2230 //DbgPrint("Write initial gain = 0x%x\n", initial_gain); 2057 /*DbgPrint("Write initial gain = 0x%x\n", initial_gain);*/
2231 // Set initial gain. 2058 /* Set initial gain. */
2232 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); 2059 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
2233 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); 2060 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
2234 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); 2061 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
@@ -2247,93 +2074,77 @@ static void dm_pd_th(
2247 static u8 initialized, force_write; 2074 static u8 initialized, force_write;
2248 static u32 reset_cnt; 2075 static u32 reset_cnt;
2249 2076
2250 if(dm_digtable.dig_algorithm_switch) 2077 if (dm_digtable.dig_algorithm_switch) {
2251 {
2252 initialized = 0; 2078 initialized = 0;
2253 reset_cnt = 0; 2079 reset_cnt = 0;
2254 } 2080 }
2255 2081
2256 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) 2082 if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2257 { 2083 if (dm_digtable.cur_connect_state == DIG_CONNECT) {
2258 if(dm_digtable.cur_connect_state == DIG_CONNECT)
2259 {
2260 if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) 2084 if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2261 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER; 2085 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
2262 else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) 2086 else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
2263 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; 2087 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2264 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) && 2088 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2265 (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh)) 2089 (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2266 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER; 2090 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2267 else 2091 else
2268 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate; 2092 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
2269 } 2093 } else {
2270 else
2271 {
2272 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; 2094 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2273 } 2095 }
2274 } 2096 } else { /* disconnected -> connected or connected -> disconnected */
2275 else // disconnected -> connected or connected -> disconnected
2276 {
2277 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; 2097 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2278 } 2098 }
2279 2099
2280 // if silent reset happened, we should rewrite the values back 2100 /* if silent reset happened, we should rewrite the values back */
2281 if(priv->reset_count != reset_cnt) 2101 if (priv->reset_count != reset_cnt) {
2282 {
2283 force_write = 1; 2102 force_write = 1;
2284 reset_cnt = priv->reset_count; 2103 reset_cnt = priv->reset_count;
2285 } 2104 }
2286 2105
2287 { 2106 {
2288 if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || 2107 if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2289 (initialized<=3) || force_write) 2108 (initialized <= 3) || force_write) {
2290 { 2109 /*DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);*/
2291 //DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState); 2110 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
2292 if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) 2111 /* Lower PD_TH for OFDM. */
2293 { 2112 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2294 // Lower PD_TH for OFDM. 2113 /*
2295 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) 2114 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
2296 { 2115 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2297 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ 2116 */
2298 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2299 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); 2117 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2300 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 2118 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2301 write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); 2119 write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2302 */ 2120 */
2303 } 2121 } else
2304 else
2305 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); 2122 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2306 } 2123 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
2307 else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) 2124 /* Higher PD_TH for OFDM. */
2308 { 2125 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2309 // Higher PD_TH for OFDM. 2126 /*
2310 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) 2127 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
2311 { 2128 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2312 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ 2129 */
2313 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2314 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); 2130 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2315 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 2131 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2316 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); 2132 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2317 */ 2133 */
2318 } 2134 } else
2319 else
2320 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); 2135 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2321 } 2136 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
2322 else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) 2137 /* Higher PD_TH for OFDM for high power state. */
2323 { 2138 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2324 // Higher PD_TH for OFDM for high power state.
2325 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2326 {
2327 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); 2139 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2328 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) 2140 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2329 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); 2141 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2330 */ 2142 */
2331 } 2143 } else
2332 else
2333 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); 2144 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2334 } 2145 }
2335 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; 2146 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2336 if(initialized <= 3) 2147 if (initialized <= 3)
2337 initialized++; 2148 initialized++;
2338 force_write = 0; 2149 force_write = 0;
2339 } 2150 }
@@ -2347,54 +2158,40 @@ static void dm_cs_ratio(
2347 static u8 initialized, force_write; 2158 static u8 initialized, force_write;
2348 static u32 reset_cnt; 2159 static u32 reset_cnt;
2349 2160
2350 if(dm_digtable.dig_algorithm_switch) 2161 if (dm_digtable.dig_algorithm_switch) {
2351 {
2352 initialized = 0; 2162 initialized = 0;
2353 reset_cnt = 0; 2163 reset_cnt = 0;
2354 } 2164 }
2355 2165
2356 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) 2166 if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2357 { 2167 if (dm_digtable.cur_connect_state == DIG_CONNECT) {
2358 if(dm_digtable.cur_connect_state == DIG_CONNECT) 2168 if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
2359 {
2360 if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2361 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; 2169 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2362 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)) 2170 else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
2363 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; 2171 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2364 else 2172 else
2365 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; 2173 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2366 } 2174 } else {
2367 else
2368 {
2369 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; 2175 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2370 } 2176 }
2371 } 2177 } else /* disconnected -> connected or connected -> disconnected */
2372 else // disconnected -> connected or connected -> disconnected
2373 {
2374 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; 2178 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2375 }
2376 2179
2377 // if silent reset happened, we should rewrite the values back 2180 /* if silent reset happened, we should rewrite the values back */
2378 if(priv->reset_count != reset_cnt) 2181 if (priv->reset_count != reset_cnt) {
2379 {
2380 force_write = 1; 2182 force_write = 1;
2381 reset_cnt = priv->reset_count; 2183 reset_cnt = priv->reset_count;
2382 } 2184 }
2383 2185
2384
2385 { 2186 {
2386 if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || 2187 if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2387 !initialized || force_write) 2188 !initialized || force_write) {
2388 { 2189 /*DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);*/
2389 //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState); 2190 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) {
2390 if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) 2191 /* Lower CS ratio for CCK. */
2391 {
2392 // Lower CS ratio for CCK.
2393 write_nic_byte(dev, 0xa0a, 0x08); 2192 write_nic_byte(dev, 0xa0a, 0x08);
2394 } 2193 } else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) {
2395 else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) 2194 /* Higher CS ratio for CCK. */
2396 {
2397 // Higher CS ratio for CCK.
2398 write_nic_byte(dev, 0xa0a, 0xcd); 2195 write_nic_byte(dev, 0xa0a, 0xcd);
2399 } 2196 }
2400 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; 2197 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
@@ -2411,53 +2208,46 @@ void dm_init_edca_turbo(struct net_device *dev)
2411 priv->bcurrent_turbo_EDCA = false; 2208 priv->bcurrent_turbo_EDCA = false;
2412 priv->ieee80211->bis_any_nonbepkts = false; 2209 priv->ieee80211->bis_any_nonbepkts = false;
2413 priv->bis_cur_rdlstate = false; 2210 priv->bis_cur_rdlstate = false;
2414} // dm_init_edca_turbo 2211} /* dm_init_edca_turbo */
2415 2212
2416static void dm_check_edca_turbo( 2213static void dm_check_edca_turbo(
2417 struct net_device *dev) 2214 struct net_device *dev)
2418{ 2215{
2419 struct r8192_priv *priv = ieee80211_priv(dev); 2216 struct r8192_priv *priv = ieee80211_priv(dev);
2420 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; 2217 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
2421 //PSTA_QOS pStaQos = pMgntInfo->pStaQos; 2218 /*PSTA_QOS pStaQos = pMgntInfo->pStaQos;*/
2422 2219
2423 // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. 2220 /* Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. */
2424 static unsigned long lastTxOkCnt; 2221 static unsigned long lastTxOkCnt;
2425 static unsigned long lastRxOkCnt; 2222 static unsigned long lastRxOkCnt;
2426 unsigned long curTxOkCnt = 0; 2223 unsigned long curTxOkCnt = 0;
2427 unsigned long curRxOkCnt = 0; 2224 unsigned long curRxOkCnt = 0;
2428 2225
2429 // 2226 /*
2430 // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters 2227 * Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2431 // should follow the settings from QAP. By Bruce, 2007-12-07. 2228 * should follow the settings from QAP. By Bruce, 2007-12-07.
2432 // 2229 */
2433 if(priv->ieee80211->state != IEEE80211_LINKED) 2230 if (priv->ieee80211->state != IEEE80211_LINKED)
2434 goto dm_CheckEdcaTurbo_EXIT; 2231 goto dm_CheckEdcaTurbo_EXIT;
2435 // We do not turn on EDCA turbo mode for some AP that has IOT issue 2232 /* We do not turn on EDCA turbo mode for some AP that has IOT issue */
2436 if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) 2233 if (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2437 goto dm_CheckEdcaTurbo_EXIT; 2234 goto dm_CheckEdcaTurbo_EXIT;
2438 2235
2439// printk("========>%s():bis_any_nonbepkts is %d\n",__func__,priv->bis_any_nonbepkts); 2236 /*printk("========>%s():bis_any_nonbepkts is %d\n", __func__, priv->bis_any_nonbepkts);*/
2440 // Check the status for current condition. 2237 /* Check the status for current condition. */
2441 if(!priv->ieee80211->bis_any_nonbepkts) 2238 if (!priv->ieee80211->bis_any_nonbepkts) {
2442 {
2443 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; 2239 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2444 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; 2240 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2445 // For RT-AP, we needs to turn it on when Rx>Tx 2241 /* For RT-AP, we needs to turn it on when Rx>Tx */
2446 if(curRxOkCnt > 4*curTxOkCnt) 2242 if (curRxOkCnt > 4*curTxOkCnt) {
2447 { 2243 /*printk("%s():curRxOkCnt > 4*curTxOkCnt\n");*/
2448 //printk("%s():curRxOkCnt > 4*curTxOkCnt\n"); 2244 if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2449 if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2450 {
2451 write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); 2245 write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2452 priv->bis_cur_rdlstate = true; 2246 priv->bis_cur_rdlstate = true;
2453 } 2247 }
2454 } 2248 } else {
2455 else 2249 /*printk("%s():curRxOkCnt < 4*curTxOkCnt\n");*/
2456 { 2250 if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2457
2458 //printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
2459 if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2460 {
2461 write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); 2251 write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2462 priv->bis_cur_rdlstate = false; 2252 priv->bis_cur_rdlstate = false;
2463 } 2253 }
@@ -2465,50 +2255,47 @@ static void dm_check_edca_turbo(
2465 } 2255 }
2466 2256
2467 priv->bcurrent_turbo_EDCA = true; 2257 priv->bcurrent_turbo_EDCA = true;
2468 } 2258 } else {
2469 else 2259 /*
2470 { 2260 * Turn Off EDCA turbo here.
2471 // 2261 * Restore original EDCA according to the declaration of AP.
2472 // Turn Off EDCA turbo here. 2262 */
2473 // Restore original EDCA according to the declaration of AP. 2263 if (priv->bcurrent_turbo_EDCA) {
2474 //
2475 if(priv->bcurrent_turbo_EDCA)
2476 {
2477
2478 { 2264 {
2479 u8 u1bAIFS; 2265 u8 u1bAIFS;
2480 u32 u4bAcParam; 2266 u32 u4bAcParam;
2481 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; 2267 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2482 u8 mode = priv->ieee80211->mode; 2268 u8 mode = priv->ieee80211->mode;
2483 2269
2484 // For Each time updating EDCA parameter, reset EDCA turbo mode status. 2270 /* For Each time updating EDCA parameter, reset EDCA turbo mode status. */
2485 dm_init_edca_turbo(dev); 2271 dm_init_edca_turbo(dev);
2486 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; 2272 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2487 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| 2273 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0])) << AC_PARAM_TXOP_LIMIT_OFFSET)|
2488 (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)| 2274 (((u32)(qos_parameters->cw_max[0])) << AC_PARAM_ECW_MAX_OFFSET)|
2489 (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)| 2275 (((u32)(qos_parameters->cw_min[0])) << AC_PARAM_ECW_MIN_OFFSET)|
2490 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); 2276 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2491 //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); 2277 /*write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);*/
2492 write_nic_dword(dev, EDCAPARA_BE, u4bAcParam); 2278 write_nic_dword(dev, EDCAPARA_BE, u4bAcParam);
2493 2279
2494 // Check ACM bit. 2280 /*
2495 // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. 2281 * Check ACM bit.
2282 * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2283 */
2496 { 2284 {
2497 // TODO: Modified this part and try to set acm control in only 1 IO processing!! 2285 /* TODO: Modified this part and try to set acm control in only 1 IO processing!! */
2498 2286
2499 PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]); 2287 PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
2500 u8 AcmCtrl; 2288 u8 AcmCtrl;
2289
2501 read_nic_byte(dev, AcmHwCtrl, &AcmCtrl); 2290 read_nic_byte(dev, AcmHwCtrl, &AcmCtrl);
2502 if(pAciAifsn->f.ACM) 2291
2503 { // ACM bit is 1. 2292 if (pAciAifsn->f.ACM) { /* ACM bit is 1. */
2504 AcmCtrl |= AcmHw_BeqEn; 2293 AcmCtrl |= AcmHw_BeqEn;
2505 } 2294 } else { /* ACM bit is 0. */
2506 else
2507 { // ACM bit is 0.
2508 AcmCtrl &= (~AcmHw_BeqEn); 2295 AcmCtrl &= (~AcmHw_BeqEn);
2509 } 2296 }
2510 2297
2511 RT_TRACE(COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl) ; 2298 RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
2512 write_nic_byte(dev, AcmHwCtrl, AcmCtrl); 2299 write_nic_byte(dev, AcmHwCtrl, AcmCtrl);
2513 } 2300 }
2514 } 2301 }
@@ -2516,13 +2303,12 @@ static void dm_check_edca_turbo(
2516 } 2303 }
2517 } 2304 }
2518 2305
2519
2520dm_CheckEdcaTurbo_EXIT: 2306dm_CheckEdcaTurbo_EXIT:
2521 // Set variables for next time. 2307 /* Set variables for next time. */
2522 priv->ieee80211->bis_any_nonbepkts = false; 2308 priv->ieee80211->bis_any_nonbepkts = false;
2523 lastTxOkCnt = priv->stats.txbytesunicast; 2309 lastTxOkCnt = priv->stats.txbytesunicast;
2524 lastRxOkCnt = priv->stats.rxbytesunicast; 2310 lastRxOkCnt = priv->stats.rxbytesunicast;
2525} // dm_CheckEdcaTurbo 2311} /* dm_CheckEdcaTurbo */
2526 2312
2527static void dm_init_ctstoself(struct net_device *dev) 2313static void dm_init_ctstoself(struct net_device *dev)
2528{ 2314{
@@ -2541,8 +2327,7 @@ static void dm_ctstoself(struct net_device *dev)
2541 unsigned long curTxOkCnt = 0; 2327 unsigned long curTxOkCnt = 0;
2542 unsigned long curRxOkCnt = 0; 2328 unsigned long curRxOkCnt = 0;
2543 2329
2544 if(priv->ieee80211->bCTSToSelfEnable != TRUE) 2330 if (priv->ieee80211->bCTSToSelfEnable != TRUE) {
2545 {
2546 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; 2331 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2547 return; 2332 return;
2548 } 2333 }
@@ -2552,17 +2337,13 @@ static void dm_ctstoself(struct net_device *dev)
2552 3. <50 disable, >55 enable 2337 3. <50 disable, >55 enable
2553 */ 2338 */
2554 2339
2555 if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) 2340 if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2556 {
2557 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; 2341 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2558 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; 2342 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2559 if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self 2343 if (curRxOkCnt > 4*curTxOkCnt) { /* downlink, disable CTS to self */
2560 {
2561 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; 2344 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2562 //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n"); 2345 /*DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");*/
2563 } 2346 } else { /* uplink */
2564 else //uplink
2565 {
2566 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; 2347 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2567 } 2348 }
2568 2349
@@ -2592,15 +2373,15 @@ static void dm_check_pbc_gpio(struct net_device *dev)
2592 struct r8192_priv *priv = ieee80211_priv(dev); 2373 struct r8192_priv *priv = ieee80211_priv(dev);
2593 u8 tmp1byte; 2374 u8 tmp1byte;
2594 2375
2595
2596 read_nic_byte(dev, GPI, &tmp1byte); 2376 read_nic_byte(dev, GPI, &tmp1byte);
2597 if(tmp1byte == 0xff) 2377 if (tmp1byte == 0xff)
2598 return; 2378 return;
2599 2379
2600 if (tmp1byte&BIT6 || tmp1byte&BIT0) 2380 if (tmp1byte&BIT6 || tmp1byte&BIT0) {
2601 { 2381 /*
2602 // Here we only set bPbcPressed to TRUE 2382 * Here we only set bPbcPressed to TRUE
2603 // After trigger PBC, the variable will be set to FALSE 2383 * After trigger PBC, the variable will be set to FALSE
2384 */
2604 RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n"); 2385 RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2605 priv->bpbc_pressed = true; 2386 priv->bpbc_pressed = true;
2606 } 2387 }
@@ -2625,26 +2406,24 @@ static void dm_check_pbc_gpio(struct net_device *dev)
2625 *---------------------------------------------------------------------------*/ 2406 *---------------------------------------------------------------------------*/
2626void dm_rf_pathcheck_workitemcallback(struct work_struct *work) 2407void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
2627{ 2408{
2628 struct delayed_work *dwork = container_of(work,struct delayed_work,work); 2409 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2629 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq); 2410 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, rfpath_check_wq);
2630 struct net_device *dev =priv->ieee80211->dev; 2411 struct net_device *dev = priv->ieee80211->dev;
2631 //bool bactually_set = false; 2412 /*bool bactually_set = false;*/
2632 u8 rfpath = 0, i; 2413 u8 rfpath = 0, i;
2633 2414
2634
2635 /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will 2415 /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
2636 always be the same. We only read 0xc04 now. */ 2416 always be the same. We only read 0xc04 now. */
2637 read_nic_byte(dev, 0xc04, &rfpath); 2417 read_nic_byte(dev, 0xc04, &rfpath);
2638 2418
2639 // Check Bit 0-3, it means if RF A-D is enabled. 2419 /* Check Bit 0-3, it means if RF A-D is enabled. */
2640 for (i = 0; i < RF90_PATH_MAX; i++) 2420 for (i = 0; i < RF90_PATH_MAX; i++) {
2641 {
2642 if (rfpath & (0x01<<i)) 2421 if (rfpath & (0x01<<i))
2643 priv->brfpath_rxenable[i] = 1; 2422 priv->brfpath_rxenable[i] = 1;
2644 else 2423 else
2645 priv->brfpath_rxenable[i] = 0; 2424 priv->brfpath_rxenable[i] = 0;
2646 } 2425 }
2647 if(!DM_RxPathSelTable.Enable) 2426 if (!DM_RxPathSelTable.Enable)
2648 return; 2427 return;
2649 2428
2650 dm_rxpath_sel_byrssi(dev); 2429 dm_rxpath_sel_byrssi(dev);
@@ -2654,17 +2433,17 @@ static void dm_init_rxpath_selection(struct net_device *dev)
2654{ 2433{
2655 u8 i; 2434 u8 i;
2656 struct r8192_priv *priv = ieee80211_priv(dev); 2435 struct r8192_priv *priv = ieee80211_priv(dev);
2657 DM_RxPathSelTable.Enable = 1; //default enabled 2436
2437 DM_RxPathSelTable.Enable = 1; /* default enabled */
2658 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low; 2438 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
2659 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH; 2439 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
2660 if(priv->CustomerID == RT_CID_819x_Netcore) 2440 if (priv->CustomerID == RT_CID_819x_Netcore)
2661 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; 2441 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2662 else 2442 else
2663 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1; 2443 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
2664 DM_RxPathSelTable.DbgMode = DM_DBG_OFF; 2444 DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
2665 DM_RxPathSelTable.disabledRF = 0; 2445 DM_RxPathSelTable.disabledRF = 0;
2666 for(i=0; i<4; i++) 2446 for (i = 0; i < 4; i++) {
2667 {
2668 DM_RxPathSelTable.rf_rssi[i] = 50; 2447 DM_RxPathSelTable.rf_rssi[i] = 50;
2669 DM_RxPathSelTable.cck_pwdb_sta[i] = -64; 2448 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2670 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; 2449 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
@@ -2674,22 +2453,21 @@ static void dm_init_rxpath_selection(struct net_device *dev)
2674static void dm_rxpath_sel_byrssi(struct net_device *dev) 2453static void dm_rxpath_sel_byrssi(struct net_device *dev)
2675{ 2454{
2676 struct r8192_priv *priv = ieee80211_priv(dev); 2455 struct r8192_priv *priv = ieee80211_priv(dev);
2677 u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0; 2456 u8 i, max_rssi_index = 0, min_rssi_index = 0, sec_rssi_index = 0, rf_num = 0;
2678 u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0; 2457 u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
2679 u8 cck_default_Rx=0x2; //RF-C 2458 u8 cck_default_Rx = 0x2; /* RF-C */
2680 u8 cck_optional_Rx=0x3;//RF-D 2459 u8 cck_optional_Rx = 0x3; /* RF-D */
2681 long tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0; 2460 long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
2682 u8 cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0; 2461 u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0, cck_rx_ver2_sec_index = 0;
2683 u8 cur_rf_rssi; 2462 u8 cur_rf_rssi;
2684 long cur_cck_pwdb; 2463 long cur_cck_pwdb;
2685 static u8 disabled_rf_cnt, cck_Rx_Path_initialized; 2464 static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
2686 u8 update_cck_rx_path; 2465 u8 update_cck_rx_path;
2687 2466
2688 if(priv->rf_type != RF_2T4R) 2467 if (priv->rf_type != RF_2T4R)
2689 return; 2468 return;
2690 2469
2691 if(!cck_Rx_Path_initialized) 2470 if (!cck_Rx_Path_initialized) {
2692 {
2693 read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_Rx_path); 2471 read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_Rx_path);
2694 DM_RxPathSelTable.cck_Rx_path &= 0xf; 2472 DM_RxPathSelTable.cck_Rx_path &= 0xf;
2695 cck_Rx_Path_initialized = 1; 2473 cck_Rx_Path_initialized = 1;
@@ -2698,90 +2476,63 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
2698 read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabledRF); 2476 read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabledRF);
2699 DM_RxPathSelTable.disabledRF = ~DM_RxPathSelTable.disabledRF & 0xf; 2477 DM_RxPathSelTable.disabledRF = ~DM_RxPathSelTable.disabledRF & 0xf;
2700 2478
2701 if(priv->ieee80211->mode == WIRELESS_MODE_B) 2479 if (priv->ieee80211->mode == WIRELESS_MODE_B) {
2702 { 2480 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; /* pure B mode, fixed cck version2 */
2703 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2 2481 /*DbgPrint("Pure B mode, use cck rx version2\n");*/
2704 //DbgPrint("Pure B mode, use cck rx version2 \n");
2705 } 2482 }
2706 2483
2707 //decide max/sec/min rssi index 2484 /* decide max/sec/min rssi index */
2708 for (i=0; i<RF90_PATH_MAX; i++) 2485 for (i = 0; i < RF90_PATH_MAX; i++) {
2709 { 2486 if (!DM_RxPathSelTable.DbgMode)
2710 if(!DM_RxPathSelTable.DbgMode)
2711 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i]; 2487 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2712 2488
2713 if(priv->brfpath_rxenable[i]) 2489 if (priv->brfpath_rxenable[i]) {
2714 {
2715 rf_num++; 2490 rf_num++;
2716 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i]; 2491 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2717 2492
2718 if(rf_num == 1) // find first enabled rf path and the rssi values 2493 if (rf_num == 1) { /* find first enabled rf path and the rssi values */
2719 { //initialize, set all rssi index to the same one 2494 /* initialize, set all rssi index to the same one */
2720 max_rssi_index = min_rssi_index = sec_rssi_index = i; 2495 max_rssi_index = min_rssi_index = sec_rssi_index = i;
2721 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; 2496 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
2722 } 2497 } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
2723 else if(rf_num == 2) 2498 if (cur_rf_rssi >= tmp_max_rssi) {
2724 { // we pick up the max index first, and let sec and min to be the same one
2725 if(cur_rf_rssi >= tmp_max_rssi)
2726 {
2727 tmp_max_rssi = cur_rf_rssi; 2499 tmp_max_rssi = cur_rf_rssi;
2728 max_rssi_index = i; 2500 max_rssi_index = i;
2729 } 2501 } else {
2730 else
2731 {
2732 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; 2502 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2733 sec_rssi_index = min_rssi_index = i; 2503 sec_rssi_index = min_rssi_index = i;
2734 } 2504 }
2735 } 2505 } else {
2736 else 2506 if (cur_rf_rssi > tmp_max_rssi) {
2737 {
2738 if(cur_rf_rssi > tmp_max_rssi)
2739 {
2740 tmp_sec_rssi = tmp_max_rssi; 2507 tmp_sec_rssi = tmp_max_rssi;
2741 sec_rssi_index = max_rssi_index; 2508 sec_rssi_index = max_rssi_index;
2742 tmp_max_rssi = cur_rf_rssi; 2509 tmp_max_rssi = cur_rf_rssi;
2743 max_rssi_index = i; 2510 max_rssi_index = i;
2744 } 2511 } else if (cur_rf_rssi == tmp_max_rssi) { /* let sec and min point to the different index */
2745 else if(cur_rf_rssi == tmp_max_rssi)
2746 { // let sec and min point to the different index
2747 tmp_sec_rssi = cur_rf_rssi; 2512 tmp_sec_rssi = cur_rf_rssi;
2748 sec_rssi_index = i; 2513 sec_rssi_index = i;
2749 } 2514 } else if ((cur_rf_rssi < tmp_max_rssi) && (cur_rf_rssi > tmp_sec_rssi)) {
2750 else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
2751 {
2752 tmp_sec_rssi = cur_rf_rssi; 2515 tmp_sec_rssi = cur_rf_rssi;
2753 sec_rssi_index = i; 2516 sec_rssi_index = i;
2754 } 2517 } else if (cur_rf_rssi == tmp_sec_rssi) {
2755 else if(cur_rf_rssi == tmp_sec_rssi) 2518 if (tmp_sec_rssi == tmp_min_rssi) {
2756 { 2519 /* let sec and min point to the different index */
2757 if(tmp_sec_rssi == tmp_min_rssi)
2758 { // let sec and min point to the different index
2759 tmp_sec_rssi = cur_rf_rssi; 2520 tmp_sec_rssi = cur_rf_rssi;
2760 sec_rssi_index = i; 2521 sec_rssi_index = i;
2522 } else {
2523 /* This case we don't need to set any index */
2761 } 2524 }
2762 else 2525 } else if ((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) {
2763 { 2526 /* This case we don't need to set any index */
2764 // This case we don't need to set any index 2527 } else if (cur_rf_rssi == tmp_min_rssi) {
2765 } 2528 if (tmp_sec_rssi == tmp_min_rssi) {
2766 } 2529 /* let sec and min point to the different index */
2767 else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
2768 {
2769 // This case we don't need to set any index
2770 }
2771 else if(cur_rf_rssi == tmp_min_rssi)
2772 {
2773 if(tmp_sec_rssi == tmp_min_rssi)
2774 { // let sec and min point to the different index
2775 tmp_min_rssi = cur_rf_rssi; 2530 tmp_min_rssi = cur_rf_rssi;
2776 min_rssi_index = i; 2531 min_rssi_index = i;
2532 } else {
2533 /* This case we don't need to set any index */
2777 } 2534 }
2778 else 2535 } else if (cur_rf_rssi < tmp_min_rssi) {
2779 {
2780 // This case we don't need to set any index
2781 }
2782 }
2783 else if(cur_rf_rssi < tmp_min_rssi)
2784 {
2785 tmp_min_rssi = cur_rf_rssi; 2536 tmp_min_rssi = cur_rf_rssi;
2786 min_rssi_index = i; 2537 min_rssi_index = i;
2787 } 2538 }
@@ -2790,83 +2541,51 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
2790 } 2541 }
2791 2542
2792 rf_num = 0; 2543 rf_num = 0;
2793 // decide max/sec/min cck pwdb index 2544 /* decide max/sec/min cck pwdb index */
2794 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) 2545 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2795 { 2546 for (i = 0; i < RF90_PATH_MAX; i++) {
2796 for (i=0; i<RF90_PATH_MAX; i++) 2547 if (priv->brfpath_rxenable[i]) {
2797 {
2798 if(priv->brfpath_rxenable[i])
2799 {
2800 rf_num++; 2548 rf_num++;
2801 cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i]; 2549 cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i];
2802 2550
2803 if(rf_num == 1) // find first enabled rf path and the rssi values 2551 if (rf_num == 1) { /* find first enabled rf path and the rssi values */
2804 { //initialize, set all rssi index to the same one 2552 /* initialize, set all rssi index to the same one */
2805 cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i; 2553 cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
2806 tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb; 2554 tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
2807 } 2555 } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
2808 else if(rf_num == 2) 2556 if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2809 { // we pick up the max index first, and let sec and min to be the same one
2810 if(cur_cck_pwdb >= tmp_cck_max_pwdb)
2811 {
2812 tmp_cck_max_pwdb = cur_cck_pwdb; 2557 tmp_cck_max_pwdb = cur_cck_pwdb;
2813 cck_rx_ver2_max_index = i; 2558 cck_rx_ver2_max_index = i;
2814 } 2559 } else {
2815 else
2816 {
2817 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb; 2560 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
2818 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i; 2561 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
2819 } 2562 }
2820 } 2563 } else {
2821 else 2564 if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2822 {
2823 if(cur_cck_pwdb > tmp_cck_max_pwdb)
2824 {
2825 tmp_cck_sec_pwdb = tmp_cck_max_pwdb; 2565 tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2826 cck_rx_ver2_sec_index = cck_rx_ver2_max_index; 2566 cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2827 tmp_cck_max_pwdb = cur_cck_pwdb; 2567 tmp_cck_max_pwdb = cur_cck_pwdb;
2828 cck_rx_ver2_max_index = i; 2568 cck_rx_ver2_max_index = i;
2829 } 2569 } else if (cur_cck_pwdb == tmp_cck_max_pwdb) {
2830 else if(cur_cck_pwdb == tmp_cck_max_pwdb) 2570 /* let sec and min point to the different index */
2831 { // let sec and min point to the different index
2832 tmp_cck_sec_pwdb = cur_cck_pwdb; 2571 tmp_cck_sec_pwdb = cur_cck_pwdb;
2833 cck_rx_ver2_sec_index = i; 2572 cck_rx_ver2_sec_index = i;
2834 } 2573 } else if ((cur_cck_pwdb < tmp_cck_max_pwdb) && (cur_cck_pwdb > tmp_cck_sec_pwdb)) {
2835 else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
2836 {
2837 tmp_cck_sec_pwdb = cur_cck_pwdb; 2574 tmp_cck_sec_pwdb = cur_cck_pwdb;
2838 cck_rx_ver2_sec_index = i; 2575 cck_rx_ver2_sec_index = i;
2839 } 2576 } else if (cur_cck_pwdb == tmp_cck_sec_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2840 else if(cur_cck_pwdb == tmp_cck_sec_pwdb) 2577 /* let sec and min point to the different index */
2841 { 2578 tmp_cck_sec_pwdb = cur_cck_pwdb;
2842 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb) 2579 cck_rx_ver2_sec_index = i;
2843 { // let sec and min point to the different index 2580 /* otherwise we don't need to set any index */
2844 tmp_cck_sec_pwdb = cur_cck_pwdb; 2581 } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2845 cck_rx_ver2_sec_index = i; 2582 /* This case we don't need to set any index */
2846 } 2583 } else if (cur_cck_pwdb == tmp_cck_min_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2847 else 2584 /* let sec and min point to the different index */
2848 { 2585 tmp_cck_min_pwdb = cur_cck_pwdb;
2849 // This case we don't need to set any index 2586 cck_rx_ver2_min_index = i;
2850 } 2587 /* otherwise we don't need to set any index */
2851 } 2588 } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2852 else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
2853 {
2854 // This case we don't need to set any index
2855 }
2856 else if(cur_cck_pwdb == tmp_cck_min_pwdb)
2857 {
2858 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2859 { // let sec and min point to the different index
2860 tmp_cck_min_pwdb = cur_cck_pwdb;
2861 cck_rx_ver2_min_index = i;
2862 }
2863 else
2864 {
2865 // This case we don't need to set any index
2866 }
2867 }
2868 else if(cur_cck_pwdb < tmp_cck_min_pwdb)
2869 {
2870 tmp_cck_min_pwdb = cur_cck_pwdb; 2589 tmp_cck_min_pwdb = cur_cck_pwdb;
2871 cck_rx_ver2_min_index = i; 2590 cck_rx_ver2_min_index = i;
2872 } 2591 }
@@ -2876,56 +2595,48 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
2876 } 2595 }
2877 } 2596 }
2878 2597
2879 2598 /*
2880 // Set CCK Rx path 2599 * Set CCK Rx path
2881 // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path. 2600 * reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2601 */
2882 update_cck_rx_path = 0; 2602 update_cck_rx_path = 0;
2883 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) 2603 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2884 {
2885 cck_default_Rx = cck_rx_ver2_max_index; 2604 cck_default_Rx = cck_rx_ver2_max_index;
2886 cck_optional_Rx = cck_rx_ver2_sec_index; 2605 cck_optional_Rx = cck_rx_ver2_sec_index;
2887 if(tmp_cck_max_pwdb != -64) 2606 if (tmp_cck_max_pwdb != -64)
2888 update_cck_rx_path = 1; 2607 update_cck_rx_path = 1;
2889 } 2608 }
2890 2609
2891 if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) 2610 if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2892 { 2611 if ((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH) {
2893 if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH) 2612 /* record the enabled rssi threshold */
2894 {
2895 //record the enabled rssi threshold
2896 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5; 2613 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
2897 //disable the BB Rx path, OFDM 2614 /* disable the BB Rx path, OFDM */
2898 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xc04[3:0] 2615 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); /* 0xc04[3:0] */
2899 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xd04[3:0] 2616 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); /* 0xd04[3:0] */
2900 disabled_rf_cnt++; 2617 disabled_rf_cnt++;
2901 } 2618 }
2902 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) 2619 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2903 {
2904 cck_default_Rx = max_rssi_index; 2620 cck_default_Rx = max_rssi_index;
2905 cck_optional_Rx = sec_rssi_index; 2621 cck_optional_Rx = sec_rssi_index;
2906 if(tmp_max_rssi) 2622 if (tmp_max_rssi)
2907 update_cck_rx_path = 1; 2623 update_cck_rx_path = 1;
2908 } 2624 }
2909 } 2625 }
2910 2626
2911 if(update_cck_rx_path) 2627 if (update_cck_rx_path) {
2912 {
2913 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx); 2628 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2914 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path); 2629 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
2915 } 2630 }
2916 2631
2917 if(DM_RxPathSelTable.disabledRF) 2632 if (DM_RxPathSelTable.disabledRF) {
2918 { 2633 for (i = 0; i < 4; i++) {
2919 for(i=0; i<4; i++) 2634 if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) { /* disabled rf */
2920 { 2635 if (tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2921 if((DM_RxPathSelTable.disabledRF>>i) & 0x1) //disabled rf 2636 /* enable the BB Rx path */
2922 { 2637 /*DbgPrint("RF-%d is enabled.\n", 0x1<<i);*/
2923 if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) 2638 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); /* 0xc04[3:0] */
2924 { 2639 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); /* 0xd04[3:0] */
2925 //enable the BB Rx path
2926 //DbgPrint("RF-%d is enabled. \n", 0x1<<i);
2927 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); // 0xc04[3:0]
2928 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); // 0xd04[3:0]
2929 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; 2640 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2930 disabled_rf_cnt--; 2641 disabled_rf_cnt--;
2931 } 2642 }
@@ -2950,14 +2661,14 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
2950 * 05/28/2008 amy Create Version 0 porting from windows code. 2661 * 05/28/2008 amy Create Version 0 porting from windows code.
2951 * 2662 *
2952 *---------------------------------------------------------------------------*/ 2663 *---------------------------------------------------------------------------*/
2953static void dm_check_rx_path_selection(struct net_device *dev) 2664static void dm_check_rx_path_selection(struct net_device *dev)
2954{ 2665{
2955 struct r8192_priv *priv = ieee80211_priv(dev); 2666 struct r8192_priv *priv = ieee80211_priv(dev);
2956 queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
2957} /* dm_CheckRxRFPath */
2958 2667
2668 queue_delayed_work(priv->priv_wq, &priv->rfpath_check_wq, 0);
2669} /* dm_CheckRxRFPath */
2959 2670
2960static void dm_init_fsync (struct net_device *dev) 2671static void dm_init_fsync(struct net_device *dev)
2961{ 2672{
2962 struct r8192_priv *priv = ieee80211_priv(dev); 2673 struct r8192_priv *priv = ieee80211_priv(dev);
2963 2674
@@ -2966,20 +2677,20 @@ static void dm_init_fsync (struct net_device *dev)
2966 priv->ieee80211->fsync_rssi_threshold = 30; 2677 priv->ieee80211->fsync_rssi_threshold = 30;
2967 priv->ieee80211->bfsync_enable = false; 2678 priv->ieee80211->bfsync_enable = false;
2968 priv->ieee80211->fsync_multiple_timeinterval = 3; 2679 priv->ieee80211->fsync_multiple_timeinterval = 3;
2969 priv->ieee80211->fsync_firstdiff_ratethreshold= 100; 2680 priv->ieee80211->fsync_firstdiff_ratethreshold = 100;
2970 priv->ieee80211->fsync_seconddiff_ratethreshold= 200; 2681 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2971 priv->ieee80211->fsync_state = Default_Fsync; 2682 priv->ieee80211->fsync_state = Default_Fsync;
2972 priv->framesyncMonitor = 1; // current default 0xc38 monitor on 2683 priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */
2973 2684
2974 init_timer(&priv->fsync_timer); 2685 init_timer(&priv->fsync_timer);
2975 priv->fsync_timer.data = (unsigned long)dev; 2686 priv->fsync_timer.data = (unsigned long)dev;
2976 priv->fsync_timer.function = dm_fsync_timer_callback; 2687 priv->fsync_timer.function = dm_fsync_timer_callback;
2977} 2688}
2978 2689
2979
2980static void dm_deInit_fsync(struct net_device *dev) 2690static void dm_deInit_fsync(struct net_device *dev)
2981{ 2691{
2982 struct r8192_priv *priv = ieee80211_priv(dev); 2692 struct r8192_priv *priv = ieee80211_priv(dev);
2693
2983 del_timer_sync(&priv->fsync_timer); 2694 del_timer_sync(&priv->fsync_timer);
2984} 2695}
2985 2696
@@ -2987,102 +2698,84 @@ void dm_fsync_timer_callback(unsigned long data)
2987{ 2698{
2988 struct net_device *dev = (struct net_device *)data; 2699 struct net_device *dev = (struct net_device *)data;
2989 struct r8192_priv *priv = ieee80211_priv((struct net_device *)data); 2700 struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
2990 u32 rate_index, rate_count = 0, rate_count_diff=0; 2701 u32 rate_index, rate_count = 0, rate_count_diff = 0;
2991 bool bSwitchFromCountDiff = false; 2702 bool bSwitchFromCountDiff = false;
2992 bool bDoubleTimeInterval = false; 2703 bool bDoubleTimeInterval = false;
2993 2704
2994 if(priv->ieee80211->state == IEEE80211_LINKED && 2705 if (priv->ieee80211->state == IEEE80211_LINKED &&
2995 priv->ieee80211->bfsync_enable && 2706 priv->ieee80211->bfsync_enable &&
2996 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) 2707 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2997 { 2708 /* Count rate 54, MCS [7], [12, 13, 14, 15] */
2998 // Count rate 54, MCS [7], [12, 13, 14, 15]
2999 u32 rate_bitmap; 2709 u32 rate_bitmap;
3000 for(rate_index = 0; rate_index <= 27; rate_index++) 2710
3001 { 2711 for (rate_index = 0; rate_index <= 27; rate_index++) {
3002 rate_bitmap = 1 << rate_index; 2712 rate_bitmap = 1 << rate_index;
3003 if(priv->ieee80211->fsync_rate_bitmap & rate_bitmap) 2713 if (priv->ieee80211->fsync_rate_bitmap & rate_bitmap)
3004 rate_count+= priv->stats.received_rate_histogram[1][rate_index]; 2714 rate_count += priv->stats.received_rate_histogram[1][rate_index];
3005 } 2715 }
3006 2716
3007 if(rate_count < priv->rate_record) 2717 if (rate_count < priv->rate_record)
3008 rate_count_diff = 0xffffffff - rate_count + priv->rate_record; 2718 rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
3009 else 2719 else
3010 rate_count_diff = rate_count - priv->rate_record; 2720 rate_count_diff = rate_count - priv->rate_record;
3011 if(rate_count_diff < priv->rateCountDiffRecord) 2721 if (rate_count_diff < priv->rateCountDiffRecord) {
3012 {
3013
3014 u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; 2722 u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
3015 // Continue count 2723 /* Continue count */
3016 if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) 2724 if (DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
3017 priv->ContinueDiffCount++; 2725 priv->ContinueDiffCount++;
3018 else 2726 else
3019 priv->ContinueDiffCount = 0; 2727 priv->ContinueDiffCount = 0;
3020 2728
3021 // Continue count over 2729 /* Continue count over */
3022 if(priv->ContinueDiffCount >=2) 2730 if (priv->ContinueDiffCount >= 2) {
3023 {
3024 bSwitchFromCountDiff = true; 2731 bSwitchFromCountDiff = true;
3025 priv->ContinueDiffCount = 0; 2732 priv->ContinueDiffCount = 0;
3026 } 2733 }
3027 } 2734 } else {
3028 else 2735 /* Stop the continued count */
3029 {
3030 // Stop the continued count
3031 priv->ContinueDiffCount = 0; 2736 priv->ContinueDiffCount = 0;
3032 } 2737 }
3033 2738
3034 //If Count diff <= FsyncRateCountThreshold 2739 /* If Count diff <= FsyncRateCountThreshold */
3035 if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) 2740 if (rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) {
3036 {
3037 bSwitchFromCountDiff = true; 2741 bSwitchFromCountDiff = true;
3038 priv->ContinueDiffCount = 0; 2742 priv->ContinueDiffCount = 0;
3039 } 2743 }
3040 priv->rate_record = rate_count; 2744 priv->rate_record = rate_count;
3041 priv->rateCountDiffRecord = rate_count_diff; 2745 priv->rateCountDiffRecord = rate_count_diff;
3042 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); 2746 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
3043 // if we never receive those mcs rate and rssi > 30 % then switch fsyn 2747 /* if we never receive those mcs rate and rssi > 30 % then switch fsyn */
3044 if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) 2748 if (priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) {
3045 {
3046 bDoubleTimeInterval = true; 2749 bDoubleTimeInterval = true;
3047 priv->bswitch_fsync = !priv->bswitch_fsync; 2750 priv->bswitch_fsync = !priv->bswitch_fsync;
3048 if(priv->bswitch_fsync) 2751 if (priv->bswitch_fsync) {
3049 {
3050 write_nic_byte(dev, 0xC36, 0x1c); 2752 write_nic_byte(dev, 0xC36, 0x1c);
3051 write_nic_byte(dev, 0xC3e, 0x90); 2753 write_nic_byte(dev, 0xC3e, 0x90);
3052 } 2754 } else {
3053 else
3054 {
3055 write_nic_byte(dev, 0xC36, 0x5c); 2755 write_nic_byte(dev, 0xC36, 0x5c);
3056 write_nic_byte(dev, 0xC3e, 0x96); 2756 write_nic_byte(dev, 0xC3e, 0x96);
3057 } 2757 }
3058 } 2758 } else if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) {
3059 else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) 2759 if (priv->bswitch_fsync) {
3060 {
3061 if(priv->bswitch_fsync)
3062 {
3063 priv->bswitch_fsync = false; 2760 priv->bswitch_fsync = false;
3064 write_nic_byte(dev, 0xC36, 0x5c); 2761 write_nic_byte(dev, 0xC36, 0x5c);
3065 write_nic_byte(dev, 0xC3e, 0x96); 2762 write_nic_byte(dev, 0xC3e, 0x96);
3066 } 2763 }
3067 } 2764 }
3068 if(bDoubleTimeInterval){ 2765 if (bDoubleTimeInterval) {
3069 if(timer_pending(&priv->fsync_timer)) 2766 if (timer_pending(&priv->fsync_timer))
3070 del_timer_sync(&priv->fsync_timer); 2767 del_timer_sync(&priv->fsync_timer);
3071 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval); 2768 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
3072 add_timer(&priv->fsync_timer); 2769 add_timer(&priv->fsync_timer);
3073 } 2770 } else {
3074 else{ 2771 if (timer_pending(&priv->fsync_timer))
3075 if(timer_pending(&priv->fsync_timer))
3076 del_timer_sync(&priv->fsync_timer); 2772 del_timer_sync(&priv->fsync_timer);
3077 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); 2773 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3078 add_timer(&priv->fsync_timer); 2774 add_timer(&priv->fsync_timer);
3079 } 2775 }
3080 } 2776 } else {
3081 else 2777 /* Let Register return to default value; */
3082 { 2778 if (priv->bswitch_fsync) {
3083 // Let Register return to default value;
3084 if(priv->bswitch_fsync)
3085 {
3086 priv->bswitch_fsync = false; 2779 priv->bswitch_fsync = false;
3087 write_nic_byte(dev, 0xC36, 0x5c); 2780 write_nic_byte(dev, 0xC36, 0x5c);
3088 write_nic_byte(dev, 0xC3e, 0x96); 2781 write_nic_byte(dev, 0xC3e, 0x96);
@@ -3091,7 +2784,7 @@ void dm_fsync_timer_callback(unsigned long data)
3091 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); 2784 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3092 } 2785 }
3093 RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); 2786 RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
3094 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); 2787 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
3095} 2788}
3096 2789
3097static void dm_StartHWFsync(struct net_device *dev) 2790static void dm_StartHWFsync(struct net_device *dev)
@@ -3108,9 +2801,8 @@ static void dm_EndSWFsync(struct net_device *dev)
3108 RT_TRACE(COMP_HALDM, "%s\n", __func__); 2801 RT_TRACE(COMP_HALDM, "%s\n", __func__);
3109 del_timer_sync(&(priv->fsync_timer)); 2802 del_timer_sync(&(priv->fsync_timer));
3110 2803
3111 // Let Register return to default value; 2804 /* Let Register return to default value; */
3112 if(priv->bswitch_fsync) 2805 if (priv->bswitch_fsync) {
3113 {
3114 priv->bswitch_fsync = false; 2806 priv->bswitch_fsync = false;
3115 2807
3116 write_nic_byte(dev, 0xC36, 0x5c); 2808 write_nic_byte(dev, 0xC36, 0x5c);
@@ -3130,30 +2822,26 @@ static void dm_StartSWFsync(struct net_device *dev)
3130 u32 rateBitmap; 2822 u32 rateBitmap;
3131 2823
3132 RT_TRACE(COMP_HALDM, "%s\n", __func__); 2824 RT_TRACE(COMP_HALDM, "%s\n", __func__);
3133 // Initial rate record to zero, start to record. 2825 /* Initial rate record to zero, start to record. */
3134 priv->rate_record = 0; 2826 priv->rate_record = 0;
3135 // Initialize continue diff count to zero, start to record. 2827 /* Initialize continue diff count to zero, start to record. */
3136 priv->ContinueDiffCount = 0; 2828 priv->ContinueDiffCount = 0;
3137 priv->rateCountDiffRecord = 0; 2829 priv->rateCountDiffRecord = 0;
3138 priv->bswitch_fsync = false; 2830 priv->bswitch_fsync = false;
3139 2831
3140 if(priv->ieee80211->mode == WIRELESS_MODE_N_24G) 2832 if (priv->ieee80211->mode == WIRELESS_MODE_N_24G) {
3141 { 2833 priv->ieee80211->fsync_firstdiff_ratethreshold = 600;
3142 priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
3143 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff; 2834 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
3144 } 2835 } else {
3145 else 2836 priv->ieee80211->fsync_firstdiff_ratethreshold = 200;
3146 {
3147 priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
3148 priv->ieee80211->fsync_seconddiff_ratethreshold = 200; 2837 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
3149 } 2838 }
3150 for(rateIndex = 0; rateIndex <= 27; rateIndex++) 2839 for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
3151 { 2840 rateBitmap = 1 << rateIndex;
3152 rateBitmap = 1 << rateIndex; 2841 if (priv->ieee80211->fsync_rate_bitmap & rateBitmap)
3153 if(priv->ieee80211->fsync_rate_bitmap & rateBitmap)
3154 priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex]; 2842 priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
3155 } 2843 }
3156 if(timer_pending(&priv->fsync_timer)) 2844 if (timer_pending(&priv->fsync_timer))
3157 del_timer_sync(&priv->fsync_timer); 2845 del_timer_sync(&priv->fsync_timer);
3158 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); 2846 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3159 add_timer(&priv->fsync_timer); 2847 add_timer(&priv->fsync_timer);
@@ -3173,139 +2861,112 @@ static void dm_EndHWFsync(struct net_device *dev)
3173void dm_check_fsync(struct net_device *dev) 2861void dm_check_fsync(struct net_device *dev)
3174{ 2862{
3175#define RegC38_Default 0 2863#define RegC38_Default 0
3176#define RegC38_NonFsync_Other_AP 1 2864#define RegC38_NonFsync_Other_AP 1
3177#define RegC38_Fsync_AP_BCM 2 2865#define RegC38_Fsync_AP_BCM 2
3178 struct r8192_priv *priv = ieee80211_priv(dev); 2866 struct r8192_priv *priv = ieee80211_priv(dev);
3179 //u32 framesyncC34; 2867 /*u32 framesyncC34;*/
3180 static u8 reg_c38_State=RegC38_Default; 2868 static u8 reg_c38_State = RegC38_Default;
3181 static u32 reset_cnt; 2869 static u32 reset_cnt;
3182 2870
3183 RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval); 2871 RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
3184 RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold); 2872 RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
3185 2873
3186 if(priv->ieee80211->state == IEEE80211_LINKED && 2874 if (priv->ieee80211->state == IEEE80211_LINKED &&
3187 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) 2875 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
3188 { 2876 if (priv->ieee80211->bfsync_enable == 0) {
3189 if(priv->ieee80211->bfsync_enable == 0) 2877 switch (priv->ieee80211->fsync_state) {
3190 { 2878 case Default_Fsync:
3191 switch (priv->ieee80211->fsync_state) 2879 dm_StartHWFsync(dev);
3192 { 2880 priv->ieee80211->fsync_state = HW_Fsync;
3193 case Default_Fsync: 2881 break;
3194 dm_StartHWFsync(dev); 2882 case SW_Fsync:
3195 priv->ieee80211->fsync_state = HW_Fsync; 2883 dm_EndSWFsync(dev);
3196 break; 2884 dm_StartHWFsync(dev);
3197 case SW_Fsync: 2885 priv->ieee80211->fsync_state = HW_Fsync;
3198 dm_EndSWFsync(dev); 2886 break;
3199 dm_StartHWFsync(dev); 2887 case HW_Fsync:
3200 priv->ieee80211->fsync_state = HW_Fsync; 2888 default:
3201 break; 2889 break;
3202 case HW_Fsync:
3203 default:
3204 break;
3205 } 2890 }
3206 } 2891 } else {
3207 else 2892 switch (priv->ieee80211->fsync_state) {
3208 { 2893 case Default_Fsync:
3209 switch (priv->ieee80211->fsync_state) 2894 dm_StartSWFsync(dev);
3210 { 2895 priv->ieee80211->fsync_state = SW_Fsync;
3211 case Default_Fsync: 2896 break;
3212 dm_StartSWFsync(dev); 2897 case HW_Fsync:
3213 priv->ieee80211->fsync_state = SW_Fsync; 2898 dm_EndHWFsync(dev);
3214 break; 2899 dm_StartSWFsync(dev);
3215 case HW_Fsync: 2900 priv->ieee80211->fsync_state = SW_Fsync;
3216 dm_EndHWFsync(dev); 2901 break;
3217 dm_StartSWFsync(dev); 2902 case SW_Fsync:
3218 priv->ieee80211->fsync_state = SW_Fsync; 2903 default:
3219 break; 2904 break;
3220 case SW_Fsync:
3221 default:
3222 break;
3223
3224 } 2905 }
3225 } 2906 }
3226 if(priv->framesyncMonitor) 2907 if (priv->framesyncMonitor) {
3227 { 2908 if (reg_c38_State != RegC38_Fsync_AP_BCM) {
3228 if(reg_c38_State != RegC38_Fsync_AP_BCM) 2909 /* For broadcom AP we write different default value */
3229 { //For broadcom AP we write different default value
3230 write_nic_byte(dev, rOFDM0_RxDetector3, 0x95); 2910 write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
3231 2911
3232 reg_c38_State = RegC38_Fsync_AP_BCM; 2912 reg_c38_State = RegC38_Fsync_AP_BCM;
3233 } 2913 }
3234 } 2914 }
3235 } 2915 } else {
3236 else 2916 switch (priv->ieee80211->fsync_state) {
3237 { 2917 case HW_Fsync:
3238 switch (priv->ieee80211->fsync_state) 2918 dm_EndHWFsync(dev);
3239 { 2919 priv->ieee80211->fsync_state = Default_Fsync;
3240 case HW_Fsync: 2920 break;
3241 dm_EndHWFsync(dev); 2921 case SW_Fsync:
3242 priv->ieee80211->fsync_state = Default_Fsync; 2922 dm_EndSWFsync(dev);
3243 break; 2923 priv->ieee80211->fsync_state = Default_Fsync;
3244 case SW_Fsync: 2924 break;
3245 dm_EndSWFsync(dev); 2925 case Default_Fsync:
3246 priv->ieee80211->fsync_state = Default_Fsync; 2926 default:
3247 break; 2927 break;
3248 case Default_Fsync:
3249 default:
3250 break;
3251 } 2928 }
3252 2929
3253 if(priv->framesyncMonitor) 2930 if (priv->framesyncMonitor) {
3254 { 2931 if (priv->ieee80211->state == IEEE80211_LINKED) {
3255 if(priv->ieee80211->state == IEEE80211_LINKED) 2932 if (priv->undecorated_smoothed_pwdb <= RegC38_TH) {
3256 { 2933 if (reg_c38_State != RegC38_NonFsync_Other_AP) {
3257 if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
3258 {
3259 if(reg_c38_State != RegC38_NonFsync_Other_AP)
3260 {
3261 write_nic_byte(dev, rOFDM0_RxDetector3, 0x90); 2934 write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
3262 2935
3263 reg_c38_State = RegC38_NonFsync_Other_AP; 2936 reg_c38_State = RegC38_NonFsync_Other_AP;
3264 } 2937 }
3265 } 2938 } else if (priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) {
3266 else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) 2939 if (reg_c38_State) {
3267 {
3268 if(reg_c38_State)
3269 {
3270 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); 2940 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3271 reg_c38_State = RegC38_Default; 2941 reg_c38_State = RegC38_Default;
3272 //DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync); 2942 /*DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x\n", pHalData->framesync);*/
3273 } 2943 }
3274 } 2944 }
3275 } 2945 } else {
3276 else 2946 if (reg_c38_State) {
3277 {
3278 if(reg_c38_State)
3279 {
3280 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); 2947 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3281 reg_c38_State = RegC38_Default; 2948 reg_c38_State = RegC38_Default;
3282 //DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync); 2949 /*DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x\n", pHalData->framesync);*/
3283 } 2950 }
3284 } 2951 }
3285 } 2952 }
3286 } 2953 }
3287 if(priv->framesyncMonitor) 2954 if (priv->framesyncMonitor) {
3288 { 2955 if (priv->reset_count != reset_cnt) { /* After silent reset, the reg_c38_State will be returned to default value */
3289 if(priv->reset_count != reset_cnt)
3290 { //After silent reset, the reg_c38_State will be returned to default value
3291 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); 2956 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3292 reg_c38_State = RegC38_Default; 2957 reg_c38_State = RegC38_Default;
3293 reset_cnt = priv->reset_count; 2958 reset_cnt = priv->reset_count;
3294 //DbgPrint("reg_c38_State = 0 for silent reset. \n"); 2959 /*DbgPrint("reg_c38_State = 0 for silent reset.\n");*/
3295 } 2960 }
3296 } 2961 } else {
3297 else 2962 if (reg_c38_State) {
3298 {
3299 if(reg_c38_State)
3300 {
3301 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); 2963 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3302 reg_c38_State = RegC38_Default; 2964 reg_c38_State = RegC38_Default;
3303 //DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync); 2965 /*DbgPrint("framesync no monitor, write 0xc38 = 0x%x\n", pHalData->framesync);*/
3304 } 2966 }
3305 } 2967 }
3306} 2968}
3307 2969
3308
3309/*----------------------------------------------------------------------------- 2970/*-----------------------------------------------------------------------------
3310 * Function: dm_shadow_init() 2971 * Function: dm_shadow_init()
3311 * 2972 *
@@ -3328,10 +2989,9 @@ void dm_shadow_init(struct net_device *dev)
3328 u16 offset; 2989 u16 offset;
3329 2990
3330 for (page = 0; page < 5; page++) 2991 for (page = 0; page < 5; page++)
3331 for (offset = 0; offset < 256; offset++) 2992 for (offset = 0; offset < 256; offset++) {
3332 {
3333 read_nic_byte(dev, offset+page*256, &dm_shadow[page][offset]); 2993 read_nic_byte(dev, offset+page*256, &dm_shadow[page][offset]);
3334 //DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]); 2994 /*DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);*/
3335 } 2995 }
3336 2996
3337 for (page = 8; page < 11; page++) 2997 for (page = 8; page < 11; page++)
@@ -3366,8 +3026,8 @@ static void dm_init_dynamic_txpower(struct net_device *dev)
3366{ 3026{
3367 struct r8192_priv *priv = ieee80211_priv(dev); 3027 struct r8192_priv *priv = ieee80211_priv(dev);
3368 3028
3369 //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. 3029 /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
3370 priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control 3030 priv->ieee80211->bdynamic_txpower_enable = true; /* Default to enable Tx Power Control */
3371 priv->bLastDTPFlag_High = false; 3031 priv->bLastDTPFlag_High = false;
3372 priv->bLastDTPFlag_Low = false; 3032 priv->bLastDTPFlag_Low = false;
3373 priv->bDynamicTxHighPower = false; 3033 priv->bDynamicTxHighPower = false;
@@ -3377,91 +3037,77 @@ static void dm_init_dynamic_txpower(struct net_device *dev)
3377static void dm_dynamic_txpower(struct net_device *dev) 3037static void dm_dynamic_txpower(struct net_device *dev)
3378{ 3038{
3379 struct r8192_priv *priv = ieee80211_priv(dev); 3039 struct r8192_priv *priv = ieee80211_priv(dev);
3380 unsigned int txhipower_threshhold=0; 3040 unsigned int txhipower_threshhold = 0;
3381 unsigned int txlowpower_threshold=0; 3041 unsigned int txlowpower_threshold = 0;
3382 if(priv->ieee80211->bdynamic_txpower_enable != true) 3042
3383 { 3043 if (priv->ieee80211->bdynamic_txpower_enable != true) {
3384 priv->bDynamicTxHighPower = false; 3044 priv->bDynamicTxHighPower = false;
3385 priv->bDynamicTxLowPower = false; 3045 priv->bDynamicTxLowPower = false;
3386 return; 3046 return;
3387 } 3047 }
3388 //printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist); 3048 /*printk("priv->ieee80211->current_network.unknown_cap_exist is %d , priv->ieee80211->current_network.broadcom_cap_exist is %d\n", priv->ieee80211->current_network.unknown_cap_exist, priv->ieee80211->current_network.broadcom_cap_exist);*/
3389 if((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)){ 3049 if ((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)) {
3390 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH; 3050 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
3391 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; 3051 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
3392 } 3052 } else {
3393 else
3394 {
3395 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH; 3053 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
3396 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; 3054 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
3397 } 3055 }
3398 3056
3399// printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__func__,txhipower_threshhold,txlowpower_threshold); 3057 /*printk("=======>%s(): txhipower_threshhold is %d, txlowpower_threshold is %d\n", __func__, txhipower_threshhold, txlowpower_threshold);*/
3400 RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb); 3058 RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", priv->undecorated_smoothed_pwdb);
3401 3059
3402 if(priv->ieee80211->state == IEEE80211_LINKED) 3060 if (priv->ieee80211->state == IEEE80211_LINKED) {
3403 { 3061 if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
3404 if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
3405 {
3406 priv->bDynamicTxHighPower = true; 3062 priv->bDynamicTxHighPower = true;
3407 priv->bDynamicTxLowPower = false; 3063 priv->bDynamicTxLowPower = false;
3408 } 3064 } else {
3409 else 3065 /* high power state check */
3410 { 3066 if (priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
3411 // high power state check
3412 if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
3413 {
3414 priv->bDynamicTxHighPower = false; 3067 priv->bDynamicTxHighPower = false;
3415 } 3068
3416 // low power state check 3069 /* low power state check */
3417 if(priv->undecorated_smoothed_pwdb < 35) 3070 if (priv->undecorated_smoothed_pwdb < 35)
3418 {
3419 priv->bDynamicTxLowPower = true; 3071 priv->bDynamicTxLowPower = true;
3420 } 3072 else if (priv->undecorated_smoothed_pwdb >= 40)
3421 else if(priv->undecorated_smoothed_pwdb >= 40)
3422 {
3423 priv->bDynamicTxLowPower = false; 3073 priv->bDynamicTxLowPower = false;
3424 }
3425 } 3074 }
3426 } 3075 } else {
3427 else 3076 /*pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;*/
3428 {
3429 //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
3430 priv->bDynamicTxHighPower = false; 3077 priv->bDynamicTxHighPower = false;
3431 priv->bDynamicTxLowPower = false; 3078 priv->bDynamicTxLowPower = false;
3432 } 3079 }
3433 3080
3434 if((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) || 3081 if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
3435 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) 3082 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
3436 { 3083 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel);
3437 RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190() channel = %d \n" , priv->ieee80211->current_network.channel);
3438 3084
3439#if defined(RTL8190P) || defined(RTL8192E) 3085#if defined(RTL8190P) || defined(RTL8192E)
3440 SetTxPowerLevel8190(Adapter,pHalData->CurrentChannel); 3086 SetTxPowerLevel8190(Adapter, pHalData->CurrentChannel);
3441#endif 3087#endif
3442 3088
3443 rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel); 3089 rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
3444 //pHalData->bStartTxCtrlByTPCNFR = FALSE; //Clear th flag of Set TX Power from Sitesurvey 3090 /*pHalData->bStartTxCtrlByTPCNFR = FALSE; Clear th flag of Set TX Power from Sitesurvey*/
3445 } 3091 }
3446 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; 3092 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
3447 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower; 3093 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
3448 3094
3449} /* dm_dynamic_txpower */ 3095} /* dm_dynamic_txpower */
3450 3096
3451//added by vivi, for read tx rate and retrycount 3097/* added by vivi, for read tx rate and retrycount */
3452static void dm_check_txrateandretrycount(struct net_device *dev) 3098static void dm_check_txrateandretrycount(struct net_device *dev)
3453{ 3099{
3454 struct r8192_priv *priv = ieee80211_priv(dev); 3100 struct r8192_priv *priv = ieee80211_priv(dev);
3455 struct ieee80211_device *ieee = priv->ieee80211; 3101 struct ieee80211_device *ieee = priv->ieee80211;
3456 //for 11n tx rate 3102 /* for 11n tx rate */
3457// priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg); 3103 /*priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);*/
3458 read_nic_byte(dev, Current_Tx_Rate_Reg, &ieee->softmac_stats.CurrentShowTxate); 3104 read_nic_byte(dev, Current_Tx_Rate_Reg, &ieee->softmac_stats.CurrentShowTxate);
3459 //printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate); 3105 /*printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);*/
3460 //for initial tx rate 3106 /* for initial tx rate */
3461// priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg); 3107 /*priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);*/
3462 read_nic_byte(dev, Initial_Tx_Rate_Reg, &ieee->softmac_stats.last_packet_rate); 3108 read_nic_byte(dev, Initial_Tx_Rate_Reg, &ieee->softmac_stats.last_packet_rate);
3463 //for tx tx retry count 3109 /* for tx tx retry count */
3464// priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg); 3110 /*priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);*/
3465 read_nic_dword(dev, Tx_Retry_Count_Reg, &ieee->softmac_stats.txretrycount); 3111 read_nic_dword(dev, Tx_Retry_Count_Reg, &ieee->softmac_stats.txretrycount);
3466} 3112}
3467 3113
@@ -3469,11 +3115,12 @@ static void dm_send_rssi_tofw(struct net_device *dev)
3469{ 3115{
3470 struct r8192_priv *priv = ieee80211_priv(dev); 3116 struct r8192_priv *priv = ieee80211_priv(dev);
3471 3117
3472 // If we test chariot, we should stop the TX command ? 3118 /*
3473 // Because 92E will always silent reset when we send tx command. We use register 3119 * If we test chariot, we should stop the TX command ?
3474 // 0x1e0(byte) to notify driver. 3120 * Because 92E will always silent reset when we send tx command. We use register
3121 * 0x1e0(byte) to notify driver.
3122 */
3475 write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); 3123 write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
3476 return;
3477} 3124}
3478 3125
3479/*---------------------------Define function prototype------------------------*/ 3126/*---------------------------Define function prototype------------------------*/
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
index 3d0a98b6d8e5..e62543d22b86 100644
--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -129,8 +129,8 @@ struct dvobj_priv {
129 struct _adapter *padapter; 129 struct _adapter *padapter;
130 u32 nr_endpoint; 130 u32 nr_endpoint;
131 u8 ishighspeed; 131 u8 ishighspeed;
132 uint(*inirp_init)(struct _adapter *adapter); 132 uint (*inirp_init)(struct _adapter *adapter);
133 uint(*inirp_deinit)(struct _adapter *adapter); 133 uint (*inirp_deinit)(struct _adapter *adapter);
134 struct usb_device *pusbdev; 134 struct usb_device *pusbdev;
135}; 135};
136 136
@@ -166,7 +166,7 @@ struct _adapter {
166 pid_t evtThread; 166 pid_t evtThread;
167 struct task_struct *xmitThread; 167 struct task_struct *xmitThread;
168 pid_t recvThread; 168 pid_t recvThread;
169 uint(*dvobj_init)(struct _adapter *adapter); 169 uint (*dvobj_init)(struct _adapter *adapter);
170 void (*dvobj_deinit)(struct _adapter *adapter); 170 void (*dvobj_deinit)(struct _adapter *adapter);
171 struct net_device *pnetdev; 171 struct net_device *pnetdev;
172 int bup; 172 int bup;
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index 5153ad9c2c75..36348d900d34 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -71,7 +71,7 @@ static inline void _init_timer(struct timer_list *ptimer,
71 71
72static inline void _set_timer(struct timer_list *ptimer, u32 delay_time) 72static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
73{ 73{
74 mod_timer(ptimer, (jiffies+(delay_time*HZ/1000))); 74 mod_timer(ptimer, (jiffies+msecs_to_jiffies(delay_time)));
75} 75}
76 76
77static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled) 77static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled)
@@ -101,12 +101,9 @@ static inline void sleep_schedulable(int ms)
101{ 101{
102 u32 delta; 102 u32 delta;
103 103
104 delta = (ms * HZ) / 1000;/*(ms)*/ 104 delta = msecs_to_jiffies(ms);/*(ms)*/
105 if (delta == 0)
106 delta = 1;/* 1 ms */
107 set_current_state(TASK_INTERRUPTIBLE); 105 set_current_state(TASK_INTERRUPTIBLE);
108 if (schedule_timeout(delta) != 0) 106 schedule_timeout(delta);
109 return;
110} 107}
111 108
112static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer) 109static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c
index 0631f3638257..409c8c897256 100644
--- a/drivers/staging/rtl8712/recv_linux.c
+++ b/drivers/staging/rtl8712/recv_linux.c
@@ -137,20 +137,6 @@ _recv_indicatepkt_drop:
137 precvpriv->rx_drop++; 137 precvpriv->rx_drop++;
138} 138}
139 139
140void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf)
141{
142 struct recv_priv *precvpriv = &padapter->recvpriv;
143
144 precvbuf->ref_cnt--;
145 /*free skb in recv_buf*/
146 dev_kfree_skb_any(precvbuf->pskb);
147 precvbuf->pskb = NULL;
148 precvbuf->reuse = false;
149 if (!precvbuf->irp_pending)
150 r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
151 (unsigned char *)precvbuf);
152}
153
154static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext) 140static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext)
155{ 141{
156 struct recv_reorder_ctrl *preorder_ctrl = 142 struct recv_reorder_ctrl *preorder_ctrl =
diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h
index f4384ef00868..1f4986e940a3 100644
--- a/drivers/staging/rtl8712/recv_osdep.h
+++ b/drivers/staging/rtl8712/recv_osdep.h
@@ -46,7 +46,6 @@ int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter,
46 struct recv_buf *precvbuf); 46 struct recv_buf *precvbuf);
47int r8712_os_recvbuf_resource_free(struct _adapter *padapter, 47int r8712_os_recvbuf_resource_free(struct _adapter *padapter,
48 struct recv_buf *precvbuf); 48 struct recv_buf *precvbuf);
49void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf);
50void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); 49void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl);
51 50
52#endif 51#endif
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h
index 039ab3e97172..67e9e910aef9 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.h
+++ b/drivers/staging/rtl8712/rtl8712_cmd.h
@@ -109,16 +109,16 @@ enum rtl8712_h2c_cmd {
109 GEN_CMD_CODE(_DisconnectCtrlEx), /*61*/ 109 GEN_CMD_CODE(_DisconnectCtrlEx), /*61*/
110 110
111 /* To do, modify these h2c cmd, add or delete */ 111 /* To do, modify these h2c cmd, add or delete */
112 GEN_CMD_CODE(_GetH2cLbk) , 112 GEN_CMD_CODE(_GetH2cLbk),
113 113
114 /* WPS extra IE */ 114 /* WPS extra IE */
115 GEN_CMD_CODE(_SetProbeReqExtraIE) , 115 GEN_CMD_CODE(_SetProbeReqExtraIE),
116 GEN_CMD_CODE(_SetAssocReqExtraIE) , 116 GEN_CMD_CODE(_SetAssocReqExtraIE),
117 GEN_CMD_CODE(_SetProbeRspExtraIE) , 117 GEN_CMD_CODE(_SetProbeRspExtraIE),
118 GEN_CMD_CODE(_SetAssocRspExtraIE) , 118 GEN_CMD_CODE(_SetAssocRspExtraIE),
119 119
120 /* the following is driver will do */ 120 /* the following is driver will do */
121 GEN_CMD_CODE(_GetCurDataRate) , 121 GEN_CMD_CODE(_GetCurDataRate),
122 122
123 GEN_CMD_CODE(_GetTxRetrycnt), /* to record times that Tx retry to 123 GEN_CMD_CODE(_GetTxRetrycnt), /* to record times that Tx retry to
124 * transmit packet after association 124 * transmit packet after association
diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h
index 3d7f79efa2c1..29a4c23a0d23 100644
--- a/drivers/staging/rtl8712/rtl8712_event.h
+++ b/drivers/staging/rtl8712/rtl8712_event.h
@@ -27,7 +27,7 @@
27#define _RTL8712_EVENT_H_ 27#define _RTL8712_EVENT_H_
28 28
29void r8712_event_handle(struct _adapter *padapter, uint *peventbuf); 29void r8712_event_handle(struct _adapter *padapter, uint *peventbuf);
30void r8712_got_addbareq_event_callback(struct _adapter *adapter , u8 *pbuf); 30void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf);
31 31
32enum rtl8712_c2h_event { 32enum rtl8712_c2h_event {
33 GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/ 33 GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index 73b7d864ccbd..9bb364f04fd4 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -196,7 +196,7 @@ static inline char *translate_scan(struct _adapter *padapter,
196 if (p && ht_ielen > 0) { 196 if (p && ht_ielen > 0) {
197 ht_cap = true; 197 ht_cap = true;
198 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 198 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
199 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2); 199 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
200 } 200 }
201 /* Add the protocol name */ 201 /* Add the protocol name */
202 iwe.cmd = SIOCGIWNAME; 202 iwe.cmd = SIOCGIWNAME;
@@ -1436,7 +1436,7 @@ static int r8711_wx_get_rate(struct net_device *dev,
1436 if (p && ht_ielen > 0) { 1436 if (p && ht_ielen > 0) {
1437 ht_cap = true; 1437 ht_cap = true;
1438 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 1438 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1439 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2); 1439 memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
1440 bw_40MHz = (pht_capie->cap_info & 1440 bw_40MHz = (pht_capie->cap_info &
1441 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0; 1441 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1442 short_GI = (pht_capie->cap_info & 1442 short_GI = (pht_capie->cap_info &
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
index b7462e8145d6..977a83358056 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -93,7 +93,7 @@ struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
93 return NULL; 93 return NULL;
94 spin_lock_irqsave(&free_queue->lock, irqL); 94 spin_lock_irqsave(&free_queue->lock, irqL);
95 plist = free_queue->queue.next; 95 plist = free_queue->queue.next;
96 pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list); 96 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
97 list_del_init(&pnetwork->list); 97 list_del_init(&pnetwork->list);
98 pnetwork->last_scanned = jiffies; 98 pnetwork->last_scanned = jiffies;
99 pmlmepriv->num_of_scanned++; 99 pmlmepriv->num_of_scanned++;
@@ -499,7 +499,7 @@ static int is_desired_network(struct _adapter *adapter,
499} 499}
500 500
501/* TODO: Perry : For Power Management */ 501/* TODO: Perry : For Power Management */
502void r8712_atimdone_event_callback(struct _adapter *adapter , u8 *pbuf) 502void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf)
503{ 503{
504} 504}
505 505
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
index a16f15e91992..0b5461208eb9 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
@@ -575,26 +575,6 @@ uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv
575 return RNDIS_STATUS_SUCCESS; 575 return RNDIS_STATUS_SUCCESS;
576} 576}
577 577
578uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
579{
580 struct _adapter *Adapter = (struct _adapter *)
581 (poid_par_priv->adapter_context);
582 uint status = RNDIS_STATUS_SUCCESS;
583 struct ndis_802_11_ssid *pssid;
584
585 if (poid_par_priv->type_of_oid != SET_OID)
586 return RNDIS_STATUS_NOT_ACCEPTED;
587 *poid_par_priv->bytes_needed = (u32)sizeof(struct ndis_802_11_ssid);
588 *poid_par_priv->bytes_rw = 0;
589 if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
590 return RNDIS_STATUS_INVALID_LENGTH;
591 pssid = (struct ndis_802_11_ssid *)poid_par_priv->information_buf;
592 if (mp_start_joinbss(Adapter, pssid) == _FAIL)
593 status = RNDIS_STATUS_NOT_ACCEPTED;
594 *poid_par_priv->bytes_rw = sizeof(struct ndis_802_11_ssid);
595 return status;
596}
597
598uint oid_rt_pro_read_register_hdl(struct oid_par_priv 578uint oid_rt_pro_read_register_hdl(struct oid_par_priv
599 *poid_par_priv) 579 *poid_par_priv)
600{ 580{
@@ -696,172 +676,6 @@ uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
696 return status; 676 return status;
697} 677}
698 678
699uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv
700 *poid_par_priv)
701{
702 struct _adapter *Adapter = (struct _adapter *)
703 (poid_par_priv->adapter_context);
704 struct burst_rw_reg *pBstRwReg;
705
706 if (poid_par_priv->type_of_oid != QUERY_OID)
707 return RNDIS_STATUS_NOT_ACCEPTED;
708 pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
709 r8712_read_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
710 pBstRwReg->Data);
711 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
712 return RNDIS_STATUS_SUCCESS;
713}
714
715uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv
716 *poid_par_priv)
717{
718 struct _adapter *Adapter = (struct _adapter *)
719 (poid_par_priv->adapter_context);
720 struct burst_rw_reg *pBstRwReg;
721
722 if (poid_par_priv->type_of_oid != SET_OID)
723 return RNDIS_STATUS_NOT_ACCEPTED;
724 pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
725 r8712_write_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
726 pBstRwReg->Data);
727 return RNDIS_STATUS_SUCCESS;
728}
729
730uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv)
731{
732 return RNDIS_STATUS_SUCCESS;
733}
734
735uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
736{
737 struct _adapter *Adapter = (struct _adapter *)
738 (poid_par_priv->adapter_context);
739 struct eeprom_rw_param *pEEPROM;
740
741 if (poid_par_priv->type_of_oid != QUERY_OID)
742 return RNDIS_STATUS_NOT_ACCEPTED;
743 pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
744 pEEPROM->value = r8712_eeprom_read16(Adapter,
745 (u16)(pEEPROM->offset >> 1));
746 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
747 return RNDIS_STATUS_SUCCESS;
748}
749
750uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
751{
752 struct _adapter *Adapter = (struct _adapter *)
753 (poid_par_priv->adapter_context);
754 struct eeprom_rw_param *pEEPROM;
755
756 if (poid_par_priv->type_of_oid != SET_OID)
757 return RNDIS_STATUS_NOT_ACCEPTED;
758 pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
759 r8712_eeprom_write16(Adapter, (u16)(pEEPROM->offset >> 1),
760 pEEPROM->value);
761 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
762 return RNDIS_STATUS_SUCCESS;
763}
764
765uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv)
766{
767 struct _adapter *Adapter = (struct _adapter *)
768 (poid_par_priv->adapter_context);
769 struct mp_wiparam *pwi_param;
770
771 if (poid_par_priv->type_of_oid != QUERY_OID)
772 return RNDIS_STATUS_NOT_ACCEPTED;
773 if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam))
774 return RNDIS_STATUS_INVALID_LENGTH;
775 if (Adapter->mppriv.workparam.bcompleted == false)
776 return RNDIS_STATUS_NOT_ACCEPTED;
777 pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf;
778 memcpy(pwi_param, &Adapter->mppriv.workparam,
779 sizeof(struct mp_wiparam));
780 Adapter->mppriv.act_in_progress = false;
781 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
782 return RNDIS_STATUS_SUCCESS;
783}
784
785uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv)
786{
787 struct _adapter *Adapter = (struct _adapter *)
788 (poid_par_priv->adapter_context);
789
790 if (poid_par_priv->type_of_oid != QUERY_OID)
791 return RNDIS_STATUS_NOT_ACCEPTED;
792 if (poid_par_priv->information_buf_len < sizeof(uint) * 2)
793 return RNDIS_STATUS_INVALID_LENGTH;
794 if (*(uint *)poid_par_priv->information_buf == 1)
795 Adapter->mppriv.rx_pktloss = 0;
796 *((uint *)poid_par_priv->information_buf+1) =
797 Adapter->mppriv.rx_pktloss;
798 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
799 return RNDIS_STATUS_SUCCESS;
800}
801
802uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
803{
804 if (poid_par_priv->type_of_oid != QUERY_OID)
805 return RNDIS_STATUS_NOT_ACCEPTED;
806 return RNDIS_STATUS_SUCCESS;
807}
808
809uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
810{
811 if (poid_par_priv->type_of_oid != SET_OID)
812 return RNDIS_STATUS_NOT_ACCEPTED;
813 return RNDIS_STATUS_SUCCESS;
814}
815
816uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv)
817{
818 struct _adapter *Adapter = (struct _adapter *)
819 (poid_par_priv->adapter_context);
820 uint status = RNDIS_STATUS_SUCCESS;
821
822 if (poid_par_priv->type_of_oid != SET_OID)
823 return RNDIS_STATUS_NOT_ACCEPTED;
824 if (r8712_setrfintfs_cmd(Adapter, *(unsigned char *)
825 poid_par_priv->information_buf) == _FAIL)
826 status = RNDIS_STATUS_NOT_ACCEPTED;
827 return status;
828}
829
830uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv)
831{
832 struct _adapter *Adapter = (struct _adapter *)
833 (poid_par_priv->adapter_context);
834
835 if (poid_par_priv->type_of_oid != QUERY_OID)
836 return RNDIS_STATUS_NOT_ACCEPTED;
837 memcpy(poid_par_priv->information_buf,
838 (unsigned char *)&Adapter->mppriv.rxstat,
839 sizeof(struct recv_stat));
840 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
841 return RNDIS_STATUS_SUCCESS;
842}
843
844uint oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv
845 *poid_par_priv)
846{
847 return RNDIS_STATUS_SUCCESS;
848}
849
850uint oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv
851 *poid_par_priv)
852{
853 struct _adapter *Adapter = (struct _adapter *)
854 (poid_par_priv->adapter_context);
855 uint status = RNDIS_STATUS_SUCCESS;
856
857 if (poid_par_priv->type_of_oid != SET_OID)
858 return RNDIS_STATUS_NOT_ACCEPTED;
859 if (r8712_setdatarate_cmd(Adapter,
860 poid_par_priv->information_buf) != _SUCCESS)
861 status = RNDIS_STATUS_NOT_ACCEPTED;
862 return status;
863}
864
865uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) 679uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
866{ 680{
867 struct _adapter *Adapter = (struct _adapter *) 681 struct _adapter *Adapter = (struct _adapter *)
@@ -890,251 +704,6 @@ uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
890 return RNDIS_STATUS_SUCCESS; 704 return RNDIS_STATUS_SUCCESS;
891} 705}
892 706
893uint oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv
894 *poid_par_priv)
895{
896 struct _adapter *Adapter = (struct _adapter *)
897 (poid_par_priv->adapter_context);
898 uint status = RNDIS_STATUS_SUCCESS;
899
900 if (poid_par_priv->type_of_oid != SET_OID)
901 return RNDIS_STATUS_NOT_ACCEPTED;
902 if (poid_par_priv->information_buf_len < sizeof(u8))
903 return RNDIS_STATUS_INVALID_LENGTH;
904 if (!r8712_setptm_cmd(Adapter, *((u8 *)poid_par_priv->information_buf)))
905 status = RNDIS_STATUS_NOT_ACCEPTED;
906 return status;
907}
908
909uint oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv)
910{
911 struct _adapter *Adapter = (struct _adapter *)
912 (poid_par_priv->adapter_context);
913 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
914 uint status = RNDIS_STATUS_SUCCESS;
915 u32 ratevalue;
916 u8 datarates[NumRates];
917 int i;
918
919 if (poid_par_priv->type_of_oid != SET_OID)
920 return RNDIS_STATUS_NOT_ACCEPTED;
921 ratevalue = *((u32 *)poid_par_priv->information_buf);
922 for (i = 0; i < NumRates; i++) {
923 if (ratevalue == mpdatarate[i])
924 datarates[i] = mpdatarate[i];
925 else
926 datarates[i] = 0xff;
927 }
928 if (r8712_setbasicrate_cmd(Adapter, datarates) != _SUCCESS)
929 status = RNDIS_STATUS_NOT_ACCEPTED;
930 return status;
931}
932
933uint oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
934{
935 struct _adapter *Adapter = (struct _adapter *)
936 (poid_par_priv->adapter_context);
937
938 if (poid_par_priv->type_of_oid != QUERY_OID)
939 return RNDIS_STATUS_NOT_ACCEPTED;
940 if (poid_par_priv->information_buf_len < 8)
941 return RNDIS_STATUS_INVALID_LENGTH;
942 *poid_par_priv->bytes_rw = 8;
943 memcpy(poid_par_priv->information_buf,
944 &(Adapter->pwrctrlpriv.pwr_mode), 8);
945 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
946 return RNDIS_STATUS_SUCCESS;
947}
948
949uint oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
950{
951 struct _adapter *Adapter = (struct _adapter *)
952 (poid_par_priv->adapter_context);
953 uint pwr_mode, smart_ps;
954
955 if (poid_par_priv->type_of_oid != SET_OID)
956 return RNDIS_STATUS_NOT_ACCEPTED;
957 *poid_par_priv->bytes_rw = 0;
958 *poid_par_priv->bytes_needed = 8;
959 if (poid_par_priv->information_buf_len < 8)
960 return RNDIS_STATUS_INVALID_LENGTH;
961 pwr_mode = *(uint *)(poid_par_priv->information_buf);
962 smart_ps = *(uint *)((addr_t)poid_par_priv->information_buf + 4);
963 if (pwr_mode != Adapter->pwrctrlpriv.pwr_mode || smart_ps !=
964 Adapter->pwrctrlpriv.smart_ps)
965 r8712_set_ps_mode(Adapter, pwr_mode, smart_ps);
966 *poid_par_priv->bytes_rw = 8;
967 return RNDIS_STATUS_SUCCESS;
968}
969
970uint oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv
971 *poid_par_priv)
972{
973 struct _adapter *Adapter = (struct _adapter *)
974 (poid_par_priv->adapter_context);
975 uint status = RNDIS_STATUS_SUCCESS;
976 struct setratable_parm *prate_table;
977 u8 res;
978
979 if (poid_par_priv->type_of_oid != SET_OID)
980 return RNDIS_STATUS_NOT_ACCEPTED;
981 *poid_par_priv->bytes_needed = sizeof(struct setratable_parm);
982 if (poid_par_priv->information_buf_len <
983 sizeof(struct setratable_parm))
984 return RNDIS_STATUS_INVALID_LENGTH;
985 prate_table = (struct setratable_parm *)poid_par_priv->information_buf;
986 res = r8712_setrttbl_cmd(Adapter, prate_table);
987 if (res == _FAIL)
988 status = RNDIS_STATUS_FAILURE;
989 return status;
990}
991
992uint oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv
993 *poid_par_priv)
994{
995 if (poid_par_priv->type_of_oid != QUERY_OID)
996 return RNDIS_STATUS_NOT_ACCEPTED;
997 return RNDIS_STATUS_SUCCESS;
998}
999
1000uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv
1001 *poid_par_priv)
1002{
1003 struct _adapter *Adapter = (struct _adapter *)
1004 (poid_par_priv->adapter_context);
1005 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1006 enum ENCRY_CTRL_STATE encry_mode = 0;
1007
1008 *poid_par_priv->bytes_needed = sizeof(u8);
1009 if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1010 return RNDIS_STATUS_INVALID_LENGTH;
1011
1012 if (poid_par_priv->type_of_oid == SET_OID) {
1013 encry_mode = *((u8 *)poid_par_priv->information_buf);
1014 switch (encry_mode) {
1015 case HW_CONTROL:
1016 psecuritypriv->sw_decrypt = false;
1017 psecuritypriv->sw_encrypt = false;
1018 break;
1019 case SW_CONTROL:
1020 psecuritypriv->sw_decrypt = true;
1021 psecuritypriv->sw_encrypt = true;
1022 break;
1023 case HW_ENCRY_SW_DECRY:
1024 psecuritypriv->sw_decrypt = true;
1025 psecuritypriv->sw_encrypt = false;
1026 break;
1027 case SW_ENCRY_HW_DECRY:
1028 psecuritypriv->sw_decrypt = false;
1029 psecuritypriv->sw_encrypt = true;
1030 break;
1031 }
1032 } else {
1033 if ((psecuritypriv->sw_encrypt == false) &&
1034 (psecuritypriv->sw_decrypt == false))
1035 encry_mode = HW_CONTROL;
1036 else if ((psecuritypriv->sw_encrypt == false) &&
1037 (psecuritypriv->sw_decrypt == true))
1038 encry_mode = HW_ENCRY_SW_DECRY;
1039 else if ((psecuritypriv->sw_encrypt == true) &&
1040 (psecuritypriv->sw_decrypt == false))
1041 encry_mode = SW_ENCRY_HW_DECRY;
1042 else if ((psecuritypriv->sw_encrypt == true) &&
1043 (psecuritypriv->sw_decrypt == true))
1044 encry_mode = SW_CONTROL;
1045 *(u8 *)poid_par_priv->information_buf = encry_mode;
1046 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1047 }
1048 return RNDIS_STATUS_SUCCESS;
1049}
1050/*----------------------------------------------------------------------*/
1051uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv)
1052{
1053 struct _adapter *Adapter = (struct _adapter *)
1054 (poid_par_priv->adapter_context);
1055
1056 uint status = RNDIS_STATUS_SUCCESS;
1057
1058 struct sta_info *psta = NULL;
1059 u8 *macaddr;
1060
1061
1062 if (poid_par_priv->type_of_oid != SET_OID)
1063 return RNDIS_STATUS_NOT_ACCEPTED;
1064
1065 *poid_par_priv->bytes_needed = ETH_ALEN;
1066 if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1067 return RNDIS_STATUS_INVALID_LENGTH;
1068 macaddr = (u8 *) poid_par_priv->information_buf;
1069 psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
1070 if (psta == NULL) { /* the sta in sta_info_queue => do nothing*/
1071 psta = r8712_alloc_stainfo(&Adapter->stapriv, macaddr);
1072 if (psta == NULL)
1073 status = RNDIS_STATUS_FAILURE;
1074 }
1075 return status;
1076}
1077/*-------------------------------------------------------------------------*/
1078uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv)
1079{
1080 struct _adapter *Adapter = (struct _adapter *)
1081 (poid_par_priv->adapter_context);
1082
1083 unsigned long irqL;
1084
1085 struct sta_info *psta = NULL;
1086 u8 *macaddr;
1087
1088
1089 if (poid_par_priv->type_of_oid != SET_OID)
1090 return RNDIS_STATUS_NOT_ACCEPTED;
1091
1092 *poid_par_priv->bytes_needed = ETH_ALEN;
1093 if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1094 return RNDIS_STATUS_INVALID_LENGTH;
1095
1096 macaddr = (u8 *)poid_par_priv->information_buf;
1097
1098 psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
1099 if (psta != NULL) {
1100 spin_lock_irqsave(&(Adapter->stapriv.sta_hash_lock), irqL);
1101 r8712_free_stainfo(Adapter, psta);
1102 spin_unlock_irqrestore(&(Adapter->stapriv.sta_hash_lock), irqL);
1103 }
1104
1105 return RNDIS_STATUS_SUCCESS;
1106}
1107/*--------------------------------------------------------------------------*/
1108static u32 mp_query_drv_var(struct _adapter *padapter, u8 offset, u32 var)
1109{
1110 return var;
1111}
1112
1113uint oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv)
1114{
1115 struct _adapter *Adapter = (struct _adapter *)
1116 (poid_par_priv->adapter_context);
1117
1118 struct DR_VARIABLE_STRUCT *pdrv_var;
1119
1120 if (poid_par_priv->type_of_oid != QUERY_OID)
1121 return RNDIS_STATUS_NOT_ACCEPTED;
1122 *poid_par_priv->bytes_needed = sizeof(struct DR_VARIABLE_STRUCT);
1123 if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1124 return RNDIS_STATUS_INVALID_LENGTH;
1125 pdrv_var = (struct DR_VARIABLE_STRUCT *)poid_par_priv->information_buf;
1126 pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset,
1127 pdrv_var->variable);
1128 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1129 return RNDIS_STATUS_SUCCESS;
1130}
1131
1132/*--------------------------------------------------------------------------*/
1133uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
1134{
1135 return RNDIS_STATUS_SUCCESS;
1136}
1137/*------------------------------------------------------------------------*/
1138uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) 707uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
1139{ 708{
1140 struct _adapter *Adapter = (struct _adapter *) 709 struct _adapter *Adapter = (struct _adapter *)
@@ -1192,38 +761,6 @@ uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
1192 return status; 761 return status;
1193} 762}
1194/*----------------------------------------------------------------------*/ 763/*----------------------------------------------------------------------*/
1195uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv)
1196{
1197 struct _adapter *Adapter = (struct _adapter *)
1198 (poid_par_priv->adapter_context);
1199 uint status = RNDIS_STATUS_SUCCESS;
1200 struct PGPKT_STRUCT *ppgpkt;
1201
1202 *poid_par_priv->bytes_rw = 0;
1203 if (poid_par_priv->information_buf_len < sizeof(struct PGPKT_STRUCT))
1204 return RNDIS_STATUS_INVALID_LENGTH;
1205 ppgpkt = (struct PGPKT_STRUCT *)poid_par_priv->information_buf;
1206 if (poid_par_priv->type_of_oid == QUERY_OID) {
1207 if (r8712_efuse_pg_packet_read(Adapter, ppgpkt->offset,
1208 ppgpkt->data) == true)
1209 *poid_par_priv->bytes_rw =
1210 poid_par_priv->information_buf_len;
1211 else
1212 status = RNDIS_STATUS_FAILURE;
1213 } else {
1214 if (r8712_efuse_reg_init(Adapter) == true) {
1215 if (r8712_efuse_pg_packet_write(Adapter, ppgpkt->offset,
1216 ppgpkt->word_en, ppgpkt->data) == true)
1217 *poid_par_priv->bytes_rw =
1218 poid_par_priv->information_buf_len;
1219 else
1220 status = RNDIS_STATUS_FAILURE;
1221 r8712_efuse_reg_uninit(Adapter);
1222 } else
1223 status = RNDIS_STATUS_FAILURE;
1224 }
1225 return status;
1226}
1227 764
1228uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv 765uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv
1229 *poid_par_priv) 766 *poid_par_priv)
@@ -1319,24 +856,6 @@ uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
1319 return RNDIS_STATUS_SUCCESS; 856 return RNDIS_STATUS_SUCCESS;
1320} 857}
1321 858
1322uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv)
1323{
1324 struct _adapter *Adapter = (struct _adapter *)
1325 (poid_par_priv->adapter_context);
1326 u32 crystal_cap = 0;
1327
1328 if (poid_par_priv->type_of_oid != SET_OID)
1329 return RNDIS_STATUS_NOT_ACCEPTED;
1330 if (poid_par_priv->information_buf_len < sizeof(u32))
1331 return RNDIS_STATUS_INVALID_LENGTH;
1332 crystal_cap = *((u32 *)poid_par_priv->information_buf);/*4*/
1333 if (crystal_cap > 0xf)
1334 return RNDIS_STATUS_NOT_ACCEPTED;
1335 Adapter->mppriv.curr_crystalcap = crystal_cap;
1336 r8712_SetCrystalCap(Adapter);
1337 return RNDIS_STATUS_SUCCESS;
1338}
1339
1340uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv 859uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
1341 *poid_par_priv) 860 *poid_par_priv)
1342{ 861{
@@ -1378,50 +897,6 @@ uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
1378 return RNDIS_STATUS_SUCCESS; 897 return RNDIS_STATUS_SUCCESS;
1379} 898}
1380 899
1381uint oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv
1382 *poid_par_priv)
1383{
1384 struct _adapter *Adapter = (struct _adapter *)
1385 (poid_par_priv->adapter_context);
1386 u32 txagc;
1387
1388 if (poid_par_priv->type_of_oid != SET_OID)
1389 return RNDIS_STATUS_NOT_ACCEPTED;
1390 if (poid_par_priv->information_buf_len < sizeof(u32))
1391 return RNDIS_STATUS_INVALID_LENGTH;
1392 txagc = *(u32 *)poid_par_priv->information_buf;
1393 r8712_SetTxAGCOffset(Adapter, txagc);
1394 return RNDIS_STATUS_SUCCESS;
1395}
1396
1397uint oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv
1398 *poid_par_priv)
1399{
1400 struct _adapter *Adapter = (struct _adapter *)
1401 (poid_par_priv->adapter_context);
1402 uint status = RNDIS_STATUS_SUCCESS;
1403 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
1404 struct mp_priv *pmppriv = &Adapter->mppriv;
1405 u32 type;
1406
1407 if (poid_par_priv->type_of_oid != SET_OID)
1408 return RNDIS_STATUS_NOT_ACCEPTED;
1409
1410 if (poid_par_priv->information_buf_len < sizeof(u32))
1411 return RNDIS_STATUS_INVALID_LENGTH;
1412
1413 type = *(u32 *)poid_par_priv->information_buf;
1414
1415 if (_LOOPBOOK_MODE_ == type) {
1416 pmppriv->mode = type;
1417 set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
1418 } else if (_2MAC_MODE_ == type) {
1419 pmppriv->mode = type;
1420 _clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE);
1421 } else
1422 status = RNDIS_STATUS_NOT_ACCEPTED;
1423 return status;
1424}
1425/*--------------------------------------------------------------------------*/ 900/*--------------------------------------------------------------------------*/
1426/*Linux*/ 901/*Linux*/
1427unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) 902unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
index 850143d5dee3..8e7c7f8b69f9 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
@@ -86,41 +86,8 @@ struct DR_VARIABLE_STRUCT {
86int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid); 86int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid);
87 87
88/* oid_rtl_seg_87_11_00 */ 88/* oid_rtl_seg_87_11_00 */
89uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv);
90uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv); 89uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv);
91uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv); 90uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv);
92uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv*
93 poid_par_priv);
94uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv*
95 poid_par_priv);
96uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv);
97uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
98uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
99uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv);
100uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv);
101uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
102uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
103uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv);
104uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv);
105/* oid_rtl_seg_87_11_20 */
106uint oid_rt_pro_cfg_debug_message_hdl(
107 struct oid_par_priv *poid_par_priv);
108uint oid_rt_pro_set_data_rate_ex_hdl(
109 struct oid_par_priv *poid_par_priv);
110uint oid_rt_pro_set_basic_rate_hdl(
111 struct oid_par_priv *poid_par_priv);
112uint oid_rt_pro_set_power_tracking_hdl(
113 struct oid_par_priv *poid_par_priv);
114/* oid_rtl_seg_87_11_50 */
115uint oid_rt_pro_qry_pwrstate_hdl(
116 struct oid_par_priv *poid_par_priv);
117uint oid_rt_pro_set_pwrstate_hdl(
118 struct oid_par_priv *poid_par_priv);
119/* oid_rtl_seg_87_11_F0 */
120uint oid_rt_pro_h2c_set_rate_table_hdl(
121 struct oid_par_priv *poid_par_priv);
122uint oid_rt_pro_h2c_get_rate_table_hdl(
123 struct oid_par_priv *poid_par_priv);
124/* oid_rtl_seg_81_80_00 */ 91/* oid_rtl_seg_81_80_00 */
125uint oid_rt_pro_set_data_rate_hdl( 92uint oid_rt_pro_set_data_rate_hdl(
126 struct oid_par_priv *poid_par_priv); 93 struct oid_par_priv *poid_par_priv);
@@ -159,28 +126,15 @@ uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
159uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv); 126uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
160/* oid_rtl_seg_81_85 */ 127/* oid_rtl_seg_81_85 */
161uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); 128uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv);
162/* oid_rtl_seg_87_12_00 */
163uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv);
164uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv);
165uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv);
166uint oid_rt_pro_query_dr_variable_hdl(
167 struct oid_par_priv *poid_par_priv);
168uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
169uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); 129uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv);
170uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); 130uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv);
171uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv);
172uint oid_rt_get_efuse_current_size_hdl( 131uint oid_rt_get_efuse_current_size_hdl(
173 struct oid_par_priv *poid_par_priv); 132 struct oid_par_priv *poid_par_priv);
174uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); 133uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv);
175uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); 134uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv);
176uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv); 135uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv);
177uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv);
178uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); 136uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
179uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv); 137uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv);
180uint oid_rt_pro_set_tx_agc_offset_hdl(
181 struct oid_par_priv *poid_par_priv);
182uint oid_rt_pro_set_pkt_test_mode_hdl(
183 struct oid_par_priv *poid_par_priv);
184uint oid_rt_get_thermal_meter_hdl( 138uint oid_rt_get_thermal_meter_hdl(
185 struct oid_par_priv *poid_par_priv); 139 struct oid_par_priv *poid_par_priv);
186uint oid_rt_reset_phy_rx_packet_count_hdl( 140uint oid_rt_reset_phy_rx_packet_count_hdl(
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
index 0526ba077bfc..dbfb55523545 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
@@ -33,17 +33,17 @@
33#define CMD_ALIVE BIT(2) 33#define CMD_ALIVE BIT(2)
34 34
35enum Power_Mgnt { 35enum Power_Mgnt {
36 PS_MODE_ACTIVE = 0 , 36 PS_MODE_ACTIVE = 0,
37 PS_MODE_MIN , 37 PS_MODE_MIN,
38 PS_MODE_MAX , 38 PS_MODE_MAX,
39 PS_MODE_DTIM , 39 PS_MODE_DTIM,
40 PS_MODE_VOIP , 40 PS_MODE_VOIP,
41 PS_MODE_UAPSD_WMM , 41 PS_MODE_UAPSD_WMM,
42 PS_MODE_UAPSD , 42 PS_MODE_UAPSD,
43 PS_MODE_IBSS , 43 PS_MODE_IBSS,
44 PS_MODE_WWLAN , 44 PS_MODE_WWLAN,
45 PM_Radio_Off , 45 PM_Radio_Off,
46 PM_Card_Disable , 46 PM_Card_Disable,
47 PS_MODE_NUM 47 PS_MODE_NUM
48}; 48};
49 49
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index 4c9b98e8210e..1752121ff494 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -83,9 +83,8 @@ static void mfree_all_stainfo(struct sta_priv *pstapriv)
83 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); 83 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
84 phead = &pstapriv->free_sta_queue.queue; 84 phead = &pstapriv->free_sta_queue.queue;
85 plist = phead->next; 85 plist = phead->next;
86 while ((end_of_queue_search(phead, plist)) == false) { 86 while ((end_of_queue_search(phead, plist)) == false)
87 plist = plist->next; 87 plist = plist->next;
88 }
89 88
90 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 89 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
91} 90}
@@ -228,7 +227,7 @@ void r8712_free_all_stainfo(struct _adapter *padapter)
228 struct sta_info, hash_list); 227 struct sta_info, hash_list);
229 plist = plist->next; 228 plist = plist->next;
230 if (pbcmc_stainfo != psta) 229 if (pbcmc_stainfo != psta)
231 r8712_free_stainfo(padapter , psta); 230 r8712_free_stainfo(padapter, psta);
232 } 231 }
233 } 232 }
234 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 233 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index 62a377e7fdc7..a28af03c9d8a 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -471,7 +471,7 @@ static sint xmitframe_swencrypt(struct _adapter *padapter,
471 return _SUCCESS; 471 return _SUCCESS;
472} 472}
473 473
474static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr, 474static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr,
475 struct pkt_attrib *pattrib) 475 struct pkt_attrib *pattrib)
476{ 476{
477 u16 *qc; 477 u16 *qc;
diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h
index c4e0ef2f52c6..742dfa0ca817 100644
--- a/drivers/staging/rtl8712/sta_info.h
+++ b/drivers/staging/rtl8712/sta_info.h
@@ -135,7 +135,7 @@ u32 _r8712_init_sta_priv(struct sta_priv *pstapriv);
135u32 _r8712_free_sta_priv(struct sta_priv *pstapriv); 135u32 _r8712_free_sta_priv(struct sta_priv *pstapriv);
136struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, 136struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv,
137 u8 *hwaddr); 137 u8 *hwaddr);
138void r8712_free_stainfo(struct _adapter *padapter , struct sta_info *psta); 138void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta);
139void r8712_free_all_stainfo(struct _adapter *padapter); 139void r8712_free_all_stainfo(struct _adapter *padapter);
140struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); 140struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr);
141void r8712_init_bcmc_stainfo(struct _adapter *padapter); 141void r8712_init_bcmc_stainfo(struct _adapter *padapter);
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 7d0d1719b136..f8b5b332e7c3 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -366,7 +366,6 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
366 struct net_device *pnetdev; 366 struct net_device *pnetdev;
367 struct usb_device *udev; 367 struct usb_device *udev;
368 368
369 printk(KERN_INFO "r8712u: Staging version\n");
370 /* In this probe function, O.S. will provide the usb interface pointer 369 /* In this probe function, O.S. will provide the usb interface pointer
371 * to driver. We have to increase the reference count of the usb device 370 * to driver. We have to increase the reference count of the usb device
372 * structure by using the usb_get_dev function. 371 * structure by using the usb_get_dev function.
@@ -463,7 +462,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
463 /* Use the mac address stored in the Efuse 462 /* Use the mac address stored in the Efuse
464 * offset = 0x12 for usb in efuse 463 * offset = 0x12 for usb in efuse
465 */ 464 */
466 memcpy(mac, &pdata[0x12], ETH_ALEN); 465 ether_addr_copy(mac, &pdata[0x12]);
467 } 466 }
468 eeprom_CustomerID = pdata[0x52]; 467 eeprom_CustomerID = pdata[0x52];
469 switch (eeprom_CustomerID) { 468 switch (eeprom_CustomerID) {
@@ -580,7 +579,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
580 } else 579 } else
581 dev_info(&udev->dev, 580 dev_info(&udev->dev,
582 "r8712u: MAC Address from efuse = %pM\n", mac); 581 "r8712u: MAC Address from efuse = %pM\n", mac);
583 memcpy(pnetdev->dev_addr, mac, ETH_ALEN); 582 ether_addr_copy(pnetdev->dev_addr, mac);
584 } 583 }
585 /* step 6. Load the firmware asynchronously */ 584 /* step 6. Load the firmware asynchronously */
586 if (rtl871x_load_fw(padapter)) 585 if (rtl871x_load_fw(padapter))
diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c
index e394d12c36b0..c6327c072918 100644
--- a/drivers/staging/rtl8723au/core/rtw_ap.c
+++ b/drivers/staging/rtl8723au/core/rtw_ap.c
@@ -456,8 +456,8 @@ static void update_bmc_sta(struct rtw_adapter *padapter)
456 sizeof(struct stainfo_stats)); 456 sizeof(struct stainfo_stats));
457 457
458 /* prepare for add_RATid23a */ 458 /* prepare for add_RATid23a */
459 supportRateNum = rtw_get_rateset_len23a((u8*)&pcur_network->SupportedRates); 459 supportRateNum = rtw_get_rateset_len23a((u8 *)&pcur_network->SupportedRates);
460 network_type = rtw_check_network_type23a((u8*)&pcur_network->SupportedRates, supportRateNum, 1); 460 network_type = rtw_check_network_type23a((u8 *)&pcur_network->SupportedRates, supportRateNum, 1);
461 461
462 memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum); 462 memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
463 psta->bssratelen = supportRateNum; 463 psta->bssratelen = supportRateNum;
@@ -897,7 +897,7 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
897 pairwise_cipher = 0; 897 pairwise_cipher = 0;
898 psecuritypriv->wpa_group_cipher = 0; 898 psecuritypriv->wpa_group_cipher = 0;
899 psecuritypriv->wpa_pairwise_cipher = 0; 899 psecuritypriv->wpa_pairwise_cipher = 0;
900 for (p = ie; ;p += (ie_len + 2)) { 900 for (p = ie; ; p += (ie_len + 2)) {
901 p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len, 901 p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
902 pbss_network->IELength - (ie_len + 2)); 902 pbss_network->IELength - (ie_len + 2));
903 if ((p) && (!memcmp(p+2, RTW_WPA_OUI23A_TYPE, 4))) { 903 if ((p) && (!memcmp(p+2, RTW_WPA_OUI23A_TYPE, 4))) {
@@ -924,7 +924,7 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
924 ie_len = 0; 924 ie_len = 0;
925 pmlmepriv->qos_option = 0; 925 pmlmepriv->qos_option = 0;
926 if (pregistrypriv->wmm_enable) { 926 if (pregistrypriv->wmm_enable) {
927 for (p = ie; ;p += (ie_len + 2)) { 927 for (p = ie; ; p += (ie_len + 2)) {
928 p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len, 928 p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
929 (pbss_network->IELength - 929 (pbss_network->IELength -
930 (ie_len + 2))); 930 (ie_len + 2)));
@@ -1204,7 +1204,7 @@ static void update_bcn_p2p_ie(struct rtw_adapter *padapter)
1204{ 1204{
1205} 1205}
1206 1206
1207static void update_bcn_vendor_spec_ie(struct rtw_adapter *padapter, u8*oui) 1207static void update_bcn_vendor_spec_ie(struct rtw_adapter *padapter, u8 *oui)
1208{ 1208{
1209 DBG_8723A("%s\n", __func__); 1209 DBG_8723A("%s\n", __func__);
1210 1210
diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c
index 60e0ded8ae02..2447a56df838 100644
--- a/drivers/staging/rtl8723au/core/rtw_cmd.c
+++ b/drivers/staging/rtl8723au/core/rtw_cmd.c
@@ -245,11 +245,6 @@ exit:
245 return res; 245 return res;
246} 246}
247 247
248void rtw_cmd_clr_isr23a(struct cmd_priv *pcmdpriv)
249{
250 pcmdpriv->cmd_done_cnt++;
251}
252
253void rtw_free_cmd_obj23a(struct cmd_obj *pcmd) 248void rtw_free_cmd_obj23a(struct cmd_obj *pcmd)
254{ 249{
255 250
@@ -852,62 +847,6 @@ exit:
852 return res; 847 return res;
853} 848}
854 849
855/*
856 * This is only ever called from on_action_spct23a_ch_switch () which isn't
857 * called from anywhere itself
858 */
859int rtw_set_ch_cmd23a(struct rtw_adapter *padapter, u8 ch, u8 bw, u8 ch_offset,
860 u8 enqueue)
861{
862 struct cmd_obj *pcmdobj;
863 struct set_ch_parm *set_ch_parm;
864 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
865 int res = _SUCCESS;
866
867 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
868 padapter->pnetdev->name, ch, bw, ch_offset);
869
870 /* check input parameter */
871
872 /* prepare cmd parameter */
873 set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_KERNEL);
874 if (!set_ch_parm) {
875 res = _FAIL;
876 goto exit;
877 }
878 set_ch_parm->ch = ch;
879 set_ch_parm->bw = bw;
880 set_ch_parm->ch_offset = ch_offset;
881
882 if (enqueue) {
883 /* need enqueue, prepare cmd_obj and enqueue */
884 pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
885 if (!pcmdobj) {
886 kfree(set_ch_parm);
887 res = _FAIL;
888 goto exit;
889 }
890
891 init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm,
892 GEN_CMD_CODE(_SetChannel));
893 res = rtw_enqueue_cmd23a(pcmdpriv, pcmdobj);
894 } else {
895 /* no need to enqueue, do the cmd hdl directly and
896 free cmd parameter */
897 if (H2C_SUCCESS != set_ch_hdl23a(padapter, (u8 *)set_ch_parm))
898 res = _FAIL;
899
900 kfree(set_ch_parm);
901 }
902
903 /* do something based on res... */
904exit:
905
906 DBG_8723A("%s(%s): res:%u\n", __func__, padapter->pnetdev->name, res);
907
908 return res;
909}
910
911static void traffic_status_watchdog(struct rtw_adapter *padapter) 850static void traffic_status_watchdog(struct rtw_adapter *padapter)
912{ 851{
913 u8 bEnterPS; 852 u8 bEnterPS;
diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c
index 81960e788f89..a6deddc02291 100644
--- a/drivers/staging/rtl8723au/core/rtw_efuse.c
+++ b/drivers/staging/rtl8723au/core/rtw_efuse.c
@@ -327,15 +327,9 @@ EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
327 *---------------------------------------------------------------------------*/ 327 *---------------------------------------------------------------------------*/
328 328
329void 329void
330EFUSE_Write1Byte( 330EFUSE_Write1Byte(struct rtw_adapter *Adapter, u16 Address, u8 Value);
331 struct rtw_adapter * Adapter,
332 u16 Address,
333 u8 Value);
334void 331void
335EFUSE_Write1Byte( 332EFUSE_Write1Byte(struct rtw_adapter *Adapter, u16 Address, u8 Value)
336 struct rtw_adapter * Adapter,
337 u16 Address,
338 u8 Value)
339{ 333{
340 u8 Bytetemp = {0x00}; 334 u8 Bytetemp = {0x00};
341 u8 temp = {0x00}; 335 u8 temp = {0x00};
@@ -635,10 +629,7 @@ Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse)
635 * 629 *
636 *---------------------------------------------------------------------------*/ 630 *---------------------------------------------------------------------------*/
637static void 631static void
638efuse_ShadowRead1Byte( 632efuse_ShadowRead1Byte(struct rtw_adapter *pAdapter, u16 Offset, u8 *Value)
639 struct rtw_adapter * pAdapter,
640 u16 Offset,
641 u8 *Value)
642{ 633{
643 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); 634 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
644 635
@@ -647,10 +638,7 @@ efuse_ShadowRead1Byte(
647 638
648/* Read Two Bytes */ 639/* Read Two Bytes */
649static void 640static void
650efuse_ShadowRead2Byte( 641efuse_ShadowRead2Byte(struct rtw_adapter *pAdapter, u16 Offset, u16 *Value)
651 struct rtw_adapter * pAdapter,
652 u16 Offset,
653 u16 *Value)
654{ 642{
655 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); 643 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
656 644
@@ -660,10 +648,7 @@ efuse_ShadowRead2Byte(
660 648
661/* Read Four Bytes */ 649/* Read Four Bytes */
662static void 650static void
663efuse_ShadowRead4Byte( 651efuse_ShadowRead4Byte(struct rtw_adapter *pAdapter, u16 Offset, u32 *Value)
664 struct rtw_adapter * pAdapter,
665 u16 Offset,
666 u32 *Value)
667{ 652{
668 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); 653 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
669 654
@@ -722,11 +707,8 @@ void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType)
722 * 707 *
723 *---------------------------------------------------------------------------*/ 708 *---------------------------------------------------------------------------*/
724void 709void
725EFUSE_ShadowRead23a( 710EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter,
726 struct rtw_adapter * pAdapter, 711 u8 Type, u16 Offset, u32 *Value)
727 u8 Type,
728 u16 Offset,
729 u32 *Value)
730{ 712{
731 if (Type == 1) 713 if (Type == 1)
732 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); 714 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c
index 7a5e6bf0d1ae..1c82dffcf596 100644
--- a/drivers/staging/rtl8723au/core/rtw_xmit.c
+++ b/drivers/staging/rtl8723au/core/rtw_xmit.c
@@ -2372,12 +2372,3 @@ int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms)
2372 return rtw_sctx_wait23a(pack_tx_ops); 2372 return rtw_sctx_wait23a(pack_tx_ops);
2373} 2373}
2374 2374
2375void rtw_ack_tx_done23a(struct xmit_priv *pxmitpriv, int status)
2376{
2377 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2378
2379 if (pxmitpriv->ack_tx)
2380 rtw23a_sctx_done_err(&pack_tx_ops, status);
2381 else
2382 DBG_8723A("%s ack_tx not set\n", __func__);
2383}
diff --git a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
index 1da4eece6f9a..33777d2852f4 100644
--- a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
@@ -47,11 +47,11 @@ u8 HalPwrSeqCmdParsing23a(struct rtw_adapter *padapter, u8 CutVersion,
47 u8 FabVersion, u8 InterfaceType, 47 u8 FabVersion, u8 InterfaceType,
48 struct wlan_pwr_cfg PwrSeqCmd[]) 48 struct wlan_pwr_cfg PwrSeqCmd[])
49{ 49{
50 struct wlan_pwr_cfg PwrCfgCmd = { 0 }; 50 struct wlan_pwr_cfg PwrCfgCmd;
51 u8 bPollingBit = false; 51 u8 bPollingBit;
52 u32 AryIdx = 0; 52 u32 AryIdx = 0;
53 u8 value = 0; 53 u8 value;
54 u32 offset = 0; 54 u32 offset;
55 u32 pollingCount = 0; /* polling autoload done. */ 55 u32 pollingCount = 0; /* polling autoload done. */
56 u32 maxPollingCnt = 5000; 56 u32 maxPollingCnt = 5000;
57 57
diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c
index 1c0f106d5996..5269b46445f4 100644
--- a/drivers/staging/rtl8723au/hal/odm.c
+++ b/drivers/staging/rtl8723au/hal/odm.c
@@ -187,24 +187,13 @@ void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm);
187 187
188void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm); 188void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm);
189 189
190void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm);
191/* END---------BB POWER SAVE----------------------- */ 190/* END---------BB POWER SAVE----------------------- */
192 191
193void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm);
194
195void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm); 192void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm);
196 193
197void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm);
198
199void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm); 194void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm);
200 195
201void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm);
202
203void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm);
204
205void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm); 196void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm);
206void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm);
207
208void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm); 197void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm);
209void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm); 198void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm);
210 199
@@ -212,16 +201,12 @@ void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm);
212 201
213void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm); 202void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm);
214 203
215void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm);
216
217void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm); 204void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm);
218 205
219void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm); 206void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm);
220 207
221void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm); 208void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm);
222 209
223void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm);
224
225void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm); 210void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm);
226 211
227static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm); 212static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
@@ -946,47 +931,13 @@ void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm)
946 return; 931 return;
947} 932}
948 933
949void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm)
950{
951 struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
952
953 if (pDM_Odm->RSSI_Min != 0xFF) {
954 if (pDM_PSTable->PreCCAState == CCA_2R) {
955 if (pDM_Odm->RSSI_Min >= 35)
956 pDM_PSTable->CurCCAState = CCA_1R;
957 else
958 pDM_PSTable->CurCCAState = CCA_2R;
959 } else {
960 if (pDM_Odm->RSSI_Min <= 30)
961 pDM_PSTable->CurCCAState = CCA_2R;
962 else
963 pDM_PSTable->CurCCAState = CCA_1R;
964 }
965 } else {
966 pDM_PSTable->CurCCAState = CCA_MAX;
967 }
968
969 if (pDM_PSTable->PreCCAState != pDM_PSTable->CurCCAState) {
970 if (pDM_PSTable->CurCCAState == CCA_1R) {
971 if (pDM_Odm->RFType == ODM_2T2R)
972 ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x13);
973 else
974 ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x23);
975 } else {
976 ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x33);
977 /* PHY_SetBBReg(pAdapter, 0xe70, bMaskByte3, 0x63); */
978 }
979 pDM_PSTable->PreCCAState = pDM_PSTable->CurCCAState;
980 }
981}
982
983void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) 934void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal)
984{ 935{
985 struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; 936 struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
986 u8 Rssi_Up_bound = 30 ; 937 u8 Rssi_Up_bound = 30;
987 u8 Rssi_Low_bound = 25; 938 u8 Rssi_Low_bound = 25;
988 if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */ 939 if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */
989 Rssi_Up_bound = 50 ; 940 Rssi_Up_bound = 50;
990 Rssi_Low_bound = 45; 941 Rssi_Low_bound = 45;
991 } 942 }
992 if (pDM_PSTable->initialize == 0) { 943 if (pDM_PSTable->initialize == 0) {
@@ -1177,10 +1128,6 @@ void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm)
1177 odm_RefreshRateAdaptiveMask23aCE23a(pDM_Odm); 1128 odm_RefreshRateAdaptiveMask23aCE23a(pDM_Odm);
1178} 1129}
1179 1130
1180void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm)
1181{
1182}
1183
1184void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm) 1131void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm)
1185{ 1132{
1186 u8 i; 1133 u8 i;
@@ -1216,10 +1163,6 @@ void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm)
1216 1163
1217} 1164}
1218 1165
1219void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm)
1220{
1221}
1222
1223/* Return Value: bool */ 1166/* Return Value: bool */
1224/* - true: RATRState is changed. */ 1167/* - true: RATRState is changed. */
1225bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate, 1168bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate,
@@ -1284,14 +1227,6 @@ void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm)
1284 pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; 1227 pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal;
1285} 1228}
1286 1229
1287/* 3 ============================================================ */
1288/* 3 RSSI Monitor */
1289/* 3 ============================================================ */
1290
1291void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm)
1292{
1293}
1294
1295void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm) 1230void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm)
1296{ 1231{
1297 /* For AP/ADSL use struct rtl8723a_priv * */ 1232 /* For AP/ADSL use struct rtl8723a_priv * */
@@ -1306,10 +1241,6 @@ void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm)
1306 odm_RSSIMonitorCheck23aCE(pDM_Odm); 1241 odm_RSSIMonitorCheck23aCE(pDM_Odm);
1307} /* odm_RSSIMonitorCheck23a */ 1242} /* odm_RSSIMonitorCheck23a */
1308 1243
1309void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm)
1310{
1311}
1312
1313static void 1244static void
1314FindMinimumRSSI( 1245FindMinimumRSSI(
1315 struct rtw_adapter *pAdapter 1246 struct rtw_adapter *pAdapter
@@ -1378,10 +1309,6 @@ void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm)
1378 ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); 1309 ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM);
1379} 1310}
1380 1311
1381void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm)
1382{
1383}
1384
1385/* endif */ 1312/* endif */
1386/* 3 ============================================================ */ 1313/* 3 ============================================================ */
1387/* 3 Tx Power Tracking */ 1314/* 3 Tx Power Tracking */
@@ -1422,19 +1349,12 @@ void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm)
1422{ 1349{
1423} 1350}
1424 1351
1425void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm)
1426{
1427}
1428
1429void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm)
1430{
1431}
1432
1433/* EDCA Turbo */ 1352/* EDCA Turbo */
1434static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) 1353static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
1435{ 1354{
1436 1355
1437 struct rtw_adapter *Adapter = pDM_Odm->Adapter; 1356 struct rtw_adapter *Adapter = pDM_Odm->Adapter;
1357
1438 pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; 1358 pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
1439 pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; 1359 pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false;
1440 Adapter->recvpriv.bIsAnyNonBEPkts = false; 1360 Adapter->recvpriv.bIsAnyNonBEPkts = false;
@@ -1591,6 +1511,7 @@ ConvertTo_dB23a(
1591void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm) 1511void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm)
1592{ 1512{
1593 struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; 1513 struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
1514
1594 pDM_SWAT_Table->ANTA_ON = true; 1515 pDM_SWAT_Table->ANTA_ON = true;
1595 pDM_SWAT_Table->ANTB_ON = true; 1516 pDM_SWAT_Table->ANTB_ON = true;
1596} 1517}
diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
index fb3cc872f205..33aafa01f900 100644
--- a/drivers/staging/rtl8723au/hal/odm_HWConfig.c
+++ b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
@@ -113,7 +113,7 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm,
113 113
114 cck_highpwr = pDM_Odm->bCckHighPower; 114 cck_highpwr = pDM_Odm->bCckHighPower;
115 115
116 cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ; 116 cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
117 117
118 /* The RSSI formula should be modified according to the gain table */ 118 /* The RSSI formula should be modified according to the gain table */
119 if (!cck_highpwr) { 119 if (!cck_highpwr) {
@@ -138,16 +138,16 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm,
138 report = (cck_agc_rpt & 0x60)>>5; 138 report = (cck_agc_rpt & 0x60)>>5;
139 switch (report) { 139 switch (report) {
140 case 0x3: 140 case 0x3:
141 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1) ; 141 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1);
142 break; 142 break;
143 case 0x2: 143 case 0x2:
144 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1); 144 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1);
145 break; 145 break;
146 case 0x1: 146 case 0x1:
147 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1) ; 147 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1);
148 break; 148 break;
149 case 0x0: 149 case 0x0:
150 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1) ; 150 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1);
151 break; 151 break;
152 } 152 }
153 } 153 }
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
index 86a83975f4f0..73cfddd6df9a 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
@@ -7255,63 +7255,19 @@ btdm_2AntTdmaDurationAdjust(struct rtw_adapter *padapter, u8 bScoHid,
7255 RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); 7255 RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
7256 if (bScoHid) { 7256 if (bScoHid) {
7257 if (bTxPause) { 7257 if (bTxPause) {
7258 if (maxInterval == 1) { 7258 btdm_2AntPsTdma(padapter, true, 15);
7259 btdm_2AntPsTdma(padapter, true, 15); 7259 pBtdm8723->psTdmaDuAdjType = 15;
7260 pBtdm8723->psTdmaDuAdjType = 15;
7261 } else if (maxInterval == 2) {
7262 btdm_2AntPsTdma(padapter, true, 15);
7263 pBtdm8723->psTdmaDuAdjType = 15;
7264 } else if (maxInterval == 3) {
7265 btdm_2AntPsTdma(padapter, true, 15);
7266 pBtdm8723->psTdmaDuAdjType = 15;
7267 } else {
7268 btdm_2AntPsTdma(padapter, true, 15);
7269 pBtdm8723->psTdmaDuAdjType = 15;
7270 }
7271 } else { 7260 } else {
7272 if (maxInterval == 1) { 7261 btdm_2AntPsTdma(padapter, true, 11);
7273 btdm_2AntPsTdma(padapter, true, 11); 7262 pBtdm8723->psTdmaDuAdjType = 11;
7274 pBtdm8723->psTdmaDuAdjType = 11;
7275 } else if (maxInterval == 2) {
7276 btdm_2AntPsTdma(padapter, true, 11);
7277 pBtdm8723->psTdmaDuAdjType = 11;
7278 } else if (maxInterval == 3) {
7279 btdm_2AntPsTdma(padapter, true, 11);
7280 pBtdm8723->psTdmaDuAdjType = 11;
7281 } else {
7282 btdm_2AntPsTdma(padapter, true, 11);
7283 pBtdm8723->psTdmaDuAdjType = 11;
7284 }
7285 } 7263 }
7286 } else { 7264 } else {
7287 if (bTxPause) { 7265 if (bTxPause) {
7288 if (maxInterval == 1) { 7266 btdm_2AntPsTdma(padapter, true, 7);
7289 btdm_2AntPsTdma(padapter, true, 7); 7267 pBtdm8723->psTdmaDuAdjType = 7;
7290 pBtdm8723->psTdmaDuAdjType = 7;
7291 } else if (maxInterval == 2) {
7292 btdm_2AntPsTdma(padapter, true, 7);
7293 pBtdm8723->psTdmaDuAdjType = 7;
7294 } else if (maxInterval == 3) {
7295 btdm_2AntPsTdma(padapter, true, 7);
7296 pBtdm8723->psTdmaDuAdjType = 7;
7297 } else {
7298 btdm_2AntPsTdma(padapter, true, 7);
7299 pBtdm8723->psTdmaDuAdjType = 7;
7300 }
7301 } else { 7268 } else {
7302 if (maxInterval == 1) { 7269 btdm_2AntPsTdma(padapter, true, 3);
7303 btdm_2AntPsTdma(padapter, true, 3); 7270 pBtdm8723->psTdmaDuAdjType = 3;
7304 pBtdm8723->psTdmaDuAdjType = 3;
7305 } else if (maxInterval == 2) {
7306 btdm_2AntPsTdma(padapter, true, 3);
7307 pBtdm8723->psTdmaDuAdjType = 3;
7308 } else if (maxInterval == 3) {
7309 btdm_2AntPsTdma(padapter, true, 3);
7310 pBtdm8723->psTdmaDuAdjType = 3;
7311 } else {
7312 btdm_2AntPsTdma(padapter, true, 3);
7313 pBtdm8723->psTdmaDuAdjType = 3;
7314 }
7315 } 7271 }
7316 } 7272 }
7317 up = 0; 7273 up = 0;
@@ -9145,7 +9101,7 @@ u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter)
9145 u32 counters = 0; 9101 u32 counters = 0;
9146 9102
9147 counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+ 9103 counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+
9148 pHalData->bt_coexist.halCoex8723.lowPriorityRx ; 9104 pHalData->bt_coexist.halCoex8723.lowPriorityRx;
9149 return counters; 9105 return counters;
9150} 9106}
9151 9107
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
index 88e91cd8ebb9..19dc5e3b2e2e 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
@@ -698,7 +698,7 @@ storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr,
698 * 11/10/2008 tynli Modify to mew files. 698 * 11/10/2008 tynli Modify to mew files.
699 *---------------------------------------------------------------------------*/ 699 *---------------------------------------------------------------------------*/
700static int 700static int
701phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter, u8 ConfigType) 701phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter)
702{ 702{
703 int i; 703 int i;
704 u32 *Rtl819XPHY_REGArray_Table_PG; 704 u32 *Rtl819XPHY_REGArray_Table_PG;
@@ -707,17 +707,15 @@ phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter, u8 ConfigType)
707 PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength; 707 PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength;
708 Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG; 708 Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG;
709 709
710 if (ConfigType == BaseBand_Config_PHY_REG) { 710 for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) {
711 for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) { 711 storePwrIndexDiffRateOffset(Adapter,
712 storePwrIndexDiffRateOffset(Adapter, 712 Rtl819XPHY_REGArray_Table_PG[i],
713 Rtl819XPHY_REGArray_Table_PG[i], 713 Rtl819XPHY_REGArray_Table_PG[i+1],
714 Rtl819XPHY_REGArray_Table_PG[i+1], 714 Rtl819XPHY_REGArray_Table_PG[i+2]);
715 Rtl819XPHY_REGArray_Table_PG[i+2]);
716 }
717 } 715 }
718 716
719 return _SUCCESS; 717 return _SUCCESS;
720} /* phy_ConfigBBWithPgHeaderFile */ 718}
721 719
722static void 720static void
723phy_BB8192C_Config_1T(struct rtw_adapter *Adapter) 721phy_BB8192C_Config_1T(struct rtw_adapter *Adapter)
@@ -768,8 +766,7 @@ phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
768 if (pEEPROM->bautoload_fail_flag == false) { 766 if (pEEPROM->bautoload_fail_flag == false) {
769 pHalData->pwrGroupCnt = 0; 767 pHalData->pwrGroupCnt = 0;
770 768
771 rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter, 769 rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter);
772 BaseBand_Config_PHY_REG);
773 } 770 }
774 771
775 if (rtStatus != _SUCCESS) 772 if (rtStatus != _SUCCESS)
@@ -923,9 +920,6 @@ _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
923 u8 regBwOpMode; 920 u8 regBwOpMode;
924 u8 regRRSR_RSC; 921 u8 regRRSR_RSC;
925 922
926 if (pHalData->rf_chip == RF_PSEUDO_11N)
927 return;
928
929 /* There is no 40MHz mode in RF_8225. */ 923 /* There is no 40MHz mode in RF_8225. */
930 if (pHalData->rf_chip == RF_8225) 924 if (pHalData->rf_chip == RF_8225)
931 return; 925 return;
@@ -1021,10 +1015,6 @@ _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
1021 /* PHY_SetRF8258Bandwidth(); */ 1015 /* PHY_SetRF8258Bandwidth(); */
1022 break; 1016 break;
1023 1017
1024 case RF_PSEUDO_11N:
1025 /* Do Nothing */
1026 break;
1027
1028 case RF_6052: 1018 case RF_6052:
1029 rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW); 1019 rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
1030 break; 1020 break;
@@ -1074,7 +1064,7 @@ PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
1074 1064
1075static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel) 1065static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
1076{ 1066{
1077 u8 eRFPath; 1067 enum RF_RADIO_PATH eRFPath;
1078 u32 param1, param2; 1068 u32 param1, param2;
1079 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); 1069 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1080 1070
@@ -1088,7 +1078,7 @@ static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
1088 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { 1078 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
1089 pHalData->RfRegChnlVal[eRFPath] = 1079 pHalData->RfRegChnlVal[eRFPath] =
1090 (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2; 1080 (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
1091 PHY_SetRFReg(Adapter, (enum RF_RADIO_PATH)eRFPath, param1, 1081 PHY_SetRFReg(Adapter, eRFPath, param1,
1092 bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); 1082 bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
1093 } 1083 }
1094 1084
@@ -1101,11 +1091,6 @@ void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
1101 u8 tmpchannel = pHalData->CurrentChannel; 1091 u8 tmpchannel = pHalData->CurrentChannel;
1102 bool result = true; 1092 bool result = true;
1103 1093
1104 if (pHalData->rf_chip == RF_PSEUDO_11N) {
1105 /* return immediately if it is peudo-phy */
1106 return;
1107 }
1108
1109 if (channel == 0) 1094 if (channel == 0)
1110 channel = 1; 1095 channel = 1;
1111 1096
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
index 6070510bb470..1759487329ab 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
@@ -79,7 +79,7 @@ static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxd
79 } 79 }
80} 80}
81 81
82static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw) 82static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
83{ 83{
84 /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */ 84 /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */
85 85
@@ -114,7 +114,7 @@ static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
114 } 114 }
115} 115}
116 116
117static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw) 117static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw)
118{ 118{
119 if (pattrib->ht_en) { 119 if (pattrib->ht_en) {
120 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0; 120 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c
index febe5cedef8f..adbf1c2dd383 100644
--- a/drivers/staging/rtl8723au/hal/usb_halinit.c
+++ b/drivers/staging/rtl8723au/hal/usb_halinit.c
@@ -625,10 +625,10 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter)
625 } 625 }
626 626
627 /* reducing 80M spur */ 627 /* reducing 80M spur */
628 PHY_SetBBReg(Adapter, RF_T_METER, bMaskDWord, 0x0381808d); 628 PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, bMaskDWord, 0x0381808d);
629 PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83); 629 PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff83);
630 PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff82); 630 PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff82);
631 PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83); 631 PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff83);
632 632
633 /* RFSW Control */ 633 /* RFSW Control */
634 PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003); /* 0x804[14]= 0 */ 634 PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003); /* 0x804[14]= 0 */
@@ -640,8 +640,10 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter)
640 /* */ 640 /* */
641 /* Joseph Note: Keep RfRegChnlVal for later use. */ 641 /* Joseph Note: Keep RfRegChnlVal for later use. */
642 /* */ 642 /* */
643 pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)0, RF_CHNLBW, bRFRegOffsetMask); 643 pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, RF_PATH_A,
644 pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)1, RF_CHNLBW, bRFRegOffsetMask); 644 RF_CHNLBW, bRFRegOffsetMask);
645 pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, RF_PATH_B,
646 RF_CHNLBW, bRFRegOffsetMask);
645 647
646 if (!mac_on) { 648 if (!mac_on) {
647 _InitQueueReservedPage(Adapter); 649 _InitQueueReservedPage(Adapter);
diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
index 688f20412bca..2247d9874719 100644
--- a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
+++ b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
@@ -17,46 +17,9 @@
17#define __INC_HAL8723PHYCFG_H__ 17#define __INC_HAL8723PHYCFG_H__
18 18
19/*--------------------------Define Parameters-------------------------------*/ 19/*--------------------------Define Parameters-------------------------------*/
20#define LOOP_LIMIT 5
21#define MAX_STALL_TIME 50 /* us */
22#define AntennaDiversityValue 0x80
23#define MAX_TXPWR_IDX_NMODE_92S 63
24#define Reset_Cnt_Limit 3
25
26
27#define MAX_AGGR_NUM 0x0909 20#define MAX_AGGR_NUM 0x0909
28 21
29/*--------------------------Define Parameters-------------------------------*/
30
31
32/*------------------------------Define structure----------------------------*/ 22/*------------------------------Define structure----------------------------*/
33enum swchnlcmdid {
34 CmdID_End,
35 CmdID_SetTxPowerLevel,
36 CmdID_BBRegWrite10,
37 CmdID_WritePortUlong,
38 CmdID_WritePortUshort,
39 CmdID_WritePortUchar,
40 CmdID_RF_WriteReg,
41};
42
43
44/* 1. Switch channel related */
45struct swchnlcmd {
46 enum swchnlcmdid CmdID;
47 u32 Para1;
48 u32 Para2;
49 u32 msDelay;
50};
51
52enum HW90_BLOCK {
53 HW90_BLOCK_MAC = 0,
54 HW90_BLOCK_PHY0 = 1,
55 HW90_BLOCK_PHY1 = 2,
56 HW90_BLOCK_RF = 3,
57 HW90_BLOCK_MAXIMUM = 4, /* Never use this */
58};
59
60enum RF_RADIO_PATH { 23enum RF_RADIO_PATH {
61 RF_PATH_A = 0, /* Radio Path A */ 24 RF_PATH_A = 0, /* Radio Path A */
62 RF_PATH_B = 1, /* Radio Path B */ 25 RF_PATH_B = 1, /* Radio Path B */
@@ -64,7 +27,6 @@ enum RF_RADIO_PATH {
64}; 27};
65 28
66#define CHANNEL_MAX_NUMBER 14 /* 14 is the max channel number */ 29#define CHANNEL_MAX_NUMBER 14 /* 14 is the max channel number */
67#define CHANNEL_GROUP_MAX 3 /* ch1~3, ch4~9, ch10~14 total three groups */
68 30
69enum WIRELESS_MODE { 31enum WIRELESS_MODE {
70 WIRELESS_MODE_UNKNOWN = 0x00, 32 WIRELESS_MODE_UNKNOWN = 0x00,
@@ -77,22 +39,6 @@ enum WIRELESS_MODE {
77 WIRELESS_MODE_AC = BIT(6) 39 WIRELESS_MODE_AC = BIT(6)
78}; 40};
79 41
80enum baseband_config_type {
81 BaseBand_Config_PHY_REG = 0, /* Radio Path A */
82 BaseBand_Config_AGC_TAB = 1, /* Radio Path B */
83};
84
85enum ra_offset_area {
86 RA_OFFSET_LEGACY_OFDM1,
87 RA_OFFSET_LEGACY_OFDM2,
88 RA_OFFSET_HT_OFDM1,
89 RA_OFFSET_HT_OFDM2,
90 RA_OFFSET_HT_OFDM3,
91 RA_OFFSET_HT_OFDM4,
92 RA_OFFSET_HT_CCK,
93};
94
95
96/* BB/RF related */ 42/* BB/RF related */
97enum rf_type_8190p { 43enum rf_type_8190p {
98 RF_TYPE_MIN, /* 0 */ 44 RF_TYPE_MIN, /* 0 */
@@ -100,7 +46,6 @@ enum rf_type_8190p {
100 RF_8256 = 2, /* 2 11b/g/n */ 46 RF_8256 = 2, /* 2 11b/g/n */
101 RF_8258 = 3, /* 3 11a/b/g/n RF */ 47 RF_8258 = 3, /* 3 11a/b/g/n RF */
102 RF_6052 = 4, /* 4 11b/g/n RF */ 48 RF_6052 = 4, /* 4 11b/g/n RF */
103 RF_PSEUDO_11N = 5, /* 5, It is a temporality RF. */
104}; 49};
105 50
106struct bb_reg_define { 51struct bb_reg_define {
diff --git a/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h b/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
index 4a1f58f2982c..3771d6bb5774 100644
--- a/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
+++ b/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
@@ -39,10 +39,10 @@
39 * { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here 39 * { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here
40 */ 40 */
41#define RTL8723A_TRANS_CARDEMU_TO_ACT \ 41#define RTL8723A_TRANS_CARDEMU_TO_ACT \
42 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ 42 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \
43 {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ 43 {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \
44 {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \ 44 {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \
45 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, /*0x00[5] = 1b'0 release analog Ips to digital , 1:isolation*/ \ 45 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, /*0x00[5] = 1b'0 release analog Ips to digital , 1:isolation*/ \
46 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0},/* disable SW LPS 0x04[10]= 0*/ \ 46 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0},/* disable SW LPS 0x04[10]= 0*/ \
47 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},/* wait till 0x04[17] = 1 power ready*/ \ 47 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},/* wait till 0x04[17] = 1 power ready*/ \
48 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},/* release WLON reset 0x04[16]= 1*/ \ 48 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},/* release WLON reset 0x04[16]= 1*/ \
@@ -57,48 +57,28 @@
57 {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\ 57 {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\
58 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ 58 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \
59 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ 59 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \
60 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, /*0x00[5] = 1b'1 analog Ips to digital , 1:isolation*/ \ 60 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, /*0x00[5] = 1b'1 analog Ips to digital , 1:isolation*/ \
61 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \ 61 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \
62 62
63 63
64#define RTL8723A_TRANS_CARDEMU_TO_SUS \ 64#define RTL8723A_TRANS_CARDEMU_TO_SUS \
65 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), (BIT(4)|BIT(3))}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ 65 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/
66 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \
67 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \
68 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \
69 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \
70 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/ \
71 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
72 66
73#define RTL8723A_TRANS_SUS_TO_CARDEMU \ 67#define RTL8723A_TRANS_SUS_TO_CARDEMU \
74 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/ \ 68 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/ \
75 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \
76 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\
77 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \
78 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ 69 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
79 70
80#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \ 71#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \
81 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07 = 0x20 , SOP option to disable BG/MB*/ \ 72 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \
82 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ 73 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/
83 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, /*0x04[10] = 1, enable SW LPS*/ \
84 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \
85 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \
86 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/ \
87 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
88 74
89#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \ 75#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \
90 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/ \ 76 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/ \
91 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \
92 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\
93 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ 77 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \
94 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ 78 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
95 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \
96 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/
97
98 79
99#define RTL8723A_TRANS_CARDEMU_TO_PDN \ 80#define RTL8723A_TRANS_CARDEMU_TO_PDN \
100 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ 81 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \
101 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \
102 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\ 82 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\
103 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/ 83 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/
104 84
@@ -106,7 +86,6 @@
106 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/ 86 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/
107 87
108#define RTL8723A_TRANS_ACT_TO_LPS \ 88#define RTL8723A_TRANS_ACT_TO_LPS \
109 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \
110 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ 89 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \
111 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ 90 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \
112 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ 91 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \
@@ -117,13 +96,10 @@
117 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*Whole BB is reset*/ \ 96 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*Whole BB is reset*/ \
118 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ 97 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \
119 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/ \ 98 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/ \
120 {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \
121 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},/*Respond TxOK to scheduler*/ 99 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},/*Respond TxOK to scheduler*/
122 100
123#define RTL8723A_TRANS_LPS_TO_ACT \ 101#define RTL8723A_TRANS_LPS_TO_ACT \
124 {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\
125 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ 102 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\
126 {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\
127 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ 103 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\
128 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ 104 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\
129 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]= 0 TSF in 40M*/\ 105 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]= 0 TSF in 40M*/\
diff --git a/drivers/staging/rtl8723au/include/osdep_intf.h b/drivers/staging/rtl8723au/include/osdep_intf.h
index 33afa62f31b1..a157eb2e78df 100644
--- a/drivers/staging/rtl8723au/include/osdep_intf.h
+++ b/drivers/staging/rtl8723au/include/osdep_intf.h
@@ -19,9 +19,6 @@
19#include <osdep_service.h> 19#include <osdep_service.h>
20#include <drv_types.h> 20#include <drv_types.h>
21 21
22int rtw_hw_suspend23a(struct rtw_adapter *padapter);
23int rtw_hw_resume23a(struct rtw_adapter *padapter);
24
25int rtw_init_drv_sw23a(struct rtw_adapter *padapter); 22int rtw_init_drv_sw23a(struct rtw_adapter *padapter);
26int rtw_free_drv_sw23a(struct rtw_adapter *padapter); 23int rtw_free_drv_sw23a(struct rtw_adapter *padapter);
27int rtw_reset_drv_sw23a(struct rtw_adapter *padapter); 24int rtw_reset_drv_sw23a(struct rtw_adapter *padapter);
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h b/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
index 05069652bae1..7add5dfe015f 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
@@ -31,8 +31,8 @@ enum rt_media_status {
31 31
32void BT_SignalCompensation(struct rtw_adapter *padapter, 32void BT_SignalCompensation(struct rtw_adapter *padapter,
33 u8 *rssi_wifi, u8 *rssi_bt); 33 u8 *rssi_wifi, u8 *rssi_bt);
34void BT_HaltProcess(struct rtw_adapter * padapter); 34void BT_HaltProcess(struct rtw_adapter *padapter);
35void BT_LpsLeave(struct rtw_adapter * padapter); 35void BT_LpsLeave(struct rtw_adapter *padapter);
36 36
37 37
38#define BT_HsConnectionEstablished(Adapter) false 38#define BT_HsConnectionEstablished(Adapter) false
@@ -1092,17 +1092,20 @@ enum hci_ext_bp_operation {
1092 BTHCI_StateMachine(_Adapter, _StateToEnter, _StateCmd, _EntryNum);\ 1092 BTHCI_StateMachine(_Adapter, _StateToEnter, _StateCmd, _EntryNum);\
1093} 1093}
1094 1094
1095void BTHCI_EventParse(struct rtw_adapter * padapter, void *pEvntData, u32 dataLen); 1095void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData,
1096 u32 dataLen);
1096#define BT_EventParse BTHCI_EventParse 1097#define BT_EventParse BTHCI_EventParse
1097u8 BTHCI_HsConnectionEstablished(struct rtw_adapter * padapter); 1098u8 BTHCI_HsConnectionEstablished(struct rtw_adapter *padapter);
1098void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter * padapter); 1099void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter *padapter);
1099void BTHCI_WifiScanNotify(struct rtw_adapter * padapter, u8 scanType); 1100void BTHCI_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType);
1100void BTHCI_StateMachine(struct rtw_adapter * padapter, u8 StateToEnter, enum hci_state_with_cmd StateCmd, u8 EntryNum); 1101void BTHCI_StateMachine(struct rtw_adapter *padapter, u8 StateToEnter,
1101void BTHCI_DisconnectPeer(struct rtw_adapter * padapter, u8 EntryNum); 1102 enum hci_state_with_cmd StateCmd, u8 EntryNum);
1102void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter * padapter); 1103void BTHCI_DisconnectPeer(struct rtw_adapter *padapter, u8 EntryNum);
1103void BTHCI_EventAMPStatusChange(struct rtw_adapter * padapter, u8 AMP_Status); 1104void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter *padapter);
1104void BTHCI_DisconnectAll(struct rtw_adapter * padapter); 1105void BTHCI_EventAMPStatusChange(struct rtw_adapter *padapter, u8 AMP_Status);
1105enum hci_status BTHCI_HandleHCICMD(struct rtw_adapter * padapter, struct packet_irp_hcicmd_data *pHciCmd); 1106void BTHCI_DisconnectAll(struct rtw_adapter *padapter);
1107enum hci_status BTHCI_HandleHCICMD(struct rtw_adapter *padapter,
1108 struct packet_irp_hcicmd_data *pHciCmd);
1106 1109
1107/* ===== End of sync from SD7 driver COMMON/bt_hci.h ===== */ 1110/* ===== End of sync from SD7 driver COMMON/bt_hci.h ===== */
1108 1111
@@ -1157,9 +1160,10 @@ struct btdm_8723a_1ant {
1157 u8 bRAChanged; 1160 u8 bRAChanged;
1158}; 1161};
1159 1162
1160void BTDM_1AntSignalCompensation(struct rtw_adapter * padapter, u8 *rssi_wifi, u8 *rssi_bt); 1163void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
1161void BTDM_1AntForDhcp(struct rtw_adapter * padapter); 1164 u8 *rssi_wifi, u8 *rssi_bt);
1162void BTDM_1AntBtCoexist8723A(struct rtw_adapter * padapter); 1165void BTDM_1AntForDhcp(struct rtw_adapter *padapter);
1166void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter);
1163 1167
1164/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.h ===== */ 1168/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.h ===== */
1165 1169
@@ -1241,7 +1245,7 @@ struct btdm_8723a_2ant {
1241 u8 btStatus; 1245 u8 btStatus;
1242}; 1246};
1243 1247
1244void BTDM_2AntBtCoexist8723A(struct rtw_adapter * padapter); 1248void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter);
1245/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.h ===== */ 1249/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.h ===== */
1246 1250
1247/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */ 1251/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */
@@ -1310,15 +1314,17 @@ struct bt_coexist_8723a {
1310 struct btdm_8723a_1ant btdm1Ant; 1314 struct btdm_8723a_1ant btdm1Ant;
1311}; 1315};
1312 1316
1313void BTDM_SetFwChnlInfo(struct rtw_adapter * padapter, enum rt_media_status mstatus); 1317void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter,
1314u8 BTDM_IsWifiConnectionExist(struct rtw_adapter * padapter); 1318 enum rt_media_status mstatus);
1315void BTDM_SetFw3a(struct rtw_adapter * padapter, u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5); 1319u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter);
1316void BTDM_QueryBtInformation(struct rtw_adapter * padapter); 1320void BTDM_SetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2, u8 byte3,
1317void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter * padapter, u8 type); 1321 u8 byte4, u8 byte5);
1318void BTDM_SetSwPenaltyTxRateAdaptive(struct rtw_adapter * padapter, u8 raType); 1322void BTDM_QueryBtInformation(struct rtw_adapter *padapter);
1319void BTDM_SetFwDecBtPwr(struct rtw_adapter * padapter, u8 bDecBtPwr); 1323void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type);
1320u8 BTDM_BtProfileSupport(struct rtw_adapter * padapter); 1324void BTDM_SetSwPenaltyTxRateAdaptive(struct rtw_adapter *padapter, u8 raType);
1321void BTDM_LpsLeave(struct rtw_adapter * padapter); 1325void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr);
1326u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter);
1327void BTDM_LpsLeave(struct rtw_adapter *padapter);
1322 1328
1323/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */ 1329/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */
1324 1330
@@ -1340,8 +1346,9 @@ enum BT_A2DP_INDEX{
1340#define BTDM_ANT_BT 2 1346#define BTDM_ANT_BT 2
1341 1347
1342 1348
1343void BTDM_SingleAnt(struct rtw_adapter * padapter, u8 bSingleAntOn, u8 bInterruptOn, u8 bMultiNAVOn); 1349void BTDM_SingleAnt(struct rtw_adapter *padapter, u8 bSingleAntOn,
1344void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter * padapter); 1350 u8 bInterruptOn, u8 bMultiNAVOn);
1351void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter);
1345 1352
1346/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.h ===== */ 1353/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.h ===== */
1347 1354
@@ -1361,7 +1368,8 @@ void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter * padapter);
1361#define BT_DACSWING_M7 2 1368#define BT_DACSWING_M7 2
1362#define BT_DACSWING_M10 3 1369#define BT_DACSWING_M10 3
1363 1370
1364void BTDM_DiminishWiFi(struct rtw_adapter * Adapter, u8 bDACOn, u8 bInterruptOn, u8 DACSwingLevel, u8 bNAVOn); 1371void BTDM_DiminishWiFi(struct rtw_adapter *Adapter, u8 bDACOn, u8 bInterruptOn,
1372 u8 DACSwingLevel, u8 bNAVOn);
1365 1373
1366/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.h ===== */ 1374/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.h ===== */
1367 1375
@@ -1534,58 +1542,63 @@ struct bt_coexist_str {
1534 u8 fw3aVal[5]; 1542 u8 fw3aVal[5];
1535}; 1543};
1536 1544
1537void BTDM_CheckAntSelMode(struct rtw_adapter * padapter); 1545void BTDM_CheckAntSelMode(struct rtw_adapter *padapter);
1538void BTDM_FwC2hBtRssi(struct rtw_adapter * padapter, u8 *tmpBuf); 1546void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf);
1539#define BT_FwC2hBtRssi BTDM_FwC2hBtRssi 1547#define BT_FwC2hBtRssi BTDM_FwC2hBtRssi
1540void BTDM_DisplayBtCoexInfo(struct rtw_adapter * padapter); 1548void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter);
1541#define BT_DisplayBtCoexInfo BTDM_DisplayBtCoexInfo 1549#define BT_DisplayBtCoexInfo BTDM_DisplayBtCoexInfo
1542void BTDM_RejectAPAggregatedPacket(struct rtw_adapter * padapter, u8 bReject); 1550void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject);
1543u8 BTDM_IsHT40(struct rtw_adapter * padapter); 1551u8 BTDM_IsHT40(struct rtw_adapter *padapter);
1544u8 BTDM_Legacy(struct rtw_adapter * padapter); 1552u8 BTDM_Legacy(struct rtw_adapter *padapter);
1545void BTDM_CheckWiFiState(struct rtw_adapter * padapter); 1553void BTDM_CheckWiFiState(struct rtw_adapter *padapter);
1546s32 BTDM_GetRxSS(struct rtw_adapter * padapter); 1554s32 BTDM_GetRxSS(struct rtw_adapter *padapter);
1547u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter * padapter, u8 levelNum, u8 RssiThresh, u8 RssiThresh1); 1555u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum,
1548u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter * padapter, u8 levelNum, u8 RssiThresh, u8 RssiThresh1); 1556 u8 RssiThresh, u8 RssiThresh1);
1549u8 BTDM_CheckCoexRSSIState(struct rtw_adapter * padapter, u8 levelNum, u8 RssiThresh, u8 RssiThresh1); 1557u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum,
1550void BTDM_Balance(struct rtw_adapter * padapter, u8 bBalanceOn, u8 ms0, u8 ms1); 1558 u8 RssiThresh, u8 RssiThresh1);
1551void BTDM_AGCTable(struct rtw_adapter * padapter, u8 type); 1559u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum,
1552void BTDM_BBBackOffLevel(struct rtw_adapter * padapter, u8 type); 1560 u8 RssiThresh, u8 RssiThresh1);
1553void BTDM_FWCoexAllOff(struct rtw_adapter * padapter); 1561void BTDM_Balance(struct rtw_adapter *padapter, u8 bBalanceOn, u8 ms0, u8 ms1);
1554void BTDM_SWCoexAllOff(struct rtw_adapter * padapter); 1562void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type);
1555void BTDM_HWCoexAllOff(struct rtw_adapter * padapter); 1563void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type);
1556void BTDM_CoexAllOff(struct rtw_adapter * padapter); 1564void BTDM_FWCoexAllOff(struct rtw_adapter *padapter);
1557void BTDM_TurnOffBtCoexistBeforeEnterIPS(struct rtw_adapter * padapter); 1565void BTDM_SWCoexAllOff(struct rtw_adapter *padapter);
1558void BTDM_SignalCompensation(struct rtw_adapter * padapter, u8 *rssi_wifi, u8 *rssi_bt); 1566void BTDM_HWCoexAllOff(struct rtw_adapter *padapter);
1559void BTDM_UpdateCoexState(struct rtw_adapter * padapter); 1567void BTDM_CoexAllOff(struct rtw_adapter *padapter);
1560u8 BTDM_IsSameCoexistState(struct rtw_adapter * padapter); 1568void BTDM_TurnOffBtCoexistBeforeEnterIPS(struct rtw_adapter *padapter);
1561void BTDM_PWDBMonitor(struct rtw_adapter * padapter); 1569void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi,
1562u8 BTDM_IsBTBusy(struct rtw_adapter * padapter); 1570 u8 *rssi_bt);
1571void BTDM_UpdateCoexState(struct rtw_adapter *padapter);
1572u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter);
1573void BTDM_PWDBMonitor(struct rtw_adapter *padapter);
1574u8 BTDM_IsBTBusy(struct rtw_adapter *padapter);
1563#define BT_IsBtBusy BTDM_IsBTBusy 1575#define BT_IsBtBusy BTDM_IsBTBusy
1564u8 BTDM_IsWifiBusy(struct rtw_adapter * padapter); 1576u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter);
1565u8 BTDM_IsCoexistStateChanged(struct rtw_adapter * padapter); 1577u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter);
1566u8 BTDM_IsWifiUplink(struct rtw_adapter * padapter); 1578u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter);
1567u8 BTDM_IsWifiDownlink(struct rtw_adapter * padapter); 1579u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter);
1568u8 BTDM_IsBTHSMode(struct rtw_adapter * padapter); 1580u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter);
1569u8 BTDM_IsBTUplink(struct rtw_adapter * padapter); 1581u8 BTDM_IsBTUplink(struct rtw_adapter *padapter);
1570u8 BTDM_IsBTDownlink(struct rtw_adapter * padapter); 1582u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter);
1571void BTDM_AdjustForBtOperation(struct rtw_adapter * padapter); 1583void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter);
1572void BTDM_ForHalt(struct rtw_adapter * padapter); 1584void BTDM_ForHalt(struct rtw_adapter *padapter);
1573void BTDM_WifiScanNotify(struct rtw_adapter * padapter, u8 scanType); 1585void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType);
1574void BTDM_WifiAssociateNotify(struct rtw_adapter * padapter, u8 action); 1586void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action);
1575void BTDM_MediaStatusNotify(struct rtw_adapter * padapter, enum rt_media_status mstatus); 1587void BTDM_MediaStatusNotify(struct rtw_adapter *padapter,
1576void BTDM_ForDhcp(struct rtw_adapter * padapter); 1588 enum rt_media_status mstatus);
1577void BTDM_ResetActionProfileState(struct rtw_adapter * padapter); 1589void BTDM_ForDhcp(struct rtw_adapter *padapter);
1578void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter * padapter, u8 antNum); 1590void BTDM_ResetActionProfileState(struct rtw_adapter *padapter);
1591void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum);
1579#define BT_SetBtCoexCurrAntNum BTDM_SetBtCoexCurrAntNum 1592#define BT_SetBtCoexCurrAntNum BTDM_SetBtCoexCurrAntNum
1580u8 BTDM_IsActionSCO(struct rtw_adapter * padapter); 1593u8 BTDM_IsActionSCO(struct rtw_adapter *padapter);
1581u8 BTDM_IsActionHID(struct rtw_adapter * padapter); 1594u8 BTDM_IsActionHID(struct rtw_adapter *padapter);
1582u8 BTDM_IsActionA2DP(struct rtw_adapter * padapter); 1595u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter);
1583u8 BTDM_IsActionPAN(struct rtw_adapter * padapter); 1596u8 BTDM_IsActionPAN(struct rtw_adapter *padapter);
1584u8 BTDM_IsActionHIDA2DP(struct rtw_adapter * padapter); 1597u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter);
1585u8 BTDM_IsActionHIDPAN(struct rtw_adapter * padapter); 1598u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter);
1586u8 BTDM_IsActionPANA2DP(struct rtw_adapter * padapter); 1599u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter);
1587u32 BTDM_BtTxRxCounterH(struct rtw_adapter * padapter); 1600u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter);
1588u32 BTDM_BtTxRxCounterL(struct rtw_adapter * padapter); 1601u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter);
1589 1602
1590/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.h ===== */ 1603/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.h ===== */
1591 1604
@@ -1593,14 +1606,14 @@ u32 BTDM_BtTxRxCounterL(struct rtw_adapter * padapter);
1593 1606
1594#define RTS_CTS_NO_LEN_LIMIT 0 1607#define RTS_CTS_NO_LEN_LIMIT 0
1595 1608
1596u8 HALBT_GetPGAntNum(struct rtw_adapter * padapter); 1609u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter);
1597#define BT_GetPGAntNum HALBT_GetPGAntNum 1610#define BT_GetPGAntNum HALBT_GetPGAntNum
1598void HALBT_SetKey(struct rtw_adapter * padapter, u8 EntryNum); 1611void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum);
1599void HALBT_RemoveKey(struct rtw_adapter * padapter, u8 EntryNum); 1612void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum);
1600u8 HALBT_IsBTExist(struct rtw_adapter * padapter); 1613u8 HALBT_IsBTExist(struct rtw_adapter *padapter);
1601#define BT_IsBtExist HALBT_IsBTExist 1614#define BT_IsBtExist HALBT_IsBTExist
1602u8 HALBT_BTChipType(struct rtw_adapter * padapter); 1615u8 HALBT_BTChipType(struct rtw_adapter *padapter);
1603void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter * padapter); 1616void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter);
1604 1617
1605/* ===== End of sync from SD7 driver HAL/HalBT.c ===== */ 1618/* ===== End of sync from SD7 driver HAL/HalBT.c ===== */
1606 1619
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_recv.h b/drivers/staging/rtl8723au/include/rtl8723a_recv.h
index 0177bbc1c1cf..875d37b3b94c 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_recv.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_recv.h
@@ -56,8 +56,8 @@ struct interrupt_msg_format {
56 unsigned int MSG_EX; 56 unsigned int MSG_EX;
57}; 57};
58 58
59int rtl8723au_init_recv_priv(struct rtw_adapter * padapter); 59int rtl8723au_init_recv_priv(struct rtw_adapter *padapter);
60void rtl8723au_free_recv_priv(struct rtw_adapter * padapter); 60void rtl8723au_free_recv_priv(struct rtw_adapter *padapter);
61void rtl8723a_process_phy_info(struct rtw_adapter *padapter, void *prframe); 61void rtl8723a_process_phy_info(struct rtw_adapter *padapter, void *prframe);
62void update_recvframe_attrib(struct recv_frame *precvframe, struct recv_stat *prxstat); 62void update_recvframe_attrib(struct recv_frame *precvframe, struct recv_stat *prxstat);
63void update_recvframe_phyinfo(struct recv_frame *precvframe, struct phy_stat *pphy_info); 63void update_recvframe_phyinfo(struct recv_frame *precvframe, struct phy_stat *pphy_info);
diff --git a/drivers/staging/rtl8723au/include/rtw_cmd.h b/drivers/staging/rtl8723au/include/rtw_cmd.h
index 71044107d13b..775dcdc1e7b9 100644
--- a/drivers/staging/rtl8723au/include/rtw_cmd.h
+++ b/drivers/staging/rtl8723au/include/rtw_cmd.h
@@ -99,7 +99,6 @@ int rtw_init_cmd_priv23a(struct cmd_priv *pcmdpriv);
99 99
100u32 rtw_init_evt_priv23a (struct evt_priv *pevtpriv); 100u32 rtw_init_evt_priv23a (struct evt_priv *pevtpriv);
101void rtw_free_evt_priv23a (struct evt_priv *pevtpriv); 101void rtw_free_evt_priv23a (struct evt_priv *pevtpriv);
102void rtw_cmd_clr_isr23a(struct cmd_priv *pcmdpriv);
103void rtw_evt_notify_isr(struct evt_priv *pevtpriv); 102void rtw_evt_notify_isr(struct evt_priv *pevtpriv);
104 103
105enum rtw_drvextra_cmd_id 104enum rtw_drvextra_cmd_id
@@ -689,10 +688,10 @@ int rtw_disassoc_cmd23a(struct rtw_adapter *padapter, u32 deauth_timeout_ms, boo
689int rtw_setopmode_cmd23a(struct rtw_adapter *padapter, enum nl80211_iftype ifmode); 688int rtw_setopmode_cmd23a(struct rtw_adapter *padapter, enum nl80211_iftype ifmode);
690int rtw_setdatarate_cmd(struct rtw_adapter *padapter, u8 *rateset); 689int rtw_setdatarate_cmd(struct rtw_adapter *padapter, u8 *rateset);
691int rtw_setbasicrate_cmd(struct rtw_adapter *padapter, u8 *rateset); 690int rtw_setbasicrate_cmd(struct rtw_adapter *padapter, u8 *rateset);
692int rtw_setbbreg_cmd(struct rtw_adapter * padapter, u8 offset, u8 val); 691int rtw_setbbreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 val);
693int rtw_setrfreg_cmd(struct rtw_adapter * padapter, u8 offset, u32 val); 692int rtw_setrfreg_cmd(struct rtw_adapter *padapter, u8 offset, u32 val);
694int rtw_getbbreg_cmd(struct rtw_adapter * padapter, u8 offset, u8 * pval); 693int rtw_getbbreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
695int rtw_getrfreg_cmd(struct rtw_adapter * padapter, u8 offset, u8 * pval); 694int rtw_getrfreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
696int rtw_setrfintfs_cmd(struct rtw_adapter *padapter, u8 mode); 695int rtw_setrfintfs_cmd(struct rtw_adapter *padapter, u8 mode);
697int rtw_setrttbl_cmd(struct rtw_adapter *padapter, struct setratable_parm *prate_table); 696int rtw_setrttbl_cmd(struct rtw_adapter *padapter, struct setratable_parm *prate_table);
698int rtw_getrttbl_cmd(struct rtw_adapter *padapter, struct getratable_rsp *pval); 697int rtw_getrttbl_cmd(struct rtw_adapter *padapter, struct getratable_rsp *pval);
@@ -713,7 +712,6 @@ int rtw_ps_cmd23a(struct rtw_adapter*padapter);
713int rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter); 712int rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter);
714#endif 713#endif
715 714
716int rtw_set_ch_cmd23a(struct rtw_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue);
717int rtw_set_chplan_cmd(struct rtw_adapter*padapter, u8 chplan, u8 enqueue); 715int rtw_set_chplan_cmd(struct rtw_adapter*padapter, u8 chplan, u8 enqueue);
718int rtw_led_blink_cmd(struct rtw_adapter*padapter, struct led_8723a *pLed); 716int rtw_led_blink_cmd(struct rtw_adapter*padapter, struct led_8723a *pLed);
719int rtw_set_csa_cmd(struct rtw_adapter*padapter, u8 new_ch_no); 717int rtw_set_csa_cmd(struct rtw_adapter*padapter, u8 new_ch_no);
diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
index 51dba1fa4c5d..ffb37b252fc1 100644
--- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
@@ -509,7 +509,7 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
509 struct ieee80211_mgmt *mgmt, u32 packet_len); 509 struct ieee80211_mgmt *mgmt, u32 packet_len);
510void update_IOT_info23a(struct rtw_adapter *padapter); 510void update_IOT_info23a(struct rtw_adapter *padapter);
511void update_capinfo23a(struct rtw_adapter *Adapter, u16 updateCap); 511void update_capinfo23a(struct rtw_adapter *Adapter, u16 updateCap);
512void update_wireless_mode23a(struct rtw_adapter * padapter); 512void update_wireless_mode23a(struct rtw_adapter *padapter);
513void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 modulation); 513void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 modulation);
514void update_bmc_sta_support_rate23a(struct rtw_adapter *padapter, u32 mac_id); 514void update_bmc_sta_support_rate23a(struct rtw_adapter *padapter, u32 mac_id);
515int update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie, 515int update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie,
diff --git a/drivers/staging/rtl8723au/include/wifi.h b/drivers/staging/rtl8723au/include/wifi.h
index fd3da3b5cf31..25d573c3e232 100644
--- a/drivers/staging/rtl8723au/include/wifi.h
+++ b/drivers/staging/rtl8723au/include/wifi.h
@@ -26,9 +26,9 @@
26------------------------------------------------------------------------------*/ 26------------------------------------------------------------------------------*/
27 27
28struct AC_param { 28struct AC_param {
29 unsigned char ACI_AIFSN; 29 u8 ACI_AIFSN;
30 unsigned char CW; 30 u8 CW;
31 unsigned short TXOP_limit; 31 __le16 TXOP_limit;
32} __packed; 32} __packed;
33 33
34struct WMM_para_element { 34struct WMM_para_element {
@@ -38,10 +38,10 @@ struct WMM_para_element {
38} __packed; 38} __packed;
39 39
40struct ADDBA_request { 40struct ADDBA_request {
41 unsigned char dialog_token; 41 u8 dialog_token;
42 unsigned short BA_para_set; 42 __le16 BA_para_set;
43 unsigned short BA_timeout_value; 43 __le16 BA_timeout_value;
44 unsigned short BA_starting_seqctrl; 44 __le16 BA_starting_seqctrl;
45} __packed; 45} __packed;
46 46
47 47
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
index c5800ae71fcf..537bd8214efe 100644
--- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
@@ -1468,9 +1468,8 @@ static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
1468 return 0; 1468 return 0;
1469 } 1469 }
1470 1470
1471 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) { 1471 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1472 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK; 1472 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
1473 }
1474 1473
1475/* 1474/*
1476 if (wpa_version & NL80211_WPA_VERSION_2) 1475 if (wpa_version & NL80211_WPA_VERSION_2)
diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c
index 9966d16342b3..1b23eb13222b 100644
--- a/drivers/staging/rtl8723au/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c
@@ -91,7 +91,7 @@ static int rtw_bt_iso = 2;/* 0:Low, 1:High, 2:From Efuse */
91/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy */ 91/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy */
92static int rtw_bt_sco = 3; 92static int rtw_bt_sco = 3;
93/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ 93/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
94static int rtw_bt_ampdu = 1 ; 94static int rtw_bt_ampdu = 1;
95#endif 95#endif
96 96
97/* 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */ 97/* 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */
diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c b/drivers/staging/rtl8723au/os_dep/usb_intf.c
index 373a617ace54..05755b870a5f 100644
--- a/drivers/staging/rtl8723au/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8723au/os_dep/usb_intf.c
@@ -80,11 +80,9 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
80 struct usb_config_descriptor *pconf_desc; 80 struct usb_config_descriptor *pconf_desc;
81 struct usb_host_interface *phost_iface; 81 struct usb_host_interface *phost_iface;
82 struct usb_interface_descriptor *piface_desc; 82 struct usb_interface_descriptor *piface_desc;
83 struct usb_host_endpoint *phost_endp;
84 struct usb_endpoint_descriptor *pendp_desc; 83 struct usb_endpoint_descriptor *pendp_desc;
85 struct usb_device *pusbd; 84 struct usb_device *pusbd;
86 int i; 85 int i, status = _FAIL;
87 int status = _FAIL;
88 86
89 pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); 87 pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
90 if (!pdvobjpriv) 88 if (!pdvobjpriv)
@@ -114,42 +112,38 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
114 pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; 112 pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
115 113
116 for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { 114 for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
117 phost_endp = phost_iface->endpoint + i; 115 pendp_desc = &phost_iface->endpoint[i].desc;
118 if (phost_endp) { 116
119 pendp_desc = &phost_endp->desc; 117 DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i);
120 118 DBG_8723A("bLength =%x\n", pendp_desc->bLength);
121 DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i); 119 DBG_8723A("bDescriptorType =%x\n", pendp_desc->bDescriptorType);
122 DBG_8723A("bLength =%x\n", pendp_desc->bLength); 120 DBG_8723A("bEndpointAddress =%x\n",
123 DBG_8723A("bDescriptorType =%x\n", 121 pendp_desc->bEndpointAddress);
124 pendp_desc->bDescriptorType); 122 DBG_8723A("wMaxPacketSize =%d\n",
125 DBG_8723A("bEndpointAddress =%x\n", 123 le16_to_cpu(pendp_desc->wMaxPacketSize));
126 pendp_desc->bEndpointAddress); 124 DBG_8723A("bInterval =%x\n", pendp_desc->bInterval);
127 DBG_8723A("wMaxPacketSize =%d\n", 125
128 le16_to_cpu(pendp_desc->wMaxPacketSize)); 126 if (usb_endpoint_is_bulk_in(pendp_desc)) {
129 DBG_8723A("bInterval =%x\n", pendp_desc->bInterval); 127 DBG_8723A("usb_endpoint_is_bulk_in = %x\n",
130 128 usb_endpoint_num(pendp_desc));
131 if (usb_endpoint_is_bulk_in(pendp_desc)) { 129 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
132 DBG_8723A("usb_endpoint_is_bulk_in = %x\n", 130 usb_endpoint_num(pendp_desc);
133 usb_endpoint_num(pendp_desc)); 131 pdvobjpriv->RtNumInPipes++;
134 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 132 } else if (usb_endpoint_is_int_in(pendp_desc)) {
135 usb_endpoint_num(pendp_desc); 133 DBG_8723A("usb_endpoint_is_int_in = %x, Interval = "
136 pdvobjpriv->RtNumInPipes++; 134 "%x\n", usb_endpoint_num(pendp_desc),
137 } else if (usb_endpoint_is_int_in(pendp_desc)) { 135 pendp_desc->bInterval);
138 DBG_8723A("usb_endpoint_is_int_in = %x, Interval = %x\n", 136 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
139 usb_endpoint_num(pendp_desc), 137 usb_endpoint_num(pendp_desc);
140 pendp_desc->bInterval); 138 pdvobjpriv->RtNumInPipes++;
141 pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = 139 } else if (usb_endpoint_is_bulk_out(pendp_desc)) {
142 usb_endpoint_num(pendp_desc); 140 DBG_8723A("usb_endpoint_is_bulk_out = %x\n",
143 pdvobjpriv->RtNumInPipes++; 141 usb_endpoint_num(pendp_desc));
144 } else if (usb_endpoint_is_bulk_out(pendp_desc)) { 142 pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
145 DBG_8723A("usb_endpoint_is_bulk_out = %x\n", 143 usb_endpoint_num(pendp_desc);
146 usb_endpoint_num(pendp_desc)); 144 pdvobjpriv->RtNumOutPipes++;
147 pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
148 usb_endpoint_num(pendp_desc);
149 pdvobjpriv->RtNumOutPipes++;
150 }
151 pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc);
152 } 145 }
146 pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc);
153 } 147 }
154 DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n", 148 DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n",
155 pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes, 149 pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes,
@@ -273,104 +267,6 @@ static void rtw_dev_unload(struct rtw_adapter *padapter)
273 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); 267 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
274} 268}
275 269
276int rtw_hw_suspend23a(struct rtw_adapter *padapter)
277{
278 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
279 struct net_device *pnetdev = padapter->pnetdev;
280 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
281
282 if ((!padapter->bup) || (padapter->bDriverStopped) ||
283 (padapter->bSurpriseRemoved)) {
284 DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n",
285 padapter->bup, padapter->bDriverStopped,
286 padapter->bSurpriseRemoved);
287 goto error_exit;
288 }
289
290 if (padapter) { /* system suspend */
291 LeaveAllPowerSaveMode23a(padapter);
292
293 DBG_8723A("==> rtw_hw_suspend23a\n");
294 down(&pwrpriv->lock);
295 pwrpriv->bips_processing = true;
296 /* padapter->net_closed = true; */
297 /* s1. */
298 if (pnetdev) {
299 netif_carrier_off(pnetdev);
300 netif_tx_stop_all_queues(pnetdev);
301 }
302
303 /* s2. */
304 rtw_disassoc_cmd23a(padapter, 500, false);
305
306 /* s2-2. indicate disconnect to os */
307 /* rtw_indicate_disconnect23a(padapter); */
308 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
309 _clr_fwstate_(pmlmepriv, _FW_LINKED);
310
311 rtw_os_indicate_disconnect23a(padapter);
312
313 /* donnot enqueue cmd */
314 rtw_lps_ctrl_wk_cmd23a(padapter,
315 LPS_CTRL_DISCONNECT, 0);
316 }
317 /* s2-3. */
318 rtw_free_assoc_resources23a(padapter, 1);
319
320 /* s2-4. */
321 rtw_free_network_queue23a(padapter);
322 rtw_ips_dev_unload23a(padapter);
323 pwrpriv->rf_pwrstate = rf_off;
324 pwrpriv->bips_processing = false;
325 up(&pwrpriv->lock);
326 } else {
327 goto error_exit;
328 }
329 return 0;
330error_exit:
331 DBG_8723A("%s, failed\n", __func__);
332 return -1;
333}
334
335int rtw_hw_resume23a(struct rtw_adapter *padapter)
336{
337 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
338 struct net_device *pnetdev = padapter->pnetdev;
339
340 if (padapter) { /* system resume */
341 DBG_8723A("==> rtw_hw_resume23a\n");
342 down(&pwrpriv->lock);
343 pwrpriv->bips_processing = true;
344 rtw_reset_drv_sw23a(padapter);
345
346 if (pm_netdev_open23a(pnetdev, false)) {
347 up(&pwrpriv->lock);
348 goto error_exit;
349 }
350
351 netif_device_attach(pnetdev);
352 netif_carrier_on(pnetdev);
353
354 if (!rtw_netif_queue_stopped(pnetdev))
355 netif_tx_start_all_queues(pnetdev);
356 else
357 netif_tx_wake_all_queues(pnetdev);
358
359 pwrpriv->bkeepfwalive = false;
360
361 pwrpriv->rf_pwrstate = rf_on;
362 pwrpriv->bips_processing = false;
363
364 up(&pwrpriv->lock);
365 } else {
366 goto error_exit;
367 }
368 return 0;
369error_exit:
370 DBG_8723A("%s, Open net dev failed\n", __func__);
371 return -1;
372}
373
374static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) 270static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
375{ 271{
376 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); 272 struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
index b4612fb615f6..a47a19135d49 100644
--- a/drivers/staging/rts5208/ms.c
+++ b/drivers/staging/rts5208/ms.c
@@ -781,7 +781,7 @@ static int msxc_change_power(struct rtsx_chip *chip, u8 mode)
781 buf[4] = 0; 781 buf[4] = 0;
782 buf[5] = 0; 782 buf[5] = 0;
783 783
784 retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6); 784 retval = ms_write_bytes(chip, PRO_WRITE_REG, 6, NO_WAIT_INT, buf, 6);
785 if (retval != STATUS_SUCCESS) 785 if (retval != STATUS_SUCCESS)
786 TRACE_RET(chip, STATUS_FAIL); 786 TRACE_RET(chip, STATUS_FAIL);
787 787
@@ -1291,7 +1291,7 @@ static int ms_write_extra_data(struct rtsx_chip *chip,
1291 for (i = 6; i < MS_EXTRA_SIZE + 6; i++) 1291 for (i = 6; i < MS_EXTRA_SIZE + 6; i++)
1292 data[i] = buf[i - 6]; 1292 data[i] = buf[i - 6];
1293 1293
1294 retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE), 1294 retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE),
1295 NO_WAIT_INT, data, 16); 1295 NO_WAIT_INT, data, 16);
1296 if (retval != STATUS_SUCCESS) 1296 if (retval != STATUS_SUCCESS)
1297 TRACE_RET(chip, STATUS_FAIL); 1297 TRACE_RET(chip, STATUS_FAIL);
@@ -1342,7 +1342,7 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
1342 data[4] = 0x20; 1342 data[4] = 0x20;
1343 data[5] = page_num; 1343 data[5] = page_num;
1344 1344
1345 retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); 1345 retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
1346 if (retval != STATUS_SUCCESS) 1346 if (retval != STATUS_SUCCESS)
1347 TRACE_RET(chip, STATUS_FAIL); 1347 TRACE_RET(chip, STATUS_FAIL);
1348 1348
@@ -1619,7 +1619,7 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
1619 data[4] = 0x20; 1619 data[4] = 0x20;
1620 data[5] = i; 1620 data[5] = i;
1621 1621
1622 retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, 1622 retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT,
1623 data, 6); 1623 data, 6);
1624 if (retval != STATUS_SUCCESS) 1624 if (retval != STATUS_SUCCESS)
1625 TRACE_RET(chip, STATUS_FAIL); 1625 TRACE_RET(chip, STATUS_FAIL);
@@ -1695,7 +1695,7 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
1695 } 1695 }
1696 1696
1697 retval = ms_set_rw_reg_addr(chip, OverwriteFlag, 1697 retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
1698 MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE)); 1698 MS_EXTRA_SIZE, SystemParm, (6 + MS_EXTRA_SIZE));
1699 1699
1700 ms_set_err_code(chip, MS_NO_ERROR); 1700 ms_set_err_code(chip, MS_NO_ERROR);
1701 1701
@@ -1988,7 +1988,7 @@ RE_SEARCH:
1988 RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); 1988 RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88);
1989 RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); 1989 RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0);
1990 1990
1991 retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1, 1991 retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1,
1992 NO_WAIT_INT); 1992 NO_WAIT_INT);
1993 if (retval != STATUS_SUCCESS) 1993 if (retval != STATUS_SUCCESS)
1994 TRACE_RET(chip, STATUS_FAIL); 1994 TRACE_RET(chip, STATUS_FAIL);
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c
index 756a9687c293..dab1995d1a6a 100644
--- a/drivers/staging/rts5208/rtsx_transport.c
+++ b/drivers/staging/rts5208/rtsx_transport.c
@@ -271,7 +271,7 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout)
271 271
272 /* Wait for TRANS_OK_INT */ 272 /* Wait for TRANS_OK_INT */
273 timeleft = wait_for_completion_interruptible_timeout( 273 timeleft = wait_for_completion_interruptible_timeout(
274 &trans_done, timeout * HZ / 1000); 274 &trans_done, msecs_to_jiffies(timeout));
275 if (timeleft <= 0) { 275 if (timeleft <= 0) {
276 dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", 276 dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
277 chip->int_reg); 277 chip->int_reg);
@@ -431,7 +431,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
431 spin_unlock_irq(&rtsx->reg_lock); 431 spin_unlock_irq(&rtsx->reg_lock);
432 432
433 timeleft = wait_for_completion_interruptible_timeout( 433 timeleft = wait_for_completion_interruptible_timeout(
434 &trans_done, timeout * HZ / 1000); 434 &trans_done, msecs_to_jiffies(timeout));
435 if (timeleft <= 0) { 435 if (timeleft <= 0) {
436 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", 436 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
437 __func__, __LINE__); 437 __func__, __LINE__);
@@ -455,7 +455,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
455 init_completion(&trans_done); 455 init_completion(&trans_done);
456 spin_unlock_irq(&rtsx->reg_lock); 456 spin_unlock_irq(&rtsx->reg_lock);
457 timeleft = wait_for_completion_interruptible_timeout( 457 timeleft = wait_for_completion_interruptible_timeout(
458 &trans_done, timeout * HZ / 1000); 458 &trans_done, msecs_to_jiffies(timeout));
459 if (timeleft <= 0) { 459 if (timeleft <= 0) {
460 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", 460 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
461 __func__, __LINE__); 461 __func__, __LINE__);
@@ -575,7 +575,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
575 spin_unlock_irq(&rtsx->reg_lock); 575 spin_unlock_irq(&rtsx->reg_lock);
576 576
577 timeleft = wait_for_completion_interruptible_timeout( 577 timeleft = wait_for_completion_interruptible_timeout(
578 &trans_done, timeout * HZ / 1000); 578 &trans_done, msecs_to_jiffies(timeout));
579 if (timeleft <= 0) { 579 if (timeleft <= 0) {
580 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", 580 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
581 __func__, __LINE__); 581 __func__, __LINE__);
@@ -602,7 +602,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
602 init_completion(&trans_done); 602 init_completion(&trans_done);
603 spin_unlock_irq(&rtsx->reg_lock); 603 spin_unlock_irq(&rtsx->reg_lock);
604 timeleft = wait_for_completion_interruptible_timeout( 604 timeleft = wait_for_completion_interruptible_timeout(
605 &trans_done, timeout * HZ / 1000); 605 &trans_done, msecs_to_jiffies(timeout));
606 if (timeleft <= 0) { 606 if (timeleft <= 0) {
607 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", 607 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
608 __func__, __LINE__); 608 __func__, __LINE__);
@@ -688,7 +688,7 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf,
688 688
689 /* Wait for TRANS_OK_INT */ 689 /* Wait for TRANS_OK_INT */
690 timeleft = wait_for_completion_interruptible_timeout( 690 timeleft = wait_for_completion_interruptible_timeout(
691 &trans_done, timeout * HZ / 1000); 691 &trans_done, msecs_to_jiffies(timeout));
692 if (timeleft <= 0) { 692 if (timeleft <= 0) {
693 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", 693 dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
694 __func__, __LINE__); 694 __func__, __LINE__);
diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c
index 66261ab25c88..9bd69ce3be00 100644
--- a/drivers/staging/skein/skein_block.c
+++ b/drivers/staging/skein/skein_block.c
@@ -82,10 +82,7 @@ do { \
82} while (0) 82} while (0)
83#else 83#else
84/* looping version */ 84/* looping version */
85#define R256(p0, p1, p2, p3, ROT, r_num) \ 85#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num)
86do { \
87 ROUND256(p0, p1, p2, p3, ROT, r_num); \
88} while (0)
89 86
90#define I256(R) \ 87#define I256(R) \
91do { \ 88do { \
@@ -174,9 +171,7 @@ do { \
174 171
175#else /* looping version */ 172#else /* looping version */
176#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ 173#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
177do { \ 174 ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \
178 ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \
179} while (0)
180 175
181#define I512(R) \ 176#define I512(R) \
182do { \ 177do { \
@@ -263,10 +258,8 @@ do { \
263#if SKEIN_UNROLL_1024 == 0 258#if SKEIN_UNROLL_1024 == 0
264#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ 259#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
265 ROT, rn) \ 260 ROT, rn) \
266do { \
267 ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ 261 ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
268 pF, ROT, rn); \ 262 pF, ROT, rn) \
269} while (0)
270 263
271#define I1024(R) \ 264#define I1024(R) \
272do { \ 265do { \
@@ -291,10 +284,8 @@ do { \
291#else /* looping version */ 284#else /* looping version */
292#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ 285#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
293 ROT, rn) \ 286 ROT, rn) \
294do { \
295 ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ 287 ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
296 pF, ROT, rn); \ 288 pF, ROT, rn) \
297} while (0)
298 289
299#define I1024(R) \ 290#define I1024(R) \
300do { \ 291do { \
diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c
index 85bd7d0168b0..899078f1b8bc 100644
--- a/drivers/staging/skein/skein_generic.c
+++ b/drivers/staging/skein/skein_generic.c
@@ -191,7 +191,6 @@ static int __init skein_generic_init(void)
191 191
192 return 0; 192 return 0;
193 193
194
195unreg512: 194unreg512:
196 crypto_unregister_shash(&alg512); 195 crypto_unregister_shash(&alg512);
197unreg256: 196unreg256:
diff --git a/drivers/staging/sm7xxfb/Kconfig b/drivers/staging/sm7xxfb/Kconfig
new file mode 100644
index 000000000000..e2922ae3a3ee
--- /dev/null
+++ b/drivers/staging/sm7xxfb/Kconfig
@@ -0,0 +1,13 @@
1config FB_SM7XX
2 tristate "Silicon Motion SM7XX framebuffer support"
3 depends on FB && PCI
4 select FB_CFB_FILLRECT
5 select FB_CFB_COPYAREA
6 select FB_CFB_IMAGEBLIT
7 help
8 Frame buffer driver for the Silicon Motion SM710, SM712, SM721
9 and SM722 chips.
10
11 This driver is also available as a module. The module will be
12 called sm7xxfb. If you want to compile it as a module, say M
13 here and read <file:Documentation/kbuild/modules.txt>.
diff --git a/drivers/staging/sm7xxfb/Makefile b/drivers/staging/sm7xxfb/Makefile
new file mode 100644
index 000000000000..48f471cf9f36
--- /dev/null
+++ b/drivers/staging/sm7xxfb/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_FB_SM7XX) += sm7xxfb.o
diff --git a/drivers/staging/sm7xxfb/TODO b/drivers/staging/sm7xxfb/TODO
new file mode 100644
index 000000000000..7cb0b242f204
--- /dev/null
+++ b/drivers/staging/sm7xxfb/TODO
@@ -0,0 +1,12 @@
1TODO:
2- Dual head support
3- 2D acceleration support
4- use kernel coding style
5- refine the code and remove unused code
6- move it to drivers/video/fbdev/sm7xxfb.c
7
8Please send any patches to
9 Greg Kroah-Hartman <greg@kroah.com>
10 Sudip Mukherjee <sudipm.mukherjee@gmail.com>
11 Teddy Wang <teddy.wang@siliconmotion.com>
12 Sudip Mukherjee <sudip@vectorindia.org>
diff --git a/drivers/staging/sm7xxfb/sm7xx.h b/drivers/staging/sm7xxfb/sm7xx.h
new file mode 100644
index 000000000000..7cc1896938b6
--- /dev/null
+++ b/drivers/staging/sm7xxfb/sm7xx.h
@@ -0,0 +1,779 @@
1/*
2 * Silicon Motion SM712 frame buffer device
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Authors: Ge Wang, gewang@siliconmotion.com
6 * Boyod boyod.yang@siliconmotion.com.cn
7 *
8 * Copyright (C) 2009 Lemote, Inc.
9 * Author: Wu Zhangjin, wuzhangjin@gmail.com
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive for
13 * more details.
14 */
15
16#define NR_PALETTE 256
17
18#define FB_ACCEL_SMI_LYNX 88
19
20#define SCREEN_X_RES 1024
21#define SCREEN_Y_RES 600
22#define SCREEN_BPP 16
23
24/*Assume SM712 graphics chip has 4MB VRAM */
25#define SM712_VIDEOMEMORYSIZE 0x00400000
26/*Assume SM722 graphics chip has 8MB VRAM */
27#define SM722_VIDEOMEMORYSIZE 0x00800000
28
29#define dac_reg (0x3c8)
30#define dac_val (0x3c9)
31
32extern void __iomem *smtc_regbaseaddress;
33#define smtc_mmiowb(dat, reg) writeb(dat, smtc_regbaseaddress + reg)
34#define smtc_mmioww(dat, reg) writew(dat, smtc_regbaseaddress + reg)
35#define smtc_mmiowl(dat, reg) writel(dat, smtc_regbaseaddress + reg)
36
37#define smtc_mmiorb(reg) readb(smtc_regbaseaddress + reg)
38#define smtc_mmiorw(reg) readw(smtc_regbaseaddress + reg)
39#define smtc_mmiorl(reg) readl(smtc_regbaseaddress + reg)
40
41#define SIZE_SR00_SR04 (0x04 - 0x00 + 1)
42#define SIZE_SR10_SR24 (0x24 - 0x10 + 1)
43#define SIZE_SR30_SR75 (0x75 - 0x30 + 1)
44#define SIZE_SR80_SR93 (0x93 - 0x80 + 1)
45#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1)
46#define SIZE_GR00_GR08 (0x08 - 0x00 + 1)
47#define SIZE_AR00_AR14 (0x14 - 0x00 + 1)
48#define SIZE_CR00_CR18 (0x18 - 0x00 + 1)
49#define SIZE_CR30_CR4D (0x4D - 0x30 + 1)
50#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1)
51#define SIZE_VPR (0x6C + 1)
52#define SIZE_DPR (0x44 + 1)
53
54static inline void smtc_crtcw(int reg, int val)
55{
56 smtc_mmiowb(reg, 0x3d4);
57 smtc_mmiowb(val, 0x3d5);
58}
59
60static inline unsigned int smtc_crtcr(int reg)
61{
62 smtc_mmiowb(reg, 0x3d4);
63 return smtc_mmiorb(0x3d5);
64}
65
66static inline void smtc_grphw(int reg, int val)
67{
68 smtc_mmiowb(reg, 0x3ce);
69 smtc_mmiowb(val, 0x3cf);
70}
71
72static inline unsigned int smtc_grphr(int reg)
73{
74 smtc_mmiowb(reg, 0x3ce);
75 return smtc_mmiorb(0x3cf);
76}
77
78static inline void smtc_attrw(int reg, int val)
79{
80 smtc_mmiorb(0x3da);
81 smtc_mmiowb(reg, 0x3c0);
82 smtc_mmiorb(0x3c1);
83 smtc_mmiowb(val, 0x3c0);
84}
85
86static inline void smtc_seqw(int reg, int val)
87{
88 smtc_mmiowb(reg, 0x3c4);
89 smtc_mmiowb(val, 0x3c5);
90}
91
92static inline unsigned int smtc_seqr(int reg)
93{
94 smtc_mmiowb(reg, 0x3c4);
95 return smtc_mmiorb(0x3c5);
96}
97
98/* The next structure holds all information relevant for a specific video mode.
99 */
100
101struct ModeInit {
102 int mmsizex;
103 int mmsizey;
104 int bpp;
105 int hz;
106 unsigned char init_misc;
107 unsigned char init_sr00_sr04[SIZE_SR00_SR04];
108 unsigned char init_sr10_sr24[SIZE_SR10_SR24];
109 unsigned char init_sr30_sr75[SIZE_SR30_SR75];
110 unsigned char init_sr80_sr93[SIZE_SR80_SR93];
111 unsigned char init_sra0_sraf[SIZE_SRA0_SRAF];
112 unsigned char init_gr00_gr08[SIZE_GR00_GR08];
113 unsigned char init_ar00_ar14[SIZE_AR00_AR14];
114 unsigned char init_cr00_cr18[SIZE_CR00_CR18];
115 unsigned char init_cr30_cr4d[SIZE_CR30_CR4D];
116 unsigned char init_cr90_cra7[SIZE_CR90_CRA7];
117};
118
119/**********************************************************************
120 SM712 Mode table.
121 **********************************************************************/
122struct ModeInit vgamode[] = {
123 {
124 /* mode#0: 640 x 480 16Bpp 60Hz */
125 640, 480, 16, 60,
126 /* Init_MISC */
127 0xE3,
128 { /* Init_SR0_SR4 */
129 0x03, 0x01, 0x0F, 0x00, 0x0E,
130 },
131 { /* Init_SR10_SR24 */
132 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
133 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0xC4, 0x30, 0x02, 0x01, 0x01,
135 },
136 { /* Init_SR30_SR75 */
137 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
138 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
139 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
140 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
141 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
142 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
143 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
144 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
145 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
146 },
147 { /* Init_SR80_SR93 */
148 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
149 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
150 0x00, 0x00, 0x00, 0x00,
151 },
152 { /* Init_SRA0_SRAF */
153 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
154 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
155 },
156 { /* Init_GR00_GR08 */
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
158 0xFF,
159 },
160 { /* Init_AR00_AR14 */
161 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
162 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
163 0x41, 0x00, 0x0F, 0x00, 0x00,
164 },
165 { /* Init_CR00_CR18 */
166 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
167 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
169 0xFF,
170 },
171 { /* Init_CR30_CR4D */
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
173 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
174 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
175 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
176 },
177 { /* Init_CR90_CRA7 */
178 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
179 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
180 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
181 },
182 },
183 {
184 /* mode#1: 640 x 480 24Bpp 60Hz */
185 640, 480, 24, 60,
186 /* Init_MISC */
187 0xE3,
188 { /* Init_SR0_SR4 */
189 0x03, 0x01, 0x0F, 0x00, 0x0E,
190 },
191 { /* Init_SR10_SR24 */
192 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
193 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0xC4, 0x30, 0x02, 0x01, 0x01,
195 },
196 { /* Init_SR30_SR75 */
197 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
198 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
199 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
200 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
201 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
202 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
203 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
204 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
205 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
206 },
207 { /* Init_SR80_SR93 */
208 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
209 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
210 0x00, 0x00, 0x00, 0x00,
211 },
212 { /* Init_SRA0_SRAF */
213 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
214 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
215 },
216 { /* Init_GR00_GR08 */
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
218 0xFF,
219 },
220 { /* Init_AR00_AR14 */
221 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
222 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
223 0x41, 0x00, 0x0F, 0x00, 0x00,
224 },
225 { /* Init_CR00_CR18 */
226 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
227 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
229 0xFF,
230 },
231 { /* Init_CR30_CR4D */
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
233 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
234 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
235 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
236 },
237 { /* Init_CR90_CRA7 */
238 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
239 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
240 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
241 },
242 },
243 {
244 /* mode#0: 640 x 480 32Bpp 60Hz */
245 640, 480, 32, 60,
246 /* Init_MISC */
247 0xE3,
248 { /* Init_SR0_SR4 */
249 0x03, 0x01, 0x0F, 0x00, 0x0E,
250 },
251 { /* Init_SR10_SR24 */
252 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
253 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0xC4, 0x30, 0x02, 0x01, 0x01,
255 },
256 { /* Init_SR30_SR75 */
257 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
258 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
259 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
260 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
261 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
262 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
263 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
264 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
265 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
266 },
267 { /* Init_SR80_SR93 */
268 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
269 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
270 0x00, 0x00, 0x00, 0x00,
271 },
272 { /* Init_SRA0_SRAF */
273 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
274 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
275 },
276 { /* Init_GR00_GR08 */
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
278 0xFF,
279 },
280 { /* Init_AR00_AR14 */
281 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
282 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
283 0x41, 0x00, 0x0F, 0x00, 0x00,
284 },
285 { /* Init_CR00_CR18 */
286 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
287 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
289 0xFF,
290 },
291 { /* Init_CR30_CR4D */
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
293 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
294 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
295 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
296 },
297 { /* Init_CR90_CRA7 */
298 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
299 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
300 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
301 },
302 },
303
304 { /* mode#2: 800 x 600 16Bpp 60Hz */
305 800, 600, 16, 60,
306 /* Init_MISC */
307 0x2B,
308 { /* Init_SR0_SR4 */
309 0x03, 0x01, 0x0F, 0x03, 0x0E,
310 },
311 { /* Init_SR10_SR24 */
312 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
313 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0xC4, 0x30, 0x02, 0x01, 0x01,
315 },
316 { /* Init_SR30_SR75 */
317 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
318 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
319 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
320 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
321 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
322 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
323 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
324 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
325 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
326 },
327 { /* Init_SR80_SR93 */
328 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
329 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
330 0x00, 0x00, 0x00, 0x00,
331 },
332 { /* Init_SRA0_SRAF */
333 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
334 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
335 },
336 { /* Init_GR00_GR08 */
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
338 0xFF,
339 },
340 { /* Init_AR00_AR14 */
341 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
342 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
343 0x41, 0x00, 0x0F, 0x00, 0x00,
344 },
345 { /* Init_CR00_CR18 */
346 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
347 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
349 0xFF,
350 },
351 { /* Init_CR30_CR4D */
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
353 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
354 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
355 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
356 },
357 { /* Init_CR90_CRA7 */
358 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
359 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
360 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
361 },
362 },
363 { /* mode#3: 800 x 600 24Bpp 60Hz */
364 800, 600, 24, 60,
365 0x2B,
366 { /* Init_SR0_SR4 */
367 0x03, 0x01, 0x0F, 0x03, 0x0E,
368 },
369 { /* Init_SR10_SR24 */
370 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
371 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0xC4, 0x30, 0x02, 0x01, 0x01,
373 },
374 { /* Init_SR30_SR75 */
375 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
376 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
377 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
378 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
379 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
380 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
381 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
382 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
383 0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
384 },
385 { /* Init_SR80_SR93 */
386 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
387 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
388 0x00, 0x00, 0x00, 0x00,
389 },
390 { /* Init_SRA0_SRAF */
391 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
392 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
393 },
394 { /* Init_GR00_GR08 */
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
396 0xFF,
397 },
398 { /* Init_AR00_AR14 */
399 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
400 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
401 0x41, 0x00, 0x0F, 0x00, 0x00,
402 },
403 { /* Init_CR00_CR18 */
404 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
405 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
407 0xFF,
408 },
409 { /* Init_CR30_CR4D */
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
411 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
412 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
413 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
414 },
415 { /* Init_CR90_CRA7 */
416 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
417 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
418 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
419 },
420 },
421 { /* mode#7: 800 x 600 32Bpp 60Hz */
422 800, 600, 32, 60,
423 /* Init_MISC */
424 0x2B,
425 { /* Init_SR0_SR4 */
426 0x03, 0x01, 0x0F, 0x03, 0x0E,
427 },
428 { /* Init_SR10_SR24 */
429 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
430 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0xC4, 0x30, 0x02, 0x01, 0x01,
432 },
433 { /* Init_SR30_SR75 */
434 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
435 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
436 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
437 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
438 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
439 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
440 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
441 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
442 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
443 },
444 { /* Init_SR80_SR93 */
445 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
446 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
447 0x00, 0x00, 0x00, 0x00,
448 },
449 { /* Init_SRA0_SRAF */
450 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
451 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
452 },
453 { /* Init_GR00_GR08 */
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
455 0xFF,
456 },
457 { /* Init_AR00_AR14 */
458 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
459 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
460 0x41, 0x00, 0x0F, 0x00, 0x00,
461 },
462 { /* Init_CR00_CR18 */
463 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
464 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
466 0xFF,
467 },
468 { /* Init_CR30_CR4D */
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
470 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
471 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
472 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
473 },
474 { /* Init_CR90_CRA7 */
475 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
476 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
477 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
478 },
479 },
480 /* We use 1024x768 table to light 1024x600 panel for lemote */
481 { /* mode#4: 1024 x 600 16Bpp 60Hz */
482 1024, 600, 16, 60,
483 /* Init_MISC */
484 0xEB,
485 { /* Init_SR0_SR4 */
486 0x03, 0x01, 0x0F, 0x00, 0x0E,
487 },
488 { /* Init_SR10_SR24 */
489 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,
490 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0xC4, 0x30, 0x02, 0x00, 0x01,
492 },
493 { /* Init_SR30_SR75 */
494 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,
495 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,
496 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
497 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,
498 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
499 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,
500 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
501 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,
502 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,
503 },
504 { /* Init_SR80_SR93 */
505 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
506 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
507 0x00, 0x00, 0x00, 0x00,
508 },
509 { /* Init_SRA0_SRAF */
510 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
511 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
512 },
513 { /* Init_GR00_GR08 */
514 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
515 0xFF,
516 },
517 { /* Init_AR00_AR14 */
518 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
519 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
520 0x41, 0x00, 0x0F, 0x00, 0x00,
521 },
522 { /* Init_CR00_CR18 */
523 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
524 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
526 0xFF,
527 },
528 { /* Init_CR30_CR4D */
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
530 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
531 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,
532 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,
533 },
534 { /* Init_CR90_CRA7 */
535 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
536 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
537 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
538 },
539 },
540 { /* mode#5: 1024 x 768 24Bpp 60Hz */
541 1024, 768, 24, 60,
542 /* Init_MISC */
543 0xEB,
544 { /* Init_SR0_SR4 */
545 0x03, 0x01, 0x0F, 0x03, 0x0E,
546 },
547 { /* Init_SR10_SR24 */
548 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
549 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0xC4, 0x30, 0x02, 0x01, 0x01,
551 },
552 { /* Init_SR30_SR75 */
553 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
554 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
555 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
556 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
557 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
558 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
559 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
560 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
561 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
562 },
563 { /* Init_SR80_SR93 */
564 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
565 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
566 0x00, 0x00, 0x00, 0x00,
567 },
568 { /* Init_SRA0_SRAF */
569 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
570 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
571 },
572 { /* Init_GR00_GR08 */
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
574 0xFF,
575 },
576 { /* Init_AR00_AR14 */
577 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
578 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
579 0x41, 0x00, 0x0F, 0x00, 0x00,
580 },
581 { /* Init_CR00_CR18 */
582 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
583 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
585 0xFF,
586 },
587 { /* Init_CR30_CR4D */
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
589 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
590 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
591 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
592 },
593 { /* Init_CR90_CRA7 */
594 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
595 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
596 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
597 },
598 },
599 { /* mode#4: 1024 x 768 32Bpp 60Hz */
600 1024, 768, 32, 60,
601 /* Init_MISC */
602 0xEB,
603 { /* Init_SR0_SR4 */
604 0x03, 0x01, 0x0F, 0x03, 0x0E,
605 },
606 { /* Init_SR10_SR24 */
607 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
608 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0xC4, 0x32, 0x02, 0x01, 0x01,
610 },
611 { /* Init_SR30_SR75 */
612 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
613 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
614 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
615 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
616 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
617 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
618 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
619 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
620 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
621 },
622 { /* Init_SR80_SR93 */
623 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
624 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
625 0x00, 0x00, 0x00, 0x00,
626 },
627 { /* Init_SRA0_SRAF */
628 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
629 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
630 },
631 { /* Init_GR00_GR08 */
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
633 0xFF,
634 },
635 { /* Init_AR00_AR14 */
636 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
637 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
638 0x41, 0x00, 0x0F, 0x00, 0x00,
639 },
640 { /* Init_CR00_CR18 */
641 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
642 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
644 0xFF,
645 },
646 { /* Init_CR30_CR4D */
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
648 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
649 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
650 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
651 },
652 { /* Init_CR90_CRA7 */
653 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
654 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
655 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
656 },
657 },
658 { /* mode#6: 320 x 240 16Bpp 60Hz */
659 320, 240, 16, 60,
660 /* Init_MISC */
661 0xEB,
662 { /* Init_SR0_SR4 */
663 0x03, 0x01, 0x0F, 0x03, 0x0E,
664 },
665 { /* Init_SR10_SR24 */
666 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
667 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0xC4, 0x32, 0x02, 0x01, 0x01,
669 },
670 { /* Init_SR30_SR75 */
671 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
672 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
673 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
674 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
675 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
676 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
677 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
678 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
679 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
680 },
681 { /* Init_SR80_SR93 */
682 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
683 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
684 0x00, 0x00, 0x00, 0x00,
685 },
686 { /* Init_SRA0_SRAF */
687 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
688 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
689 },
690 { /* Init_GR00_GR08 */
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
692 0xFF,
693 },
694 { /* Init_AR00_AR14 */
695 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
696 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
697 0x41, 0x00, 0x0F, 0x00, 0x00,
698 },
699 { /* Init_CR00_CR18 */
700 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
701 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
703 0xFF,
704 },
705 { /* Init_CR30_CR4D */
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
707 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
708 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
709 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
710 },
711 { /* Init_CR90_CRA7 */
712 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
713 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
714 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
715 },
716 },
717
718 { /* mode#8: 320 x 240 32Bpp 60Hz */
719 320, 240, 32, 60,
720 /* Init_MISC */
721 0xEB,
722 { /* Init_SR0_SR4 */
723 0x03, 0x01, 0x0F, 0x03, 0x0E,
724 },
725 { /* Init_SR10_SR24 */
726 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
727 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0xC4, 0x32, 0x02, 0x01, 0x01,
729 },
730 { /* Init_SR30_SR75 */
731 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
732 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
733 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
734 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
735 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
736 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
737 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
738 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
739 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
740 },
741 { /* Init_SR80_SR93 */
742 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
743 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
744 0x00, 0x00, 0x00, 0x00,
745 },
746 { /* Init_SRA0_SRAF */
747 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
748 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
749 },
750 { /* Init_GR00_GR08 */
751 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
752 0xFF,
753 },
754 { /* Init_AR00_AR14 */
755 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
756 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
757 0x41, 0x00, 0x0F, 0x00, 0x00,
758 },
759 { /* Init_CR00_CR18 */
760 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
761 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
763 0xFF,
764 },
765 { /* Init_CR30_CR4D */
766 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
767 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
768 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
769 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
770 },
771 { /* Init_CR90_CRA7 */
772 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
773 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
774 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
775 },
776 },
777};
778
779#define numvgamodes ARRAY_SIZE(vgamode)
diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c
new file mode 100644
index 000000000000..ebd95365ffae
--- /dev/null
+++ b/drivers/staging/sm7xxfb/sm7xxfb.c
@@ -0,0 +1,1024 @@
1/*
2 * Silicon Motion SM7XX frame buffer device
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Authors: Ge Wang, gewang@siliconmotion.com
6 * Boyod boyod.yang@siliconmotion.com.cn
7 *
8 * Copyright (C) 2009 Lemote, Inc.
9 * Author: Wu Zhangjin, wuzhangjin@gmail.com
10 *
11 * Copyright (C) 2011 Igalia, S.L.
12 * Author: Javier M. Mellid <jmunhoz@igalia.com>
13 *
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file COPYING in the main directory of this archive for
16 * more details.
17 *
18 * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips
19 */
20
21#include <linux/io.h>
22#include <linux/fb.h>
23#include <linux/pci.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/uaccess.h>
27#include <linux/module.h>
28#include <linux/console.h>
29#include <linux/screen_info.h>
30
31#ifdef CONFIG_PM
32#include <linux/pm.h>
33#endif
34
35#include "sm7xx.h"
36
37/*
38* Private structure
39*/
40struct smtcfb_info {
41 struct pci_dev *pdev;
42 struct fb_info fb;
43 u16 chip_id;
44 u8 chip_rev_id;
45
46 void __iomem *lfb; /* linear frame buffer */
47 void __iomem *dp_regs; /* drawing processor control regs */
48 void __iomem *vp_regs; /* video processor control regs */
49 void __iomem *cp_regs; /* capture processor control regs */
50 void __iomem *mmio; /* memory map IO port */
51
52 u_int width;
53 u_int height;
54 u_int hz;
55
56 u32 colreg[17];
57};
58
59void __iomem *smtc_regbaseaddress; /* Memory Map IO starting address */
60
61static struct fb_var_screeninfo smtcfb_var = {
62 .xres = 1024,
63 .yres = 600,
64 .xres_virtual = 1024,
65 .yres_virtual = 600,
66 .bits_per_pixel = 16,
67 .red = {16, 8, 0},
68 .green = {8, 8, 0},
69 .blue = {0, 8, 0},
70 .activate = FB_ACTIVATE_NOW,
71 .height = -1,
72 .width = -1,
73 .vmode = FB_VMODE_NONINTERLACED,
74 .nonstd = 0,
75 .accel_flags = FB_ACCELF_TEXT,
76};
77
78static struct fb_fix_screeninfo smtcfb_fix = {
79 .id = "smXXXfb",
80 .type = FB_TYPE_PACKED_PIXELS,
81 .visual = FB_VISUAL_TRUECOLOR,
82 .line_length = 800 * 3,
83 .accel = FB_ACCEL_SMI_LYNX,
84 .type_aux = 0,
85 .xpanstep = 0,
86 .ypanstep = 0,
87 .ywrapstep = 0,
88};
89
90struct vesa_mode {
91 char index[6];
92 u16 lfb_width;
93 u16 lfb_height;
94 u16 lfb_depth;
95};
96
97static struct vesa_mode vesa_mode_table[] = {
98 {"0x301", 640, 480, 8},
99 {"0x303", 800, 600, 8},
100 {"0x305", 1024, 768, 8},
101 {"0x307", 1280, 1024, 8},
102
103 {"0x311", 640, 480, 16},
104 {"0x314", 800, 600, 16},
105 {"0x317", 1024, 768, 16},
106 {"0x31A", 1280, 1024, 16},
107
108 {"0x312", 640, 480, 24},
109 {"0x315", 800, 600, 24},
110 {"0x318", 1024, 768, 24},
111 {"0x31B", 1280, 1024, 24},
112};
113
114static struct screen_info smtc_scr_info;
115
116/* process command line options, get vga parameter */
117static int __init sm7xx_vga_setup(char *options)
118{
119 int i;
120
121 if (!options || !*options)
122 return -EINVAL;
123
124 smtc_scr_info.lfb_width = 0;
125 smtc_scr_info.lfb_height = 0;
126 smtc_scr_info.lfb_depth = 0;
127
128 pr_debug("sm7xx_vga_setup = %s\n", options);
129
130 for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) {
131 if (strstr(options, vesa_mode_table[i].index)) {
132 smtc_scr_info.lfb_width = vesa_mode_table[i].lfb_width;
133 smtc_scr_info.lfb_height =
134 vesa_mode_table[i].lfb_height;
135 smtc_scr_info.lfb_depth = vesa_mode_table[i].lfb_depth;
136 return 0;
137 }
138 }
139
140 return -1;
141}
142__setup("vga=", sm7xx_vga_setup);
143
144static void sm712_setpalette(int regno, unsigned red, unsigned green,
145 unsigned blue, struct fb_info *info)
146{
147 /* set bit 5:4 = 01 (write LCD RAM only) */
148 smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
149
150 smtc_mmiowb(regno, dac_reg);
151 smtc_mmiowb(red >> 10, dac_val);
152 smtc_mmiowb(green >> 10, dac_val);
153 smtc_mmiowb(blue >> 10, dac_val);
154}
155
156/* chan_to_field
157 *
158 * convert a colour value into a field position
159 *
160 * from pxafb.c
161 */
162
163static inline unsigned int chan_to_field(unsigned int chan,
164 struct fb_bitfield *bf)
165{
166 chan &= 0xffff;
167 chan >>= 16 - bf->length;
168 return chan << bf->offset;
169}
170
171static int smtc_blank(int blank_mode, struct fb_info *info)
172{
173 /* clear DPMS setting */
174 switch (blank_mode) {
175 case FB_BLANK_UNBLANK:
176 /* Screen On: HSync: On, VSync : On */
177 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
178 smtc_seqw(0x6a, 0x16);
179 smtc_seqw(0x6b, 0x02);
180 smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
181 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
182 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
183 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
184 smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
185 break;
186 case FB_BLANK_NORMAL:
187 /* Screen Off: HSync: On, VSync : On Soft blank */
188 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
189 smtc_seqw(0x6a, 0x16);
190 smtc_seqw(0x6b, 0x02);
191 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
192 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
193 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
194 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
195 break;
196 case FB_BLANK_VSYNC_SUSPEND:
197 /* Screen On: HSync: On, VSync : Off */
198 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
199 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
200 smtc_seqw(0x6a, 0x0c);
201 smtc_seqw(0x6b, 0x02);
202 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
203 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
204 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
205 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
206 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
207 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
208 break;
209 case FB_BLANK_HSYNC_SUSPEND:
210 /* Screen On: HSync: Off, VSync : On */
211 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
212 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
213 smtc_seqw(0x6a, 0x0c);
214 smtc_seqw(0x6b, 0x02);
215 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
216 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
217 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
218 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
219 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
220 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
221 break;
222 case FB_BLANK_POWERDOWN:
223 /* Screen On: HSync: Off, VSync : Off */
224 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
225 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
226 smtc_seqw(0x6a, 0x0c);
227 smtc_seqw(0x6b, 0x02);
228 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
229 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
230 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
231 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
232 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
233 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
234 break;
235 default:
236 return -EINVAL;
237 }
238
239 return 0;
240}
241
242static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
243 unsigned blue, unsigned trans, struct fb_info *info)
244{
245 struct smtcfb_info *sfb;
246 u32 val;
247
248 sfb = info->par;
249
250 if (regno > 255)
251 return 1;
252
253 switch (sfb->fb.fix.visual) {
254 case FB_VISUAL_DIRECTCOLOR:
255 case FB_VISUAL_TRUECOLOR:
256 /*
257 * 16/32 bit true-colour, use pseudo-palette for 16 base color
258 */
259 if (regno < 16) {
260 if (sfb->fb.var.bits_per_pixel == 16) {
261 u32 *pal = sfb->fb.pseudo_palette;
262
263 val = chan_to_field(red, &sfb->fb.var.red);
264 val |= chan_to_field(green, &sfb->fb.var.green);
265 val |= chan_to_field(blue, &sfb->fb.var.blue);
266#ifdef __BIG_ENDIAN
267 pal[regno] =
268 ((red & 0xf800) >> 8) |
269 ((green & 0xe000) >> 13) |
270 ((green & 0x1c00) << 3) |
271 ((blue & 0xf800) >> 3);
272#else
273 pal[regno] = val;
274#endif
275 } else {
276 u32 *pal = sfb->fb.pseudo_palette;
277
278 val = chan_to_field(red, &sfb->fb.var.red);
279 val |= chan_to_field(green, &sfb->fb.var.green);
280 val |= chan_to_field(blue, &sfb->fb.var.blue);
281#ifdef __BIG_ENDIAN
282 val =
283 (val & 0xff00ff00 >> 8) |
284 (val & 0x00ff00ff << 8);
285#endif
286 pal[regno] = val;
287 }
288 }
289 break;
290
291 case FB_VISUAL_PSEUDOCOLOR:
292 /* color depth 8 bit */
293 sm712_setpalette(regno, red, green, blue, info);
294 break;
295
296 default:
297 return 1; /* unknown type */
298 }
299
300 return 0;
301}
302
303#ifdef __BIG_ENDIAN
304static ssize_t smtcfb_read(struct fb_info *info, char __user *buf, size_t
305 count, loff_t *ppos)
306{
307 unsigned long p = *ppos;
308
309 u32 *buffer, *dst;
310 u32 __iomem *src;
311 int c, i, cnt = 0, err = 0;
312 unsigned long total_size;
313
314 if (!info || !info->screen_base)
315 return -ENODEV;
316
317 if (info->state != FBINFO_STATE_RUNNING)
318 return -EPERM;
319
320 total_size = info->screen_size;
321
322 if (total_size == 0)
323 total_size = info->fix.smem_len;
324
325 if (p >= total_size)
326 return 0;
327
328 if (count >= total_size)
329 count = total_size;
330
331 if (count + p > total_size)
332 count = total_size - p;
333
334 buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
335 if (!buffer)
336 return -ENOMEM;
337
338 src = (u32 __iomem *) (info->screen_base + p);
339
340 if (info->fbops->fb_sync)
341 info->fbops->fb_sync(info);
342
343 while (count) {
344 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
345 dst = buffer;
346 for (i = c >> 2; i--;) {
347 *dst = fb_readl(src++);
348 *dst =
349 (*dst & 0xff00ff00 >> 8) |
350 (*dst & 0x00ff00ff << 8);
351 dst++;
352 }
353 if (c & 3) {
354 u8 *dst8 = (u8 *)dst;
355 u8 __iomem *src8 = (u8 __iomem *)src;
356
357 for (i = c & 3; i--;) {
358 if (i & 1) {
359 *dst8++ = fb_readb(++src8);
360 } else {
361 *dst8++ = fb_readb(--src8);
362 src8 += 2;
363 }
364 }
365 src = (u32 __iomem *)src8;
366 }
367
368 if (copy_to_user(buf, buffer, c)) {
369 err = -EFAULT;
370 break;
371 }
372 *ppos += c;
373 buf += c;
374 cnt += c;
375 count -= c;
376 }
377
378 kfree(buffer);
379
380 return (err) ? err : cnt;
381}
382
383static ssize_t
384smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
385 loff_t *ppos)
386{
387 unsigned long p = *ppos;
388
389 u32 *buffer, *src;
390 u32 __iomem *dst;
391 int c, i, cnt = 0, err = 0;
392 unsigned long total_size;
393
394 if (!info || !info->screen_base)
395 return -ENODEV;
396
397 if (info->state != FBINFO_STATE_RUNNING)
398 return -EPERM;
399
400 total_size = info->screen_size;
401
402 if (total_size == 0)
403 total_size = info->fix.smem_len;
404
405 if (p > total_size)
406 return -EFBIG;
407
408 if (count > total_size) {
409 err = -EFBIG;
410 count = total_size;
411 }
412
413 if (count + p > total_size) {
414 if (!err)
415 err = -ENOSPC;
416
417 count = total_size - p;
418 }
419
420 buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
421 if (!buffer)
422 return -ENOMEM;
423
424 dst = (u32 __iomem *) (info->screen_base + p);
425
426 if (info->fbops->fb_sync)
427 info->fbops->fb_sync(info);
428
429 while (count) {
430 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
431 src = buffer;
432
433 if (copy_from_user(src, buf, c)) {
434 err = -EFAULT;
435 break;
436 }
437
438 for (i = c >> 2; i--;) {
439 fb_writel((*src & 0xff00ff00 >> 8) |
440 (*src & 0x00ff00ff << 8), dst++);
441 src++;
442 }
443 if (c & 3) {
444 u8 *src8 = (u8 *)src;
445 u8 __iomem *dst8 = (u8 __iomem *)dst;
446
447 for (i = c & 3; i--;) {
448 if (i & 1) {
449 fb_writeb(*src8++, ++dst8);
450 } else {
451 fb_writeb(*src8++, --dst8);
452 dst8 += 2;
453 }
454 }
455 dst = (u32 __iomem *)dst8;
456 }
457
458 *ppos += c;
459 buf += c;
460 cnt += c;
461 count -= c;
462 }
463
464 kfree(buffer);
465
466 return (cnt) ? cnt : err;
467}
468#endif /* ! __BIG_ENDIAN */
469
470static void sm7xx_set_timing(struct smtcfb_info *sfb)
471{
472 int i = 0, j = 0;
473 u32 m_nscreenstride;
474
475 dev_dbg(&sfb->pdev->dev,
476 "sfb->width=%d sfb->height=%d sfb->fb.var.bits_per_pixel=%d sfb->hz=%d\n",
477 sfb->width, sfb->height, sfb->fb.var.bits_per_pixel, sfb->hz);
478
479 for (j = 0; j < numvgamodes; j++) {
480 if (vgamode[j].mmsizex == sfb->width &&
481 vgamode[j].mmsizey == sfb->height &&
482 vgamode[j].bpp == sfb->fb.var.bits_per_pixel &&
483 vgamode[j].hz == sfb->hz) {
484 dev_dbg(&sfb->pdev->dev,
485 "vgamode[j].mmsizex=%d vgamode[j].mmSizeY=%d vgamode[j].bpp=%d vgamode[j].hz=%d\n",
486 vgamode[j].mmsizex, vgamode[j].mmsizey,
487 vgamode[j].bpp, vgamode[j].hz);
488
489 dev_dbg(&sfb->pdev->dev, "vgamode index=%d\n", j);
490
491 smtc_mmiowb(0x0, 0x3c6);
492
493 smtc_seqw(0, 0x1);
494
495 smtc_mmiowb(vgamode[j].init_misc, 0x3c2);
496
497 /* init SEQ register SR00 - SR04 */
498 for (i = 0; i < SIZE_SR00_SR04; i++)
499 smtc_seqw(i, vgamode[j].init_sr00_sr04[i]);
500
501 /* init SEQ register SR10 - SR24 */
502 for (i = 0; i < SIZE_SR10_SR24; i++)
503 smtc_seqw(i + 0x10,
504 vgamode[j].init_sr10_sr24[i]);
505
506 /* init SEQ register SR30 - SR75 */
507 for (i = 0; i < SIZE_SR30_SR75; i++)
508 if ((i + 0x30) != 0x62 &&
509 (i + 0x30) != 0x6a &&
510 (i + 0x30) != 0x6b)
511 smtc_seqw(i + 0x30,
512 vgamode[j].init_sr30_sr75[i]);
513
514 /* init SEQ register SR80 - SR93 */
515 for (i = 0; i < SIZE_SR80_SR93; i++)
516 smtc_seqw(i + 0x80,
517 vgamode[j].init_sr80_sr93[i]);
518
519 /* init SEQ register SRA0 - SRAF */
520 for (i = 0; i < SIZE_SRA0_SRAF; i++)
521 smtc_seqw(i + 0xa0,
522 vgamode[j].init_sra0_sraf[i]);
523
524 /* init Graphic register GR00 - GR08 */
525 for (i = 0; i < SIZE_GR00_GR08; i++)
526 smtc_grphw(i, vgamode[j].init_gr00_gr08[i]);
527
528 /* init Attribute register AR00 - AR14 */
529 for (i = 0; i < SIZE_AR00_AR14; i++)
530 smtc_attrw(i, vgamode[j].init_ar00_ar14[i]);
531
532 /* init CRTC register CR00 - CR18 */
533 for (i = 0; i < SIZE_CR00_CR18; i++)
534 smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]);
535
536 /* init CRTC register CR30 - CR4D */
537 for (i = 0; i < SIZE_CR30_CR4D; i++)
538 smtc_crtcw(i + 0x30,
539 vgamode[j].init_cr30_cr4d[i]);
540
541 /* init CRTC register CR90 - CRA7 */
542 for (i = 0; i < SIZE_CR90_CRA7; i++)
543 smtc_crtcw(i + 0x90,
544 vgamode[j].init_cr90_cra7[i]);
545 }
546 }
547 smtc_mmiowb(0x67, 0x3c2);
548
549 /* set VPR registers */
550 writel(0x0, sfb->vp_regs + 0x0C);
551 writel(0x0, sfb->vp_regs + 0x40);
552
553 /* set data width */
554 m_nscreenstride =
555 (sfb->width * sfb->fb.var.bits_per_pixel) / 64;
556 switch (sfb->fb.var.bits_per_pixel) {
557 case 8:
558 writel(0x0, sfb->vp_regs + 0x0);
559 break;
560 case 16:
561 writel(0x00020000, sfb->vp_regs + 0x0);
562 break;
563 case 24:
564 writel(0x00040000, sfb->vp_regs + 0x0);
565 break;
566 case 32:
567 writel(0x00030000, sfb->vp_regs + 0x0);
568 break;
569 }
570 writel((u32) (((m_nscreenstride + 2) << 16) | m_nscreenstride),
571 sfb->vp_regs + 0x10);
572}
573
574static void smtc_set_timing(struct smtcfb_info *sfb)
575{
576 switch (sfb->chip_id) {
577 case 0x710:
578 case 0x712:
579 case 0x720:
580 sm7xx_set_timing(sfb);
581 break;
582 }
583}
584
585static void smtcfb_setmode(struct smtcfb_info *sfb)
586{
587 switch (sfb->fb.var.bits_per_pixel) {
588 case 32:
589 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
590 sfb->fb.fix.line_length = sfb->fb.var.xres * 4;
591 sfb->fb.var.red.length = 8;
592 sfb->fb.var.green.length = 8;
593 sfb->fb.var.blue.length = 8;
594 sfb->fb.var.red.offset = 16;
595 sfb->fb.var.green.offset = 8;
596 sfb->fb.var.blue.offset = 0;
597 break;
598 case 24:
599 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
600 sfb->fb.fix.line_length = sfb->fb.var.xres * 3;
601 sfb->fb.var.red.length = 8;
602 sfb->fb.var.green.length = 8;
603 sfb->fb.var.blue.length = 8;
604 sfb->fb.var.red.offset = 16;
605 sfb->fb.var.green.offset = 8;
606 sfb->fb.var.blue.offset = 0;
607 break;
608 case 8:
609 sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
610 sfb->fb.fix.line_length = sfb->fb.var.xres;
611 sfb->fb.var.red.length = 3;
612 sfb->fb.var.green.length = 3;
613 sfb->fb.var.blue.length = 2;
614 sfb->fb.var.red.offset = 5;
615 sfb->fb.var.green.offset = 2;
616 sfb->fb.var.blue.offset = 0;
617 break;
618 case 16:
619 default:
620 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
621 sfb->fb.fix.line_length = sfb->fb.var.xres * 2;
622 sfb->fb.var.red.length = 5;
623 sfb->fb.var.green.length = 6;
624 sfb->fb.var.blue.length = 5;
625 sfb->fb.var.red.offset = 11;
626 sfb->fb.var.green.offset = 5;
627 sfb->fb.var.blue.offset = 0;
628 break;
629 }
630
631 sfb->width = sfb->fb.var.xres;
632 sfb->height = sfb->fb.var.yres;
633 sfb->hz = 60;
634 smtc_set_timing(sfb);
635}
636
637static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
638{
639 /* sanity checks */
640 if (var->xres_virtual < var->xres)
641 var->xres_virtual = var->xres;
642
643 if (var->yres_virtual < var->yres)
644 var->yres_virtual = var->yres;
645
646 /* set valid default bpp */
647 if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16) &&
648 (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32))
649 var->bits_per_pixel = 16;
650
651 return 0;
652}
653
654static int smtc_set_par(struct fb_info *info)
655{
656 smtcfb_setmode(info->par);
657
658 return 0;
659}
660
661static struct fb_ops smtcfb_ops = {
662 .owner = THIS_MODULE,
663 .fb_check_var = smtc_check_var,
664 .fb_set_par = smtc_set_par,
665 .fb_setcolreg = smtc_setcolreg,
666 .fb_blank = smtc_blank,
667 .fb_fillrect = cfb_fillrect,
668 .fb_imageblit = cfb_imageblit,
669 .fb_copyarea = cfb_copyarea,
670#ifdef __BIG_ENDIAN
671 .fb_read = smtcfb_read,
672 .fb_write = smtcfb_write,
673#endif
674};
675
676/*
677 * alloc struct smtcfb_info and assign default values
678 */
679static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev)
680{
681 struct smtcfb_info *sfb;
682
683 sfb = kzalloc(sizeof(*sfb), GFP_KERNEL);
684
685 if (!sfb)
686 return NULL;
687
688 sfb->pdev = pdev;
689
690 sfb->fb.flags = FBINFO_FLAG_DEFAULT;
691 sfb->fb.fbops = &smtcfb_ops;
692 sfb->fb.fix = smtcfb_fix;
693 sfb->fb.var = smtcfb_var;
694 sfb->fb.pseudo_palette = sfb->colreg;
695 sfb->fb.par = sfb;
696
697 return sfb;
698}
699
700/*
701 * free struct smtcfb_info
702 */
703static void smtc_free_fb_info(struct smtcfb_info *sfb)
704{
705 kfree(sfb);
706}
707
708/*
709 * Unmap in the memory mapped IO registers
710 */
711
712static void smtc_unmap_mmio(struct smtcfb_info *sfb)
713{
714 if (sfb && smtc_regbaseaddress)
715 smtc_regbaseaddress = NULL;
716}
717
718/*
719 * Map in the screen memory
720 */
721
722static int smtc_map_smem(struct smtcfb_info *sfb,
723 struct pci_dev *pdev, u_long smem_len)
724{
725 sfb->fb.fix.smem_start = pci_resource_start(pdev, 0);
726
727#ifdef __BIG_ENDIAN
728 if (sfb->fb.var.bits_per_pixel == 32)
729 sfb->fb.fix.smem_start += 0x800000;
730#endif
731
732 sfb->fb.fix.smem_len = smem_len;
733
734 sfb->fb.screen_base = sfb->lfb;
735
736 if (!sfb->fb.screen_base) {
737 dev_err(&pdev->dev,
738 "%s: unable to map screen memory\n", sfb->fb.fix.id);
739 return -ENOMEM;
740 }
741
742 return 0;
743}
744
745/*
746 * Unmap in the screen memory
747 *
748 */
749static void smtc_unmap_smem(struct smtcfb_info *sfb)
750{
751 if (sfb && sfb->fb.screen_base) {
752 iounmap(sfb->fb.screen_base);
753 sfb->fb.screen_base = NULL;
754 }
755}
756
757/*
758 * We need to wake up the device and make sure its in linear memory mode.
759 */
760static inline void sm7xx_init_hw(void)
761{
762 outb_p(0x18, 0x3c4);
763 outb_p(0x11, 0x3c5);
764}
765
766static int smtcfb_pci_probe(struct pci_dev *pdev,
767 const struct pci_device_id *ent)
768{
769 struct smtcfb_info *sfb;
770 u_long smem_size = 0x00800000; /* default 8MB */
771 int err;
772 unsigned long mmio_base;
773
774 dev_info(&pdev->dev, "Silicon Motion display driver.");
775
776 err = pci_enable_device(pdev); /* enable SMTC chip */
777 if (err)
778 return err;
779
780 sprintf(smtcfb_fix.id, "sm%Xfb", ent->device);
781
782 sfb = smtc_alloc_fb_info(pdev);
783
784 if (!sfb) {
785 err = -ENOMEM;
786 goto failed_free;
787 }
788
789 sfb->chip_id = ent->device;
790
791 pci_set_drvdata(pdev, sfb);
792
793 sm7xx_init_hw();
794
795 /* get mode parameter from smtc_scr_info */
796 if (smtc_scr_info.lfb_width != 0) {
797 sfb->fb.var.xres = smtc_scr_info.lfb_width;
798 sfb->fb.var.yres = smtc_scr_info.lfb_height;
799 sfb->fb.var.bits_per_pixel = smtc_scr_info.lfb_depth;
800 } else {
801 /* default resolution 1024x600 16bit mode */
802 sfb->fb.var.xres = SCREEN_X_RES;
803 sfb->fb.var.yres = SCREEN_Y_RES;
804 sfb->fb.var.bits_per_pixel = SCREEN_BPP;
805 }
806
807#ifdef __BIG_ENDIAN
808 if (sfb->fb.var.bits_per_pixel == 24)
809 sfb->fb.var.bits_per_pixel = (smtc_scr_info.lfb_depth = 32);
810#endif
811 /* Map address and memory detection */
812 mmio_base = pci_resource_start(pdev, 0);
813 pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);
814
815 switch (sfb->chip_id) {
816 case 0x710:
817 case 0x712:
818 sfb->fb.fix.mmio_start = mmio_base + 0x00400000;
819 sfb->fb.fix.mmio_len = 0x00400000;
820 smem_size = SM712_VIDEOMEMORYSIZE;
821#ifdef __BIG_ENDIAN
822 sfb->lfb = ioremap(mmio_base, 0x00c00000);
823#else
824 sfb->lfb = ioremap(mmio_base, 0x00800000);
825#endif
826 sfb->mmio = (smtc_regbaseaddress =
827 sfb->lfb + 0x00700000);
828 sfb->dp_regs = sfb->lfb + 0x00408000;
829 sfb->vp_regs = sfb->lfb + 0x0040c000;
830#ifdef __BIG_ENDIAN
831 if (sfb->fb.var.bits_per_pixel == 32) {
832 sfb->lfb += 0x800000;
833 dev_info(&pdev->dev, "sfb->lfb=%p", sfb->lfb);
834 }
835#endif
836 if (!smtc_regbaseaddress) {
837 dev_err(&pdev->dev,
838 "%s: unable to map memory mapped IO!",
839 sfb->fb.fix.id);
840 err = -ENOMEM;
841 goto failed_fb;
842 }
843
844 /* set MCLK = 14.31818 * (0x16 / 0x2) */
845 smtc_seqw(0x6a, 0x16);
846 smtc_seqw(0x6b, 0x02);
847 smtc_seqw(0x62, 0x3e);
848 /* enable PCI burst */
849 smtc_seqw(0x17, 0x20);
850 /* enable word swap */
851#ifdef __BIG_ENDIAN
852 if (sfb->fb.var.bits_per_pixel == 32)
853 smtc_seqw(0x17, 0x30);
854#endif
855 break;
856 case 0x720:
857 sfb->fb.fix.mmio_start = mmio_base;
858 sfb->fb.fix.mmio_len = 0x00200000;
859 smem_size = SM722_VIDEOMEMORYSIZE;
860 sfb->dp_regs = ioremap(mmio_base, 0x00a00000);
861 sfb->lfb = sfb->dp_regs + 0x00200000;
862 sfb->mmio = (smtc_regbaseaddress =
863 sfb->dp_regs + 0x000c0000);
864 sfb->vp_regs = sfb->dp_regs + 0x800;
865
866 smtc_seqw(0x62, 0xff);
867 smtc_seqw(0x6a, 0x0d);
868 smtc_seqw(0x6b, 0x02);
869 break;
870 default:
871 dev_err(&pdev->dev,
872 "No valid Silicon Motion display chip was detected!");
873
874 goto failed_fb;
875 }
876
877 /* can support 32 bpp */
878 if (15 == sfb->fb.var.bits_per_pixel)
879 sfb->fb.var.bits_per_pixel = 16;
880
881 sfb->fb.var.xres_virtual = sfb->fb.var.xres;
882 sfb->fb.var.yres_virtual = sfb->fb.var.yres;
883 err = smtc_map_smem(sfb, pdev, smem_size);
884 if (err)
885 goto failed;
886
887 smtcfb_setmode(sfb);
888
889 err = register_framebuffer(&sfb->fb);
890 if (err < 0)
891 goto failed;
892
893 dev_info(&pdev->dev,
894 "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.",
895 sfb->chip_id, sfb->chip_rev_id, sfb->fb.var.xres,
896 sfb->fb.var.yres, sfb->fb.var.bits_per_pixel);
897
898 return 0;
899
900failed:
901 dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail.");
902
903 smtc_unmap_smem(sfb);
904 smtc_unmap_mmio(sfb);
905failed_fb:
906 smtc_free_fb_info(sfb);
907
908failed_free:
909 pci_disable_device(pdev);
910
911 return err;
912}
913
914/*
915 * 0x710 (LynxEM)
916 * 0x712 (LynxEM+)
917 * 0x720 (Lynx3DM, Lynx3DM+)
918 */
919static const struct pci_device_id smtcfb_pci_table[] = {
920 { PCI_DEVICE(0x126f, 0x710), },
921 { PCI_DEVICE(0x126f, 0x712), },
922 { PCI_DEVICE(0x126f, 0x720), },
923 {0,}
924};
925
926static void smtcfb_pci_remove(struct pci_dev *pdev)
927{
928 struct smtcfb_info *sfb;
929
930 sfb = pci_get_drvdata(pdev);
931 smtc_unmap_smem(sfb);
932 smtc_unmap_mmio(sfb);
933 unregister_framebuffer(&sfb->fb);
934 smtc_free_fb_info(sfb);
935}
936
937#ifdef CONFIG_PM
938static int smtcfb_pci_suspend(struct device *device)
939{
940 struct pci_dev *pdev = to_pci_dev(device);
941 struct smtcfb_info *sfb;
942
943 sfb = pci_get_drvdata(pdev);
944
945 /* set the hw in sleep mode use external clock and self memory refresh
946 * so that we can turn off internal PLLs later on
947 */
948 smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
949 smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
950
951 console_lock();
952 fb_set_suspend(&sfb->fb, 1);
953 console_unlock();
954
955 /* additionally turn off all function blocks including internal PLLs */
956 smtc_seqw(0x21, 0xff);
957
958 return 0;
959}
960
961static int smtcfb_pci_resume(struct device *device)
962{
963 struct pci_dev *pdev = to_pci_dev(device);
964 struct smtcfb_info *sfb;
965
966 sfb = pci_get_drvdata(pdev);
967
968 /* reinit hardware */
969 sm7xx_init_hw();
970 switch (sfb->chip_id) {
971 case 0x710:
972 case 0x712:
973 /* set MCLK = 14.31818 * (0x16 / 0x2) */
974 smtc_seqw(0x6a, 0x16);
975 smtc_seqw(0x6b, 0x02);
976 smtc_seqw(0x62, 0x3e);
977 /* enable PCI burst */
978 smtc_seqw(0x17, 0x20);
979#ifdef __BIG_ENDIAN
980 if (sfb->fb.var.bits_per_pixel == 32)
981 smtc_seqw(0x17, 0x30);
982#endif
983 break;
984 case 0x720:
985 smtc_seqw(0x62, 0xff);
986 smtc_seqw(0x6a, 0x0d);
987 smtc_seqw(0x6b, 0x02);
988 break;
989 }
990
991 smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
992 smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
993
994 smtcfb_setmode(sfb);
995
996 console_lock();
997 fb_set_suspend(&sfb->fb, 0);
998 console_unlock();
999
1000 return 0;
1001}
1002
1003static SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume);
1004#define SM7XX_PM_OPS (&sm7xx_pm_ops)
1005
1006#else /* !CONFIG_PM */
1007
1008#define SM7XX_PM_OPS NULL
1009
1010#endif /* !CONFIG_PM */
1011
1012static struct pci_driver smtcfb_driver = {
1013 .name = "smtcfb",
1014 .id_table = smtcfb_pci_table,
1015 .probe = smtcfb_pci_probe,
1016 .remove = smtcfb_pci_remove,
1017 .driver.pm = SM7XX_PM_OPS,
1018};
1019
1020module_pci_driver(smtcfb_driver);
1021
1022MODULE_AUTHOR("Siliconmotion ");
1023MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");
1024MODULE_LICENSE("GPL");
diff --git a/drivers/staging/speakup/i18n.h b/drivers/staging/speakup/i18n.h
index 16a0871373d9..326d086f9d5a 100644
--- a/drivers/staging/speakup/i18n.h
+++ b/drivers/staging/speakup/i18n.h
@@ -3,7 +3,7 @@
3/* Internationalization declarations */ 3/* Internationalization declarations */
4 4
5enum msg_index_t { 5enum msg_index_t {
6 MSG_FIRST_INDEX , 6 MSG_FIRST_INDEX,
7 MSG_ANNOUNCEMENTS_START = MSG_FIRST_INDEX, 7 MSG_ANNOUNCEMENTS_START = MSG_FIRST_INDEX,
8 MSG_BLANK = MSG_ANNOUNCEMENTS_START, 8 MSG_BLANK = MSG_ANNOUNCEMENTS_START,
9 MSG_IAM_ALIVE, 9 MSG_IAM_ALIVE,
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index b12c76de60b0..3708bc13ae86 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -566,7 +566,7 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
566 if (ch >= ' ' && ch < '~') 566 if (ch >= ' ' && ch < '~')
567 *cp1++ = ch; 567 *cp1++ = ch;
568 else 568 else
569 cp1 += sprintf(cp1, "\\""x%02x", ch); 569 cp1 += sprintf(cp1, "\\x%02x", ch);
570 } 570 }
571 *cp1++ = '"'; 571 *cp1++ = '"';
572 *cp1++ = '\n'; 572 *cp1++ = '\n';
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
index 507fc9a1776e..a0315701c7d9 100644
--- a/drivers/staging/speakup/selection.c
+++ b/drivers/staging/speakup/selection.c
@@ -157,7 +157,7 @@ static void __speakup_paste_selection(struct work_struct *work)
157 pasted += count; 157 pasted += count;
158 } 158 }
159 remove_wait_queue(&vc->paste_wait, &wait); 159 remove_wait_queue(&vc->paste_wait, &wait);
160 current->state = TASK_RUNNING; 160 __set_current_state(TASK_RUNNING);
161 161
162 tty_buffer_unlock_exclusive(&vc->port); 162 tty_buffer_unlock_exclusive(&vc->port);
163 tty_ldisc_deref(ld); 163 tty_ldisc_deref(ld);
diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c
index f3aa4239dc68..01eddab93c66 100644
--- a/drivers/staging/speakup/synth.c
+++ b/drivers/staging/speakup/synth.c
@@ -30,9 +30,9 @@ struct speakup_info_t speakup_info = {
30 * must be taken at each kernel->speakup transition and released at 30 * must be taken at each kernel->speakup transition and released at
31 * each corresponding speakup->kernel transition. 31 * each corresponding speakup->kernel transition.
32 * 32 *
33 * The progression thread only interferes with the speakup machinery through 33 * The progression thread only interferes with the speakup machinery
34 * the synth buffer, so only needs to take the lock while tinkering with 34 * through the synth buffer, so only needs to take the lock
35 * the buffer. 35 * while tinkering with the buffer.
36 * 36 *
37 * We use spin_lock/trylock_irqsave and spin_unlock_irqrestore with this 37 * We use spin_lock/trylock_irqsave and spin_unlock_irqrestore with this
38 * spinlock because speakup needs to disable the keyboard IRQ. 38 * spinlock because speakup needs to disable the keyboard IRQ.
diff --git a/drivers/staging/unisys/Kconfig b/drivers/staging/unisys/Kconfig
index ac080c9dcf46..19fcb3465509 100644
--- a/drivers/staging/unisys/Kconfig
+++ b/drivers/staging/unisys/Kconfig
@@ -12,7 +12,6 @@ if UNISYSSPAR
12source "drivers/staging/unisys/visorutil/Kconfig" 12source "drivers/staging/unisys/visorutil/Kconfig"
13source "drivers/staging/unisys/visorchannel/Kconfig" 13source "drivers/staging/unisys/visorchannel/Kconfig"
14source "drivers/staging/unisys/visorchipset/Kconfig" 14source "drivers/staging/unisys/visorchipset/Kconfig"
15source "drivers/staging/unisys/channels/Kconfig"
16source "drivers/staging/unisys/uislib/Kconfig" 15source "drivers/staging/unisys/uislib/Kconfig"
17source "drivers/staging/unisys/virtpci/Kconfig" 16source "drivers/staging/unisys/virtpci/Kconfig"
18source "drivers/staging/unisys/virthba/Kconfig" 17source "drivers/staging/unisys/virthba/Kconfig"
diff --git a/drivers/staging/unisys/Makefile b/drivers/staging/unisys/Makefile
index b988d6940aae..68b9925e7d5e 100644
--- a/drivers/staging/unisys/Makefile
+++ b/drivers/staging/unisys/Makefile
@@ -4,7 +4,6 @@
4obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil/ 4obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil/
5obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel/ 5obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel/
6obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset/ 6obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset/
7obj-$(CONFIG_UNISYS_CHANNELSTUB) += channels/
8obj-$(CONFIG_UNISYS_UISLIB) += uislib/ 7obj-$(CONFIG_UNISYS_UISLIB) += uislib/
9obj-$(CONFIG_UNISYS_VIRTPCI) += virtpci/ 8obj-$(CONFIG_UNISYS_VIRTPCI) += virtpci/
10obj-$(CONFIG_UNISYS_VIRTHBA) += virthba/ 9obj-$(CONFIG_UNISYS_VIRTHBA) += virthba/
diff --git a/drivers/staging/unisys/channels/Kconfig b/drivers/staging/unisys/channels/Kconfig
deleted file mode 100644
index 179c6cea2824..000000000000
--- a/drivers/staging/unisys/channels/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Unisys channels configuration
3#
4
5config UNISYS_CHANNELSTUB
6 tristate "Unisys channelstub driver"
7 depends on UNISYSSPAR && UNISYS_VISORUTIL
8 ---help---
9 If you say Y here, you will enable the Unisys channels driver.
10
diff --git a/drivers/staging/unisys/channels/Makefile b/drivers/staging/unisys/channels/Makefile
deleted file mode 100644
index adc184206035..000000000000
--- a/drivers/staging/unisys/channels/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1#
2# Makefile for Unisys channelstub
3#
4
5obj-$(CONFIG_UNISYS_CHANNELSTUB) += visorchannelstub.o
6
7visorchannelstub-y := channel.o chanstub.o
8
9ccflags-y += -Idrivers/staging/unisys/include
10ccflags-y += -Idrivers/staging/unisys/common-spar/include
11ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c
deleted file mode 100644
index 74cc4d6b515f..000000000000
--- a/drivers/staging/unisys/channels/channel.c
+++ /dev/null
@@ -1,219 +0,0 @@
1/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
2 * All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for more
13 * details.
14 */
15
16#include <linux/kernel.h>
17#ifdef CONFIG_MODVERSIONS
18#include <config/modversions.h>
19#endif
20#include <linux/module.h>
21#include <linux/init.h> /* for module_init and module_exit */
22#include <linux/slab.h> /* for memcpy */
23#include <linux/types.h>
24
25/* Implementation of exported functions for Supervisor channels */
26#include "channel.h"
27
28/*
29 * Routine Description:
30 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
31 * Queue of the Channel pointed to by pChannel
32 *
33 * Parameters:
34 * pChannel: (IN) points to the IO Channel
35 * Queue: (IN) nth Queue of the IO Channel
36 * pSignal: (IN) pointer to the signal
37 *
38 * Assumptions:
39 * - pChannel, Queue and pSignal are valid.
40 * - If insertion fails due to a full queue, the caller will determine the
41 * retry policy (e.g. wait & try again, report an error, etc.).
42 *
43 * Return value:
44 * 1 if the insertion succeeds, 0 if the queue was full.
45 */
46unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue,
47 void *sig)
48{
49 void __iomem *psignal;
50 unsigned int head, tail, nof;
51
52 struct signal_queue_header __iomem *pqhdr =
53 (struct signal_queue_header __iomem *)
54 ((char __iomem *)ch + readq(&ch->ch_space_offset))
55 + queue;
56
57 /* capture current head and tail */
58 head = readl(&pqhdr->head);
59 tail = readl(&pqhdr->tail);
60
61 /* queue is full if (head + 1) % n equals tail */
62 if (((head + 1) % readl(&pqhdr->max_slots)) == tail) {
63 nof = readq(&pqhdr->num_overflows) + 1;
64 writeq(nof, &pqhdr->num_overflows);
65 return 0;
66 }
67
68 /* increment the head index */
69 head = (head + 1) % readl(&pqhdr->max_slots);
70
71 /* copy signal to the head location from the area pointed to
72 * by pSignal
73 */
74 psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
75 (head * readl(&pqhdr->signal_size));
76 memcpy_toio(psignal, sig, readl(&pqhdr->signal_size));
77
78 mb(); /* channel synch */
79 writel(head, &pqhdr->head);
80
81 writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent);
82 return 1;
83}
84EXPORT_SYMBOL_GPL(spar_signal_insert);
85
86/*
87 * Routine Description:
88 * Removes one signal from Channel pChannel's nth Queue at the
89 * time of the call and copies it into the memory pointed to by
90 * pSignal.
91 *
92 * Parameters:
93 * pChannel: (IN) points to the IO Channel
94 * Queue: (IN) nth Queue of the IO Channel
95 * pSignal: (IN) pointer to where the signals are to be copied
96 *
97 * Assumptions:
98 * - pChannel and Queue are valid.
99 * - pSignal points to a memory area large enough to hold queue's SignalSize
100 *
101 * Return value:
102 * 1 if the removal succeeds, 0 if the queue was empty.
103 */
104unsigned char
105spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig)
106{
107 void __iomem *psource;
108 unsigned int head, tail;
109 struct signal_queue_header __iomem *pqhdr =
110 (struct signal_queue_header __iomem *)((char __iomem *)ch +
111 readq(&ch->ch_space_offset)) + queue;
112
113 /* capture current head and tail */
114 head = readl(&pqhdr->head);
115 tail = readl(&pqhdr->tail);
116
117 /* queue is empty if the head index equals the tail index */
118 if (head == tail) {
119 writeq(readq(&pqhdr->num_empty) + 1, &pqhdr->num_empty);
120 return 0;
121 }
122
123 /* advance past the 'empty' front slot */
124 tail = (tail + 1) % readl(&pqhdr->max_slots);
125
126 /* copy signal from tail location to the area pointed to by pSignal */
127 psource = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
128 (tail * readl(&pqhdr->signal_size));
129 memcpy_fromio(sig, psource, readl(&pqhdr->signal_size));
130
131 mb(); /* channel synch */
132 writel(tail, &pqhdr->tail);
133
134 writeq(readq(&pqhdr->num_received) + 1,
135 &pqhdr->num_received);
136 return 1;
137}
138EXPORT_SYMBOL_GPL(spar_signal_remove);
139
140/*
141 * Routine Description:
142 * Removes all signals present in Channel pChannel's nth Queue at the
143 * time of the call and copies them into the memory pointed to by
144 * pSignal. Returns the # of signals copied as the value of the routine.
145 *
146 * Parameters:
147 * pChannel: (IN) points to the IO Channel
148 * Queue: (IN) nth Queue of the IO Channel
149 * pSignal: (IN) pointer to where the signals are to be copied
150 *
151 * Assumptions:
152 * - pChannel and Queue are valid.
153 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
154 * # of signals, each of which is Queue's SignalSize.
155 *
156 * Return value:
157 * # of signals copied.
158 */
159unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
160 void *sig)
161{
162 void *psource;
163 unsigned int head, tail, count = 0;
164 struct signal_queue_header *pqhdr =
165 (struct signal_queue_header *)((char *)ch +
166 ch->ch_space_offset) + queue;
167
168 /* capture current head and tail */
169 head = pqhdr->head;
170 tail = pqhdr->tail;
171
172 /* queue is empty if the head index equals the tail index */
173 if (head == tail)
174 return 0;
175
176 while (head != tail) {
177 /* advance past the 'empty' front slot */
178 tail = (tail + 1) % pqhdr->max_slots;
179
180 /* copy signal from tail location to the area pointed
181 * to by pSignal
182 */
183 psource =
184 (char *)pqhdr + pqhdr->sig_base_offset +
185 (tail * pqhdr->signal_size);
186 memcpy((char *)sig + (pqhdr->signal_size * count),
187 psource, pqhdr->signal_size);
188
189 mb(); /* channel synch */
190 pqhdr->tail = tail;
191
192 count++;
193 pqhdr->num_received++;
194 }
195
196 return count;
197}
198
199/*
200 * Routine Description:
201 * Determine whether a signal queue is empty.
202 *
203 * Parameters:
204 * pChannel: (IN) points to the IO Channel
205 * Queue: (IN) nth Queue of the IO Channel
206 *
207 * Return value:
208 * 1 if the signal queue is empty, 0 otherwise.
209 */
210unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,
211 u32 queue)
212{
213 struct signal_queue_header __iomem *pqhdr =
214 (struct signal_queue_header __iomem *)((char __iomem *)ch +
215 readq(&ch->ch_space_offset)) + queue;
216 return readl(&pqhdr->head) == readl(&pqhdr->tail);
217}
218EXPORT_SYMBOL_GPL(spar_signalqueue_empty);
219
diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c
deleted file mode 100644
index b6fd126f16f1..000000000000
--- a/drivers/staging/unisys/channels/chanstub.c
+++ /dev/null
@@ -1,75 +0,0 @@
1/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
2 * All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for more
13 * details.
14 */
15
16#define EXPORT_SYMTAB
17#include <linux/kernel.h>
18#ifdef CONFIG_MODVERSIONS
19#include <config/modversions.h>
20#endif
21#include <linux/module.h>
22#include <linux/init.h> /* for module_init and module_exit */
23#include <linux/slab.h> /* for memcpy */
24#include <linux/types.h>
25
26#include "channel.h"
27#include "chanstub.h"
28#include "timskmod.h"
29#include "version.h"
30
31static __init int
32channel_mod_init(void)
33{
34 if (!unisys_spar_platform)
35 return -ENODEV;
36 return 0;
37}
38
39static __exit void
40channel_mod_exit(void)
41{
42}
43
44unsigned char
45SignalInsert_withLock(struct channel_header __iomem *pChannel, u32 Queue,
46 void *pSignal, spinlock_t *lock)
47{
48 unsigned char result;
49 unsigned long flags;
50
51 spin_lock_irqsave(lock, flags);
52 result = spar_signal_insert(pChannel, Queue, pSignal);
53 spin_unlock_irqrestore(lock, flags);
54 return result;
55}
56
57unsigned char
58SignalRemove_withLock(struct channel_header __iomem *pChannel, u32 Queue,
59 void *pSignal, spinlock_t *lock)
60{
61 unsigned char result;
62
63 spin_lock(lock);
64 result = spar_signal_remove(pChannel, Queue, pSignal);
65 spin_unlock(lock);
66 return result;
67}
68
69module_init(channel_mod_init);
70module_exit(channel_mod_exit);
71
72MODULE_LICENSE("GPL");
73MODULE_AUTHOR("Bryan Glaudel");
74MODULE_ALIAS("uischan");
75 /* this is extracted during depmod and kept in modules.dep */
diff --git a/drivers/staging/unisys/channels/chanstub.h b/drivers/staging/unisys/channels/chanstub.h
deleted file mode 100644
index 1531759a1b31..000000000000
--- a/drivers/staging/unisys/channels/chanstub.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
2 * All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for more
13 * details.
14 */
15
16#ifndef __CHANSTUB_H__
17#define __CHANSTUB_H__
18unsigned char SignalInsert_withLock(struct channel_header __iomem *pChannel,
19 u32 Queue, void *pSignal, spinlock_t *lock);
20unsigned char SignalRemove_withLock(struct channel_header __iomem *pChannel,
21 u32 Queue, void *pSignal, spinlock_t *lock);
22
23#endif
diff --git a/drivers/staging/unisys/common-spar/include/version.h b/drivers/staging/unisys/common-spar/include/version.h
index f25208fc3ed1..83d1da7a2f81 100644
--- a/drivers/staging/unisys/common-spar/include/version.h
+++ b/drivers/staging/unisys/common-spar/include/version.h
@@ -30,7 +30,6 @@
30#define SPARVER4 "0" 30#define SPARVER4 "0"
31 31
32#define VERSION SPARVER1 "." SPARVER2 "." SPARVER3 "." SPARVER4 32#define VERSION SPARVER1 "." SPARVER2 "." SPARVER3 "." SPARVER4
33#define VERSIONDATE __DATE__
34 33
35/* Here are various version forms needed in Windows environments. 34/* Here are various version forms needed in Windows environments.
36 */ 35 */
diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h
index cff7983dab85..4019a0d63645 100644
--- a/drivers/staging/unisys/include/timskmod.h
+++ b/drivers/staging/unisys/include/timskmod.h
@@ -133,7 +133,7 @@
133 * x - the number of seconds to sleep. 133 * x - the number of seconds to sleep.
134 */ 134 */
135#define SLEEP(x) \ 135#define SLEEP(x) \
136 do { current->state = TASK_INTERRUPTIBLE; \ 136 do { __set_current_state(TASK_INTERRUPTIBLE); \
137 schedule_timeout((x)*HZ); \ 137 schedule_timeout((x)*HZ); \
138 } while (0) 138 } while (0)
139 139
@@ -141,7 +141,7 @@
141 * x - the number of jiffies to sleep. 141 * x - the number of jiffies to sleep.
142 */ 142 */
143#define SLEEPJIFFIES(x) \ 143#define SLEEPJIFFIES(x) \
144 do { current->state = TASK_INTERRUPTIBLE; \ 144 do { __set_current_state(TASK_INTERRUPTIBLE); \
145 schedule_timeout(x); \ 145 schedule_timeout(x); \
146 } while (0) 146 } while (0)
147 147
diff --git a/drivers/staging/unisys/uislib/Kconfig b/drivers/staging/unisys/uislib/Kconfig
index 6b134e267904..a712eb82224a 100644
--- a/drivers/staging/unisys/uislib/Kconfig
+++ b/drivers/staging/unisys/uislib/Kconfig
@@ -4,7 +4,7 @@
4 4
5config UNISYS_UISLIB 5config UNISYS_UISLIB
6 tristate "Unisys uislib driver" 6 tristate "Unisys uislib driver"
7 depends on UNISYSSPAR && UNISYS_VISORCHIPSET && UNISYS_CHANNELSTUB && HAS_IOMEM 7 depends on UNISYSSPAR && UNISYS_VISORCHIPSET && HAS_IOMEM
8 ---help--- 8 ---help---
9 If you say Y here, you will enable the Unisys uislib driver. 9 If you say Y here, you will enable the Unisys uislib driver.
10 10
diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c
index 7c87452a9f14..a9eeddeba735 100644
--- a/drivers/staging/unisys/uislib/uislib.c
+++ b/drivers/staging/unisys/uislib/uislib.c
@@ -41,7 +41,6 @@
41 41
42#include "sparstop.h" 42#include "sparstop.h"
43#include "visorchipset.h" 43#include "visorchipset.h"
44#include "chanstub.h"
45#include "version.h" 44#include "version.h"
46#include "guestlinuxdebug.h" 45#include "guestlinuxdebug.h"
47 46
@@ -59,8 +58,8 @@
59/* global function pointers that act as callback functions into virtpcimod */ 58/* global function pointers that act as callback functions into virtpcimod */
60int (*virt_control_chan_func)(struct guest_msgs *); 59int (*virt_control_chan_func)(struct guest_msgs *);
61 60
62static int ProcReadBufferValid; 61static int debug_buf_valid;
63static char *ProcReadBuffer; /* Note this MUST be global, 62static char *debug_buf; /* Note this MUST be global,
64 * because the contents must */ 63 * because the contents must */
65static unsigned int chipset_inited; 64static unsigned int chipset_inited;
66 65
@@ -71,24 +70,24 @@ static unsigned int chipset_inited;
71 UIS_THREAD_WAIT; \ 70 UIS_THREAD_WAIT; \
72 } while (1) 71 } while (1)
73 72
74static struct bus_info *BusListHead; 73static struct bus_info *bus_list;
75static rwlock_t BusListLock; 74static rwlock_t bus_list_lock;
76static int BusListCount; /* number of buses in the list */ 75static int bus_list_count; /* number of buses in the list */
77static int MaxBusCount; /* maximum number of buses expected */ 76static int max_bus_count; /* maximum number of buses expected */
78static u64 PhysicalDataChan; 77static u64 phys_data_chan;
79static int PlatformNumber; 78static int platform_no;
80 79
81static struct uisthread_info Incoming_ThreadInfo; 80static struct uisthread_info incoming_ti;
82static BOOL Incoming_Thread_Started = FALSE; 81static BOOL incoming_started = FALSE;
83static LIST_HEAD(List_Polling_Device_Channels); 82static LIST_HEAD(poll_dev_chan);
84static unsigned long long tot_moved_to_tail_cnt; 83static unsigned long long tot_moved_to_tail_cnt;
85static unsigned long long tot_wait_cnt; 84static unsigned long long tot_wait_cnt;
86static unsigned long long tot_wakeup_cnt; 85static unsigned long long tot_wakeup_cnt;
87static unsigned long long tot_schedule_cnt; 86static unsigned long long tot_schedule_cnt;
88static int en_smart_wakeup = 1; 87static int en_smart_wakeup = 1;
89static DEFINE_SEMAPHORE(Lock_Polling_Device_Channels); /* unlocked */ 88static DEFINE_SEMAPHORE(poll_dev_lock); /* unlocked */
90static DECLARE_WAIT_QUEUE_HEAD(Wakeup_Polling_Device_Channels); 89static DECLARE_WAIT_QUEUE_HEAD(poll_dev_wake_q);
91static int Go_Polling_Device_Channels; 90static int poll_dev_start;
92 91
93#define CALLHOME_PROC_ENTRY_FN "callhome" 92#define CALLHOME_PROC_ENTRY_FN "callhome"
94#define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled" 93#define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
@@ -115,7 +114,7 @@ static unsigned long long cycles_before_wait, wait_cycles;
115/*****************************************************/ 114/*****************************************************/
116 115
117static ssize_t info_debugfs_read(struct file *file, char __user *buf, 116static ssize_t info_debugfs_read(struct file *file, char __user *buf,
118 size_t len, loff_t *offset); 117 size_t len, loff_t *offset);
119static const struct file_operations debugfs_info_fops = { 118static const struct file_operations debugfs_info_fops = {
120 .read = info_debugfs_read, 119 .read = info_debugfs_read,
121}; 120};
@@ -129,58 +128,52 @@ init_msg_header(struct controlvm_message *msg, u32 id, uint rsp, uint svr)
129 msg->hdr.flags.server = svr; 128 msg->hdr.flags.server = svr;
130} 129}
131 130
132static __iomem void * 131static __iomem void *init_vbus_channel(u64 ch_addr, u32 ch_bytes)
133init_vbus_channel(u64 channelAddr, u32 channelBytes)
134{ 132{
135 void __iomem *rc = NULL; 133 void __iomem *ch = uislib_ioremap_cache(ch_addr, ch_bytes);
136 void __iomem *pChan = uislib_ioremap_cache(channelAddr, channelBytes);
137 134
138 if (!pChan) { 135 if (!ch) {
139 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", 136 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
140 (unsigned long long) channelAddr, 137 (unsigned long long)ch_addr,
141 (unsigned long long) channelBytes); 138 (unsigned long long)ch_bytes);
142 rc = NULL; 139 return NULL;
143 goto Away;
144 } 140 }
145 if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan)) { 141 if (!SPAR_VBUS_CHANNEL_OK_CLIENT(ch)) {
146 ERRDRV("%s channel cannot be used", __func__); 142 ERRDRV("%s channel cannot be used", __func__);
147 uislib_iounmap(pChan); 143 uislib_iounmap(ch);
148 rc = NULL; 144 return NULL;
149 goto Away;
150 } 145 }
151 rc = pChan; 146 return ch;
152Away:
153 return rc;
154} 147}
155 148
156static int 149static int
157create_bus(struct controlvm_message *msg, char *buf) 150create_bus(struct controlvm_message *msg, char *buf)
158{ 151{
159 u32 busNo, deviceCount; 152 u32 bus_no, dev_count;
160 struct bus_info *tmp, *bus; 153 struct bus_info *tmp, *bus;
161 size_t size; 154 size_t size;
162 155
163 if (MaxBusCount == BusListCount) { 156 if (max_bus_count == bus_list_count) {
164 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n", 157 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
165 MaxBusCount); 158 max_bus_count);
166 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, MaxBusCount, 159 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, max_bus_count,
167 POSTCODE_SEVERITY_ERR); 160 POSTCODE_SEVERITY_ERR);
168 return CONTROLVM_RESP_ERROR_MAX_BUSES; 161 return CONTROLVM_RESP_ERROR_MAX_BUSES;
169 } 162 }
170 163
171 busNo = msg->cmd.create_bus.bus_no; 164 bus_no = msg->cmd.create_bus.bus_no;
172 deviceCount = msg->cmd.create_bus.dev_count; 165 dev_count = msg->cmd.create_bus.dev_count;
173 166
174 POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount, 167 POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, bus_no, dev_count,
175 POSTCODE_SEVERITY_INFO); 168 POSTCODE_SEVERITY_INFO);
176 169
177 size = 170 size =
178 sizeof(struct bus_info) + 171 sizeof(struct bus_info) +
179 (deviceCount * sizeof(struct device_info *)); 172 (dev_count * sizeof(struct device_info *));
180 bus = kzalloc(size, GFP_ATOMIC); 173 bus = kzalloc(size, GFP_ATOMIC);
181 if (!bus) { 174 if (!bus) {
182 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n"); 175 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
183 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo, 176 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no,
184 POSTCODE_SEVERITY_ERR); 177 POSTCODE_SEVERITY_ERR);
185 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED; 178 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
186 } 179 }
@@ -191,27 +184,29 @@ create_bus(struct controlvm_message *msg, char *buf)
191 if (msg->hdr.flags.test_message) { 184 if (msg->hdr.flags.test_message) {
192 /* This implies we're the IOVM so set guest handle to 0... */ 185 /* This implies we're the IOVM so set guest handle to 0... */
193 bus->guest_handle = 0; 186 bus->guest_handle = 0;
194 bus->bus_no = busNo; 187 bus->bus_no = bus_no;
195 bus->local_vnic = 1; 188 bus->local_vnic = 1;
196 } else 189 } else {
197 bus->bus_no = bus->guest_handle = busNo; 190 bus->bus_no = bus_no;
198 sprintf(bus->name, "%d", (int) bus->bus_no); 191 bus->guest_handle = bus_no;
199 bus->device_count = deviceCount; 192 }
193 sprintf(bus->name, "%d", (int)bus->bus_no);
194 bus->device_count = dev_count;
200 bus->device = 195 bus->device =
201 (struct device_info **) ((char *) bus + sizeof(struct bus_info)); 196 (struct device_info **)((char *)bus + sizeof(struct bus_info));
202 bus->bus_inst_uuid = msg->cmd.create_bus.bus_inst_uuid; 197 bus->bus_inst_uuid = msg->cmd.create_bus.bus_inst_uuid;
203 bus->bus_channel_bytes = 0; 198 bus->bus_channel_bytes = 0;
204 bus->bus_channel = NULL; 199 bus->bus_channel = NULL;
205 200
206 /* add bus to our bus list - but check for duplicates first */ 201 /* add bus to our bus list - but check for duplicates first */
207 read_lock(&BusListLock); 202 read_lock(&bus_list_lock);
208 for (tmp = BusListHead; tmp; tmp = tmp->next) { 203 for (tmp = bus_list; tmp; tmp = tmp->next) {
209 if (tmp->bus_no == bus->bus_no) 204 if (tmp->bus_no == bus->bus_no)
210 break; 205 break;
211 } 206 }
212 read_unlock(&BusListLock); 207 read_unlock(&bus_list_lock);
213 if (tmp) { 208 if (tmp) {
214 /* found a bus already in the list with same busNo - 209 /* found a bus already in the list with same bus_no -
215 * reject add 210 * reject add
216 */ 211 */
217 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n", 212 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
@@ -221,8 +216,8 @@ create_bus(struct controlvm_message *msg, char *buf)
221 kfree(bus); 216 kfree(bus);
222 return CONTROLVM_RESP_ERROR_ALREADY_DONE; 217 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
223 } 218 }
224 if ((msg->cmd.create_bus.channel_addr != 0) 219 if ((msg->cmd.create_bus.channel_addr != 0) &&
225 && (msg->cmd.create_bus.channel_bytes != 0)) { 220 (msg->cmd.create_bus.channel_bytes != 0)) {
226 bus->bus_channel_bytes = msg->cmd.create_bus.channel_bytes; 221 bus->bus_channel_bytes = msg->cmd.create_bus.channel_bytes;
227 bus->bus_channel = 222 bus->bus_channel =
228 init_vbus_channel(msg->cmd.create_bus.channel_addr, 223 init_vbus_channel(msg->cmd.create_bus.channel_addr,
@@ -233,9 +228,9 @@ create_bus(struct controlvm_message *msg, char *buf)
233 struct guest_msgs cmd; 228 struct guest_msgs cmd;
234 229
235 cmd.msgtype = GUEST_ADD_VBUS; 230 cmd.msgtype = GUEST_ADD_VBUS;
236 cmd.add_vbus.bus_no = busNo; 231 cmd.add_vbus.bus_no = bus_no;
237 cmd.add_vbus.chanptr = bus->bus_channel; 232 cmd.add_vbus.chanptr = bus->bus_channel;
238 cmd.add_vbus.dev_count = deviceCount; 233 cmd.add_vbus.dev_count = dev_count;
239 cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid; 234 cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid;
240 cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid; 235 cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid;
241 if (!virt_control_chan_func) { 236 if (!virt_control_chan_func) {
@@ -256,15 +251,15 @@ create_bus(struct controlvm_message *msg, char *buf)
256 } 251 }
257 252
258 /* add bus at the head of our list */ 253 /* add bus at the head of our list */
259 write_lock(&BusListLock); 254 write_lock(&bus_list_lock);
260 if (!BusListHead) 255 if (!bus_list) {
261 BusListHead = bus; 256 bus_list = bus;
262 else { 257 } else {
263 bus->next = BusListHead; 258 bus->next = bus_list;
264 BusListHead = bus; 259 bus_list = bus;
265 } 260 }
266 BusListCount++; 261 bus_list_count++;
267 write_unlock(&BusListLock); 262 write_unlock(&bus_list_lock);
268 263
269 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->bus_no, 264 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->bus_no,
270 POSTCODE_SEVERITY_INFO); 265 POSTCODE_SEVERITY_INFO);
@@ -277,15 +272,15 @@ destroy_bus(struct controlvm_message *msg, char *buf)
277 int i; 272 int i;
278 struct bus_info *bus, *prev = NULL; 273 struct bus_info *bus, *prev = NULL;
279 struct guest_msgs cmd; 274 struct guest_msgs cmd;
280 u32 busNo; 275 u32 bus_no;
281 276
282 busNo = msg->cmd.destroy_bus.bus_no; 277 bus_no = msg->cmd.destroy_bus.bus_no;
283 278
284 read_lock(&BusListLock); 279 read_lock(&bus_list_lock);
285 280
286 bus = BusListHead; 281 bus = bus_list;
287 while (bus) { 282 while (bus) {
288 if (bus->bus_no == busNo) 283 if (bus->bus_no == bus_no)
289 break; 284 break;
290 prev = bus; 285 prev = bus;
291 bus = bus->next; 286 bus = bus->next;
@@ -293,8 +288,8 @@ destroy_bus(struct controlvm_message *msg, char *buf)
293 288
294 if (!bus) { 289 if (!bus) {
295 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n", 290 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
296 busNo); 291 bus_no);
297 read_unlock(&BusListLock); 292 read_unlock(&bus_list_lock);
298 return CONTROLVM_RESP_ERROR_ALREADY_DONE; 293 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
299 } 294 }
300 295
@@ -302,12 +297,12 @@ destroy_bus(struct controlvm_message *msg, char *buf)
302 for (i = 0; i < bus->device_count; i++) { 297 for (i = 0; i < bus->device_count; i++) {
303 if (bus->device[i] != NULL) { 298 if (bus->device[i] != NULL) {
304 LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.", 299 LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
305 i, busNo); 300 i, bus_no);
306 read_unlock(&BusListLock); 301 read_unlock(&bus_list_lock);
307 return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED; 302 return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED;
308 } 303 }
309 } 304 }
310 read_unlock(&BusListLock); 305 read_unlock(&bus_list_lock);
311 306
312 if (msg->hdr.flags.server) 307 if (msg->hdr.flags.server)
313 goto remove; 308 goto remove;
@@ -315,7 +310,7 @@ destroy_bus(struct controlvm_message *msg, char *buf)
315 /* client messages require us to call the virtpci callback associated 310 /* client messages require us to call the virtpci callback associated
316 with this bus. */ 311 with this bus. */
317 cmd.msgtype = GUEST_DEL_VBUS; 312 cmd.msgtype = GUEST_DEL_VBUS;
318 cmd.del_vbus.bus_no = busNo; 313 cmd.del_vbus.bus_no = bus_no;
319 if (!virt_control_chan_func) { 314 if (!virt_control_chan_func) {
320 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered."); 315 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
321 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; 316 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
@@ -327,13 +322,13 @@ destroy_bus(struct controlvm_message *msg, char *buf)
327 322
328 /* finally, remove the bus from the list */ 323 /* finally, remove the bus from the list */
329remove: 324remove:
330 write_lock(&BusListLock); 325 write_lock(&bus_list_lock);
331 if (prev) /* not at head */ 326 if (prev) /* not at head */
332 prev->next = bus->next; 327 prev->next = bus->next;
333 else 328 else
334 BusListHead = bus->next; 329 bus_list = bus->next;
335 BusListCount--; 330 bus_list_count--;
336 write_unlock(&BusListLock); 331 write_unlock(&bus_list_lock);
337 332
338 if (bus->bus_channel) { 333 if (bus->bus_channel) {
339 uislib_iounmap(bus->bus_channel); 334 uislib_iounmap(bus->bus_channel);
@@ -344,26 +339,26 @@ remove:
344 return CONTROLVM_RESP_SUCCESS; 339 return CONTROLVM_RESP_SUCCESS;
345} 340}
346 341
347static int 342static int create_device(struct controlvm_message *msg, char *buf)
348create_device(struct controlvm_message *msg, char *buf)
349{ 343{
350 struct device_info *dev; 344 struct device_info *dev;
351 struct bus_info *bus; 345 struct bus_info *bus;
352 u32 busNo, devNo; 346 struct guest_msgs cmd;
347 u32 bus_no, dev_no;
353 int result = CONTROLVM_RESP_SUCCESS; 348 int result = CONTROLVM_RESP_SUCCESS;
354 u64 minSize = MIN_IO_CHANNEL_SIZE; 349 u64 min_size = MIN_IO_CHANNEL_SIZE;
355 struct req_handler_info *pReqHandler; 350 struct req_handler_info *req_handler;
356 351
357 busNo = msg->cmd.create_device.bus_no; 352 bus_no = msg->cmd.create_device.bus_no;
358 devNo = msg->cmd.create_device.dev_no; 353 dev_no = msg->cmd.create_device.dev_no;
359 354
360 POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, 355 POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no,
361 POSTCODE_SEVERITY_INFO); 356 POSTCODE_SEVERITY_INFO);
362 357
363 dev = kzalloc(sizeof(struct device_info), GFP_ATOMIC); 358 dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
364 if (!dev) { 359 if (!dev) {
365 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n"); 360 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
366 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, 361 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
367 POSTCODE_SEVERITY_ERR); 362 POSTCODE_SEVERITY_ERR);
368 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED; 363 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
369 } 364 }
@@ -371,169 +366,157 @@ create_device(struct controlvm_message *msg, char *buf)
371 dev->channel_uuid = msg->cmd.create_device.data_type_uuid; 366 dev->channel_uuid = msg->cmd.create_device.data_type_uuid;
372 dev->intr = msg->cmd.create_device.intr; 367 dev->intr = msg->cmd.create_device.intr;
373 dev->channel_addr = msg->cmd.create_device.channel_addr; 368 dev->channel_addr = msg->cmd.create_device.channel_addr;
374 dev->bus_no = busNo; 369 dev->bus_no = bus_no;
375 dev->dev_no = devNo; 370 dev->dev_no = dev_no;
376 sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */ 371 sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */
377 sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo); 372 sprintf(dev->devid, "vbus%u:dev%u", (unsigned)bus_no, (unsigned)dev_no);
378 /* map the channel memory for the device. */ 373 /* map the channel memory for the device. */
379 if (msg->hdr.flags.test_message) 374 if (msg->hdr.flags.test_message) {
380 dev->chanptr = (void __iomem *)__va(dev->channel_addr); 375 dev->chanptr = (void __iomem *)__va(dev->channel_addr);
381 else { 376 } else {
382 pReqHandler = req_handler_find(dev->channel_uuid); 377 req_handler = req_handler_find(dev->channel_uuid);
383 if (pReqHandler) 378 if (req_handler)
384 /* generic service handler registered for this 379 /* generic service handler registered for this
385 * channel 380 * channel
386 */ 381 */
387 minSize = pReqHandler->min_channel_bytes; 382 min_size = req_handler->min_channel_bytes;
388 if (minSize > msg->cmd.create_device.channel_bytes) { 383 if (min_size > msg->cmd.create_device.channel_bytes) {
389 LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx", 384 LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
390 (ulong) msg->cmd.create_device.channel_bytes, 385 (ulong)msg->cmd.create_device.channel_bytes,
391 (ulong) minSize); 386 (ulong)min_size);
392 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, 387 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
393 POSTCODE_SEVERITY_ERR); 388 bus_no, POSTCODE_SEVERITY_ERR);
394 result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL; 389 result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL;
395 goto Away; 390 goto cleanup;
396 } 391 }
397 dev->chanptr = 392 dev->chanptr =
398 uislib_ioremap_cache(dev->channel_addr, 393 uislib_ioremap_cache(dev->channel_addr,
399 msg->cmd.create_device.channel_bytes); 394 msg->cmd.create_device.channel_bytes);
400 if (!dev->chanptr) { 395 if (!dev->chanptr) {
401 LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", 396 LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
402 dev->channel_addr, 397 dev->channel_addr,
403 msg->cmd.create_device.channel_bytes); 398 msg->cmd.create_device.channel_bytes);
404 result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED; 399 result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
405 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, 400 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
406 POSTCODE_SEVERITY_ERR); 401 bus_no, POSTCODE_SEVERITY_ERR);
407 goto Away; 402 goto cleanup;
408 } 403 }
409 } 404 }
410 dev->instance_uuid = msg->cmd.create_device.dev_inst_uuid; 405 dev->instance_uuid = msg->cmd.create_device.dev_inst_uuid;
411 dev->channel_bytes = msg->cmd.create_device.channel_bytes; 406 dev->channel_bytes = msg->cmd.create_device.channel_bytes;
412 407
413 read_lock(&BusListLock); 408 read_lock(&bus_list_lock);
414 for (bus = BusListHead; bus; bus = bus->next) { 409 for (bus = bus_list; bus; bus = bus->next) {
415 if (bus->bus_no == busNo) { 410 if (bus->bus_no != bus_no)
416 /* make sure the device number is valid */ 411 continue;
417 if (devNo >= bus->device_count) { 412 /* make sure the device number is valid */
418 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).", 413 if (dev_no >= bus->device_count) {
419 devNo, bus->device_count); 414 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
420 result = CONTROLVM_RESP_ERROR_MAX_DEVICES; 415 dev_no, bus->device_count);
416 result = CONTROLVM_RESP_ERROR_MAX_DEVICES;
417 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
418 bus_no, POSTCODE_SEVERITY_ERR);
419 read_unlock(&bus_list_lock);
420 goto cleanup;
421 }
422 /* make sure this device is not already set */
423 if (bus->device[dev_no]) {
424 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
425 dev_no);
426 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
427 dev_no, bus_no,
428 POSTCODE_SEVERITY_ERR);
429 result = CONTROLVM_RESP_ERROR_ALREADY_DONE;
430 read_unlock(&bus_list_lock);
431 goto cleanup;
432 }
433 read_unlock(&bus_list_lock);
434 /* the msg is bound for virtpci; send
435 * guest_msgs struct to callback
436 */
437 if (msg->hdr.flags.server) {
438 bus->device[dev_no] = dev;
439 POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no,
440 bus_no, POSTCODE_SEVERITY_INFO);
441 return CONTROLVM_RESP_SUCCESS;
442 }
443 if (uuid_le_cmp(dev->channel_uuid,
444 spar_vhba_channel_protocol_uuid) == 0) {
445 wait_for_valid_guid(&((struct channel_header __iomem *)
446 (dev->chanptr))->chtype);
447 if (!SPAR_VHBA_CHANNEL_OK_CLIENT(dev->chanptr)) {
448 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
449 dev_no);
421 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, 450 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
422 devNo, busNo, 451 dev_no, bus_no,
423 POSTCODE_SEVERITY_ERR); 452 POSTCODE_SEVERITY_ERR);
424 read_unlock(&BusListLock); 453 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
425 goto Away; 454 goto cleanup;
426 } 455 }
427 /* make sure this device is not already set */ 456 cmd.msgtype = GUEST_ADD_VHBA;
428 if (bus->device[devNo]) { 457 cmd.add_vhba.chanptr = dev->chanptr;
429 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.", 458 cmd.add_vhba.bus_no = bus_no;
430 devNo); 459 cmd.add_vhba.device_no = dev_no;
460 cmd.add_vhba.instance_uuid = dev->instance_uuid;
461 cmd.add_vhba.intr = dev->intr;
462 } else if (uuid_le_cmp(dev->channel_uuid,
463 spar_vnic_channel_protocol_uuid) == 0) {
464 wait_for_valid_guid(&((struct channel_header __iomem *)
465 (dev->chanptr))->chtype);
466 if (!SPAR_VNIC_CHANNEL_OK_CLIENT(dev->chanptr)) {
467 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
468 dev_no);
431 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, 469 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
432 devNo, busNo, 470 dev_no, bus_no,
433 POSTCODE_SEVERITY_ERR); 471 POSTCODE_SEVERITY_ERR);
434 result = CONTROLVM_RESP_ERROR_ALREADY_DONE; 472 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
435 read_unlock(&BusListLock); 473 goto cleanup;
436 goto Away;
437 } 474 }
438 read_unlock(&BusListLock); 475 cmd.msgtype = GUEST_ADD_VNIC;
439 /* the msg is bound for virtpci; send 476 cmd.add_vnic.chanptr = dev->chanptr;
440 * guest_msgs struct to callback 477 cmd.add_vnic.bus_no = bus_no;
441 */ 478 cmd.add_vnic.device_no = dev_no;
442 if (!msg->hdr.flags.server) { 479 cmd.add_vnic.instance_uuid = dev->instance_uuid;
443 struct guest_msgs cmd; 480 cmd.add_vhba.intr = dev->intr;
444 481 } else {
445 if (!uuid_le_cmp(dev->channel_uuid, 482 LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
446 spar_vhba_channel_protocol_uuid)) { 483 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
447 wait_for_valid_guid(&(( 484 bus_no, POSTCODE_SEVERITY_ERR);
448 struct channel_header 485 result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
449 __iomem *) (dev-> 486 goto cleanup;
450 chanptr))-> 487 }
451 chtype);
452 if (!SPAR_VHBA_CHANNEL_OK_CLIENT
453 (dev->chanptr)) {
454 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
455 devNo);
456 POSTCODE_LINUX_4
457 (DEVICE_CREATE_FAILURE_PC,
458 devNo, busNo,
459 POSTCODE_SEVERITY_ERR);
460 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
461 goto Away;
462 }
463 cmd.msgtype = GUEST_ADD_VHBA;
464 cmd.add_vhba.chanptr = dev->chanptr;
465 cmd.add_vhba.bus_no = busNo;
466 cmd.add_vhba.device_no = devNo;
467 cmd.add_vhba.instance_uuid =
468 dev->instance_uuid;
469 cmd.add_vhba.intr = dev->intr;
470 } else
471 if (!uuid_le_cmp(dev->channel_uuid,
472 spar_vnic_channel_protocol_uuid)) {
473 wait_for_valid_guid(&((
474 struct channel_header
475 __iomem *) (dev->
476 chanptr))->
477 chtype);
478 if (!SPAR_VNIC_CHANNEL_OK_CLIENT
479 (dev->chanptr)) {
480 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
481 devNo);
482 POSTCODE_LINUX_4
483 (DEVICE_CREATE_FAILURE_PC,
484 devNo, busNo,
485 POSTCODE_SEVERITY_ERR);
486 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
487 goto Away;
488 }
489 cmd.msgtype = GUEST_ADD_VNIC;
490 cmd.add_vnic.chanptr = dev->chanptr;
491 cmd.add_vnic.bus_no = busNo;
492 cmd.add_vnic.device_no = devNo;
493 cmd.add_vnic.instance_uuid =
494 dev->instance_uuid;
495 cmd.add_vhba.intr = dev->intr;
496 } else {
497 LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
498 POSTCODE_LINUX_4
499 (DEVICE_CREATE_FAILURE_PC, devNo,
500 busNo, POSTCODE_SEVERITY_ERR);
501 result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
502 goto Away;
503 }
504 488
505 if (!virt_control_chan_func) { 489 if (!virt_control_chan_func) {
506 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered."); 490 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
507 POSTCODE_LINUX_4 491 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
508 (DEVICE_CREATE_FAILURE_PC, devNo, 492 bus_no, POSTCODE_SEVERITY_ERR);
509 busNo, POSTCODE_SEVERITY_ERR); 493 result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
510 result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; 494 goto cleanup;
511 goto Away; 495 }
512 }
513 496
514 if (!virt_control_chan_func(&cmd)) { 497 if (!virt_control_chan_func(&cmd)) {
515 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error."); 498 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
516 POSTCODE_LINUX_4 499 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
517 (DEVICE_CREATE_FAILURE_PC, devNo, 500 bus_no, POSTCODE_SEVERITY_ERR);
518 busNo, POSTCODE_SEVERITY_ERR); 501 result =
519 result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; 502 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
520 goto Away; 503 goto cleanup;
521 }
522 }
523 bus->device[devNo] = dev;
524 POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, devNo, busNo,
525 POSTCODE_SEVERITY_INFO);
526 return CONTROLVM_RESP_SUCCESS;
527 } 504 }
505
506 bus->device[dev_no] = dev;
507 POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no,
508 bus_no, POSTCODE_SEVERITY_INFO);
509 return CONTROLVM_RESP_SUCCESS;
528 } 510 }
529 read_unlock(&BusListLock); 511 read_unlock(&bus_list_lock);
530 512
531 LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo); 513 LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.",
532 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, 514 bus_no);
515 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
533 POSTCODE_SEVERITY_ERR); 516 POSTCODE_SEVERITY_ERR);
534 result = CONTROLVM_RESP_ERROR_BUS_INVALID; 517 result = CONTROLVM_RESP_ERROR_BUS_INVALID;
535 518
536Away: 519cleanup:
537 if (!msg->hdr.flags.test_message) { 520 if (!msg->hdr.flags.test_message) {
538 uislib_iounmap(dev->chanptr); 521 uislib_iounmap(dev->chanptr);
539 dev->chanptr = NULL; 522 dev->chanptr = NULL;
@@ -543,32 +526,31 @@ Away:
543 return result; 526 return result;
544} 527}
545 528
546static int 529static int pause_device(struct controlvm_message *msg)
547pause_device(struct controlvm_message *msg)
548{ 530{
549 u32 busNo, devNo; 531 u32 bus_no, dev_no;
550 struct bus_info *bus; 532 struct bus_info *bus;
551 struct device_info *dev; 533 struct device_info *dev;
552 struct guest_msgs cmd; 534 struct guest_msgs cmd;
553 int retval = CONTROLVM_RESP_SUCCESS; 535 int retval = CONTROLVM_RESP_SUCCESS;
554 536
555 busNo = msg->cmd.device_change_state.bus_no; 537 bus_no = msg->cmd.device_change_state.bus_no;
556 devNo = msg->cmd.device_change_state.dev_no; 538 dev_no = msg->cmd.device_change_state.dev_no;
557 539
558 read_lock(&BusListLock); 540 read_lock(&bus_list_lock);
559 for (bus = BusListHead; bus; bus = bus->next) { 541 for (bus = bus_list; bus; bus = bus->next) {
560 if (bus->bus_no == busNo) { 542 if (bus->bus_no == bus_no) {
561 /* make sure the device number is valid */ 543 /* make sure the device number is valid */
562 if (devNo >= bus->device_count) { 544 if (dev_no >= bus->device_count) {
563 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).", 545 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
564 devNo, bus->device_count); 546 dev_no, bus->device_count);
565 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; 547 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
566 } else { 548 } else {
567 /* make sure this device exists */ 549 /* make sure this device exists */
568 dev = bus->device[devNo]; 550 dev = bus->device[dev_no];
569 if (!dev) { 551 if (!dev) {
570 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.", 552 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
571 devNo); 553 dev_no);
572 retval = 554 retval =
573 CONTROLVM_RESP_ERROR_ALREADY_DONE; 555 CONTROLVM_RESP_ERROR_ALREADY_DONE;
574 } 556 }
@@ -578,20 +560,20 @@ pause_device(struct controlvm_message *msg)
578 } 560 }
579 if (!bus) { 561 if (!bus) {
580 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist", 562 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
581 busNo); 563 bus_no);
582 retval = CONTROLVM_RESP_ERROR_BUS_INVALID; 564 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
583 } 565 }
584 read_unlock(&BusListLock); 566 read_unlock(&bus_list_lock);
585 if (retval == CONTROLVM_RESP_SUCCESS) { 567 if (retval == CONTROLVM_RESP_SUCCESS) {
586 /* the msg is bound for virtpci; send 568 /* the msg is bound for virtpci; send
587 * guest_msgs struct to callback 569 * guest_msgs struct to callback
588 */ 570 */
589 if (!uuid_le_cmp(dev->channel_uuid, 571 if (uuid_le_cmp(dev->channel_uuid,
590 spar_vhba_channel_protocol_uuid)) { 572 spar_vhba_channel_protocol_uuid) == 0) {
591 cmd.msgtype = GUEST_PAUSE_VHBA; 573 cmd.msgtype = GUEST_PAUSE_VHBA;
592 cmd.pause_vhba.chanptr = dev->chanptr; 574 cmd.pause_vhba.chanptr = dev->chanptr;
593 } else if (!uuid_le_cmp(dev->channel_uuid, 575 } else if (uuid_le_cmp(dev->channel_uuid,
594 spar_vnic_channel_protocol_uuid)) { 576 spar_vnic_channel_protocol_uuid) == 0) {
595 cmd.msgtype = GUEST_PAUSE_VNIC; 577 cmd.msgtype = GUEST_PAUSE_VNIC;
596 cmd.pause_vnic.chanptr = dev->chanptr; 578 cmd.pause_vnic.chanptr = dev->chanptr;
597 } else { 579 } else {
@@ -611,32 +593,31 @@ pause_device(struct controlvm_message *msg)
611 return retval; 593 return retval;
612} 594}
613 595
614static int 596static int resume_device(struct controlvm_message *msg)
615resume_device(struct controlvm_message *msg)
616{ 597{
617 u32 busNo, devNo; 598 u32 bus_no, dev_no;
618 struct bus_info *bus; 599 struct bus_info *bus;
619 struct device_info *dev; 600 struct device_info *dev;
620 struct guest_msgs cmd; 601 struct guest_msgs cmd;
621 int retval = CONTROLVM_RESP_SUCCESS; 602 int retval = CONTROLVM_RESP_SUCCESS;
622 603
623 busNo = msg->cmd.device_change_state.bus_no; 604 bus_no = msg->cmd.device_change_state.bus_no;
624 devNo = msg->cmd.device_change_state.dev_no; 605 dev_no = msg->cmd.device_change_state.dev_no;
625 606
626 read_lock(&BusListLock); 607 read_lock(&bus_list_lock);
627 for (bus = BusListHead; bus; bus = bus->next) { 608 for (bus = bus_list; bus; bus = bus->next) {
628 if (bus->bus_no == busNo) { 609 if (bus->bus_no == bus_no) {
629 /* make sure the device number is valid */ 610 /* make sure the device number is valid */
630 if (devNo >= bus->device_count) { 611 if (dev_no >= bus->device_count) {
631 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).", 612 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
632 devNo, bus->device_count); 613 dev_no, bus->device_count);
633 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; 614 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
634 } else { 615 } else {
635 /* make sure this device exists */ 616 /* make sure this device exists */
636 dev = bus->device[devNo]; 617 dev = bus->device[dev_no];
637 if (!dev) { 618 if (!dev) {
638 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.", 619 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
639 devNo); 620 dev_no);
640 retval = 621 retval =
641 CONTROLVM_RESP_ERROR_ALREADY_DONE; 622 CONTROLVM_RESP_ERROR_ALREADY_DONE;
642 } 623 }
@@ -647,20 +628,20 @@ resume_device(struct controlvm_message *msg)
647 628
648 if (!bus) { 629 if (!bus) {
649 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist", 630 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
650 busNo); 631 bus_no);
651 retval = CONTROLVM_RESP_ERROR_BUS_INVALID; 632 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
652 } 633 }
653 read_unlock(&BusListLock); 634 read_unlock(&bus_list_lock);
654 /* the msg is bound for virtpci; send 635 /* the msg is bound for virtpci; send
655 * guest_msgs struct to callback 636 * guest_msgs struct to callback
656 */ 637 */
657 if (retval == CONTROLVM_RESP_SUCCESS) { 638 if (retval == CONTROLVM_RESP_SUCCESS) {
658 if (!uuid_le_cmp(dev->channel_uuid, 639 if (uuid_le_cmp(dev->channel_uuid,
659 spar_vhba_channel_protocol_uuid)) { 640 spar_vhba_channel_protocol_uuid) == 0) {
660 cmd.msgtype = GUEST_RESUME_VHBA; 641 cmd.msgtype = GUEST_RESUME_VHBA;
661 cmd.resume_vhba.chanptr = dev->chanptr; 642 cmd.resume_vhba.chanptr = dev->chanptr;
662 } else if (!uuid_le_cmp(dev->channel_uuid, 643 } else if (uuid_le_cmp(dev->channel_uuid,
663 spar_vnic_channel_protocol_uuid)) { 644 spar_vnic_channel_protocol_uuid) == 0) {
664 cmd.msgtype = GUEST_RESUME_VNIC; 645 cmd.msgtype = GUEST_RESUME_VNIC;
665 cmd.resume_vnic.chanptr = dev->chanptr; 646 cmd.resume_vnic.chanptr = dev->chanptr;
666 } else { 647 } else {
@@ -680,33 +661,33 @@ resume_device(struct controlvm_message *msg)
680 return retval; 661 return retval;
681} 662}
682 663
683static int 664static int destroy_device(struct controlvm_message *msg, char *buf)
684destroy_device(struct controlvm_message *msg, char *buf)
685{ 665{
686 u32 busNo, devNo; 666 u32 bus_no, dev_no;
687 struct bus_info *bus; 667 struct bus_info *bus;
688 struct device_info *dev; 668 struct device_info *dev;
689 struct guest_msgs cmd; 669 struct guest_msgs cmd;
690 int retval = CONTROLVM_RESP_SUCCESS; 670 int retval = CONTROLVM_RESP_SUCCESS;
691 671
692 busNo = msg->cmd.destroy_device.bus_no; 672 bus_no = msg->cmd.destroy_device.bus_no;
693 devNo = msg->cmd.destroy_device.bus_no; 673 dev_no = msg->cmd.destroy_device.bus_no;
694 674
695 read_lock(&BusListLock); 675 read_lock(&bus_list_lock);
696 LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo); 676 LOGINF("destroy_device called for bus_no=%u, dev_no=%u", bus_no,
697 for (bus = BusListHead; bus; bus = bus->next) { 677 dev_no);
698 if (bus->bus_no == busNo) { 678 for (bus = bus_list; bus; bus = bus->next) {
679 if (bus->bus_no == bus_no) {
699 /* make sure the device number is valid */ 680 /* make sure the device number is valid */
700 if (devNo >= bus->device_count) { 681 if (dev_no >= bus->device_count) {
701 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).", 682 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device(%d) >= device_count(%d).",
702 devNo, bus->device_count); 683 dev_no, bus->device_count);
703 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; 684 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
704 } else { 685 } else {
705 /* make sure this device exists */ 686 /* make sure this device exists */
706 dev = bus->device[devNo]; 687 dev = bus->device[dev_no];
707 if (!dev) { 688 if (!dev) {
708 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.", 689 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
709 devNo); 690 dev_no);
710 retval = 691 retval =
711 CONTROLVM_RESP_ERROR_ALREADY_DONE; 692 CONTROLVM_RESP_ERROR_ALREADY_DONE;
712 } 693 }
@@ -717,20 +698,20 @@ destroy_device(struct controlvm_message *msg, char *buf)
717 698
718 if (!bus) { 699 if (!bus) {
719 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist", 700 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
720 busNo); 701 bus_no);
721 retval = CONTROLVM_RESP_ERROR_BUS_INVALID; 702 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
722 } 703 }
723 read_unlock(&BusListLock); 704 read_unlock(&bus_list_lock);
724 if (retval == CONTROLVM_RESP_SUCCESS) { 705 if (retval == CONTROLVM_RESP_SUCCESS) {
725 /* the msg is bound for virtpci; send 706 /* the msg is bound for virtpci; send
726 * guest_msgs struct to callback 707 * guest_msgs struct to callback
727 */ 708 */
728 if (!uuid_le_cmp(dev->channel_uuid, 709 if (uuid_le_cmp(dev->channel_uuid,
729 spar_vhba_channel_protocol_uuid)) { 710 spar_vhba_channel_protocol_uuid) == 0) {
730 cmd.msgtype = GUEST_DEL_VHBA; 711 cmd.msgtype = GUEST_DEL_VHBA;
731 cmd.del_vhba.chanptr = dev->chanptr; 712 cmd.del_vhba.chanptr = dev->chanptr;
732 } else if (!uuid_le_cmp(dev->channel_uuid, 713 } else if (uuid_le_cmp(dev->channel_uuid,
733 spar_vnic_channel_protocol_uuid)) { 714 spar_vnic_channel_protocol_uuid) == 0) {
734 cmd.msgtype = GUEST_DEL_VNIC; 715 cmd.msgtype = GUEST_DEL_VNIC;
735 cmd.del_vnic.chanptr = dev->chanptr; 716 cmd.del_vnic.chanptr = dev->chanptr;
736 } else { 717 } else {
@@ -739,7 +720,7 @@ destroy_device(struct controlvm_message *msg, char *buf)
739 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; 720 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
740 } 721 }
741 if (!virt_control_chan_func) { 722 if (!virt_control_chan_func) {
742 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered."); 723 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci callback not registered.");
743 return 724 return
744 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; 725 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
745 } 726 }
@@ -755,7 +736,7 @@ destroy_device(struct controlvm_message *msg, char *buf)
755 */ 736 */
756 if (dev->polling) { 737 if (dev->polling) {
757 LOGINF("calling uislib_disable_channel_interrupts"); 738 LOGINF("calling uislib_disable_channel_interrupts");
758 uislib_disable_channel_interrupts(busNo, devNo); 739 uislib_disable_channel_interrupts(bus_no, dev_no);
759 } 740 }
760 /* unmap the channel memory for the device. */ 741 /* unmap the channel memory for the device. */
761 if (!msg->hdr.flags.test_message) { 742 if (!msg->hdr.flags.test_message) {
@@ -763,7 +744,7 @@ destroy_device(struct controlvm_message *msg, char *buf)
763 uislib_iounmap(dev->chanptr); 744 uislib_iounmap(dev->chanptr);
764 } 745 }
765 kfree(dev); 746 kfree(dev);
766 bus->device[devNo] = NULL; 747 bus->device[dev_no] = NULL;
767 } 748 }
768 return retval; 749 return retval;
769} 750}
@@ -773,9 +754,9 @@ init_chipset(struct controlvm_message *msg, char *buf)
773{ 754{
774 POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); 755 POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
775 756
776 MaxBusCount = msg->cmd.init_chipset.bus_count; 757 max_bus_count = msg->cmd.init_chipset.bus_count;
777 PlatformNumber = msg->cmd.init_chipset.platform_number; 758 platform_no = msg->cmd.init_chipset.platform_number;
778 PhysicalDataChan = 0; 759 phys_data_chan = 0;
779 760
780 /* We need to make sure we have our functions registered 761 /* We need to make sure we have our functions registered
781 * before processing messages. If we are a test vehicle the 762 * before processing messages. If we are a test vehicle the
@@ -793,31 +774,29 @@ init_chipset(struct controlvm_message *msg, char *buf)
793 return CONTROLVM_RESP_SUCCESS; 774 return CONTROLVM_RESP_SUCCESS;
794} 775}
795 776
796static int 777static int delete_bus_glue(u32 bus_no)
797delete_bus_glue(u32 busNo)
798{ 778{
799 struct controlvm_message msg; 779 struct controlvm_message msg;
800 780
801 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); 781 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
802 msg.cmd.destroy_bus.bus_no = busNo; 782 msg.cmd.destroy_bus.bus_no = bus_no;
803 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { 783 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
804 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo); 784 LOGERR("destroy_bus failed. bus_no=0x%x\n", bus_no);
805 return 0; 785 return 0;
806 } 786 }
807 return 1; 787 return 1;
808} 788}
809 789
810static int 790static int delete_device_glue(u32 bus_no, u32 dev_no)
811delete_device_glue(u32 busNo, u32 devNo)
812{ 791{
813 struct controlvm_message msg; 792 struct controlvm_message msg;
814 793
815 init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); 794 init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
816 msg.cmd.destroy_device.bus_no = busNo; 795 msg.cmd.destroy_device.bus_no = bus_no;
817 msg.cmd.destroy_device.dev_no = devNo; 796 msg.cmd.destroy_device.dev_no = dev_no;
818 if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { 797 if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
819 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo, 798 LOGERR("destroy_device failed. bus_no=0x%x dev_no=0x%x\n",
820 devNo); 799 bus_no, dev_no);
821 return 0; 800 return 0;
822 } 801 }
823 return 1; 802 return 1;
@@ -874,7 +853,6 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid,
874} 853}
875EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus); 854EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
876 855
877
878int 856int
879uislib_client_inject_del_bus(u32 bus_no) 857uislib_client_inject_del_bus(u32 bus_no)
880{ 858{
@@ -919,7 +897,6 @@ uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no)
919 return rc; 897 return rc;
920 } 898 }
921 return 0; 899 return 0;
922
923} 900}
924EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba); 901EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
925 902
@@ -956,7 +933,7 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no,
956 msg.cmd.create_device.channel_addr = phys_chan_addr; 933 msg.cmd.create_device.channel_addr = phys_chan_addr;
957 if (chan_bytes < MIN_IO_CHANNEL_SIZE) { 934 if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
958 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", 935 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
959 chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); 936 chan_bytes, (unsigned int)MIN_IO_CHANNEL_SIZE);
960 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes, 937 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes,
961 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); 938 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
962 return 0; 939 return 0;
@@ -1015,7 +992,7 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no,
1015 msg.cmd.create_device.channel_addr = phys_chan_addr; 992 msg.cmd.create_device.channel_addr = phys_chan_addr;
1016 if (chan_bytes < MIN_IO_CHANNEL_SIZE) { 993 if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
1017 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", 994 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1018 chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); 995 chan_bytes, (unsigned int)MIN_IO_CHANNEL_SIZE);
1019 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes, 996 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes,
1020 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); 997 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
1021 return 0; 998 return 0;
@@ -1072,7 +1049,6 @@ uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no)
1072 return -1; 1049 return -1;
1073 } 1050 }
1074 return 0; 1051 return 0;
1075
1076} 1052}
1077EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic); 1053EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
1078 1054
@@ -1129,14 +1105,12 @@ info_debugfs_read_helper(char **buff, int *buff_len)
1129 if (PLINE("\nBuses:\n") < 0) 1105 if (PLINE("\nBuses:\n") < 0)
1130 goto err_done; 1106 goto err_done;
1131 1107
1132 read_lock(&BusListLock); 1108 read_lock(&bus_list_lock);
1133 for (bus = BusListHead; bus; bus = bus->next) { 1109 for (bus = bus_list; bus; bus = bus->next) {
1134
1135 if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n", 1110 if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n",
1136 bus, bus->bus_no, bus->device_count) < 0) 1111 bus, bus->bus_no, bus->device_count) < 0)
1137 goto err_done_unlock; 1112 goto err_done_unlock;
1138 1113
1139
1140 if (PLINE(" Devices:\n") < 0) 1114 if (PLINE(" Devices:\n") < 0)
1141 goto err_done_unlock; 1115 goto err_done_unlock;
1142 1116
@@ -1156,7 +1130,7 @@ info_debugfs_read_helper(char **buff, int *buff_len)
1156 } 1130 }
1157 } 1131 }
1158 } 1132 }
1159 read_unlock(&BusListLock); 1133 read_unlock(&bus_list_lock);
1160 1134
1161 if (PLINE("UisUtils_Registered_Services: %d\n", 1135 if (PLINE("UisUtils_Registered_Services: %d\n",
1162 atomic_read(&uisutils_registered_services)) < 0) 1136 atomic_read(&uisutils_registered_services)) < 0)
@@ -1175,70 +1149,68 @@ info_debugfs_read_helper(char **buff, int *buff_len)
1175 return tot; 1149 return tot;
1176 1150
1177err_done_unlock: 1151err_done_unlock:
1178 read_unlock(&BusListLock); 1152 read_unlock(&bus_list_lock);
1179err_done: 1153err_done:
1180 return -1; 1154 return -1;
1181} 1155}
1182 1156
1183static ssize_t 1157static ssize_t info_debugfs_read(struct file *file, char __user *buf,
1184info_debugfs_read(struct file *file, char __user *buf, 1158 size_t len, loff_t *offset)
1185 size_t len, loff_t *offset)
1186{ 1159{
1187 char *temp; 1160 char *temp;
1188 int totalBytes = 0; 1161 int total_bytes = 0;
1189 int remaining_bytes = PROC_READ_BUFFER_SIZE; 1162 int remaining_bytes = PROC_READ_BUFFER_SIZE;
1190 1163
1191/* *start = buf; */ 1164/* *start = buf; */
1192 if (ProcReadBuffer == NULL) { 1165 if (debug_buf == NULL) {
1193 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n."); 1166 DBGINF("debug_buf == NULL; allocating buffer.\n.");
1194 ProcReadBuffer = vmalloc(PROC_READ_BUFFER_SIZE); 1167 debug_buf = vmalloc(PROC_READ_BUFFER_SIZE);
1195 1168
1196 if (ProcReadBuffer == NULL) { 1169 if (debug_buf == NULL) {
1197 LOGERR("failed to allocate buffer to provide proc data.\n"); 1170 LOGERR("failed to allocate buffer to provide proc data.\n");
1198 return -ENOMEM; 1171 return -ENOMEM;
1199 } 1172 }
1200 } 1173 }
1201 1174
1202 temp = ProcReadBuffer; 1175 temp = debug_buf;
1203 1176
1204 if ((*offset == 0) || (!ProcReadBufferValid)) { 1177 if ((*offset == 0) || (!debug_buf_valid)) {
1205 DBGINF("calling info_debugfs_read_helper.\n"); 1178 DBGINF("calling info_debugfs_read_helper.\n");
1206 /* if the read fails, then -1 will be returned */ 1179 /* if the read fails, then -1 will be returned */
1207 totalBytes = info_debugfs_read_helper(&temp, &remaining_bytes); 1180 total_bytes = info_debugfs_read_helper(&temp, &remaining_bytes);
1208 ProcReadBufferValid = 1; 1181 debug_buf_valid = 1;
1209 } else 1182 } else {
1210 totalBytes = strlen(ProcReadBuffer); 1183 total_bytes = strlen(debug_buf);
1184 }
1211 1185
1212 return simple_read_from_buffer(buf, len, offset, 1186 return simple_read_from_buffer(buf, len, offset,
1213 ProcReadBuffer, totalBytes); 1187 debug_buf, total_bytes);
1214} 1188}
1215 1189
1216static struct device_info * 1190static struct device_info *find_dev(u32 bus_no, u32 dev_no)
1217find_dev(u32 busNo, u32 devNo)
1218{ 1191{
1219 struct bus_info *bus; 1192 struct bus_info *bus;
1220 struct device_info *dev = NULL; 1193 struct device_info *dev = NULL;
1221 1194
1222 read_lock(&BusListLock); 1195 read_lock(&bus_list_lock);
1223 for (bus = BusListHead; bus; bus = bus->next) { 1196 for (bus = bus_list; bus; bus = bus->next) {
1224 if (bus->bus_no == busNo) { 1197 if (bus->bus_no == bus_no) {
1225 /* make sure the device number is valid */ 1198 /* make sure the device number is valid */
1226 if (devNo >= bus->device_count) { 1199 if (dev_no >= bus->device_count) {
1227 LOGERR("%s bad busNo, devNo=%d,%d", 1200 LOGERR("%s bad bus_no, dev_no=%d,%d",
1228 __func__, 1201 __func__,
1229 (int) (busNo), (int) (devNo)); 1202 (int)bus_no, (int)dev_no);
1230 goto Away; 1203 break;
1231 } 1204 }
1232 dev = bus->device[devNo]; 1205 dev = bus->device[dev_no];
1233 if (!dev) 1206 if (!dev)
1234 LOGERR("%s bad busNo, devNo=%d,%d", 1207 LOGERR("%s bad bus_no, dev_no=%d,%d",
1235 __func__, 1208 __func__,
1236 (int) (busNo), (int) (devNo)); 1209 (int)bus_no, (int)dev_no);
1237 goto Away; 1210 break;
1238 } 1211 }
1239 } 1212 }
1240Away: 1213 read_unlock(&bus_list_lock);
1241 read_unlock(&BusListLock);
1242 return dev; 1214 return dev;
1243} 1215}
1244 1216
@@ -1262,8 +1234,7 @@ Away:
1262 * less-busy ones. 1234 * less-busy ones.
1263 * 1235 *
1264 */ 1236 */
1265static int 1237static int process_incoming(void *v)
1266Process_Incoming(void *v)
1267{ 1238{
1268 unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles; 1239 unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles;
1269 struct list_head *new_tail = NULL; 1240 struct list_head *new_tail = NULL;
@@ -1272,7 +1243,7 @@ Process_Incoming(void *v)
1272 UIS_DAEMONIZE("dev_incoming"); 1243 UIS_DAEMONIZE("dev_incoming");
1273 for (i = 0; i < 16; i++) { 1244 for (i = 0; i < 16; i++) {
1274 old_cycles = get_cycles(); 1245 old_cycles = get_cycles();
1275 wait_event_timeout(Wakeup_Polling_Device_Channels, 1246 wait_event_timeout(poll_dev_wake_q,
1276 0, POLLJIFFIES_NORMAL); 1247 0, POLLJIFFIES_NORMAL);
1277 cur_cycles = get_cycles(); 1248 cur_cycles = get_cycles();
1278 if (wait_cycles == 0) { 1249 if (wait_cycles == 0) {
@@ -1285,15 +1256,15 @@ Process_Incoming(void *v)
1285 LOGINF("wait_cycles=%llu", wait_cycles); 1256 LOGINF("wait_cycles=%llu", wait_cycles);
1286 cycles_before_wait = wait_cycles; 1257 cycles_before_wait = wait_cycles;
1287 idle_cycles = 0; 1258 idle_cycles = 0;
1288 Go_Polling_Device_Channels = 0; 1259 poll_dev_start = 0;
1289 while (1) { 1260 while (1) {
1290 struct list_head *lelt, *tmp; 1261 struct list_head *lelt, *tmp;
1291 struct device_info *dev = NULL; 1262 struct device_info *dev = NULL;
1292 1263
1293 /* poll each channel for input */ 1264 /* poll each channel for input */
1294 down(&Lock_Polling_Device_Channels); 1265 down(&poll_dev_lock);
1295 new_tail = NULL; 1266 new_tail = NULL;
1296 list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) { 1267 list_for_each_safe(lelt, tmp, &poll_dev_chan) {
1297 int rc = 0; 1268 int rc = 0;
1298 1269
1299 dev = list_entry(lelt, struct device_info, 1270 dev = list_entry(lelt, struct device_info,
@@ -1315,22 +1286,22 @@ Process_Incoming(void *v)
1315 if (! 1286 if (!
1316 (list_is_last 1287 (list_is_last
1317 (lelt, 1288 (lelt,
1318 &List_Polling_Device_Channels))) { 1289 &poll_dev_chan))) {
1319 new_tail = lelt; 1290 new_tail = lelt;
1320 dev->moved_to_tail_cnt++; 1291 dev->moved_to_tail_cnt++;
1321 } else 1292 } else {
1322 dev->last_on_list_cnt++; 1293 dev->last_on_list_cnt++;
1294 }
1323 } 1295 }
1324
1325 } 1296 }
1326 if (Incoming_ThreadInfo.should_stop) 1297 if (incoming_ti.should_stop)
1327 break; 1298 break;
1328 } 1299 }
1329 if (new_tail != NULL) { 1300 if (new_tail != NULL) {
1330 tot_moved_to_tail_cnt++; 1301 tot_moved_to_tail_cnt++;
1331 list_move_tail(new_tail, &List_Polling_Device_Channels); 1302 list_move_tail(new_tail, &poll_dev_chan);
1332 } 1303 }
1333 up(&Lock_Polling_Device_Channels); 1304 up(&poll_dev_lock);
1334 cur_cycles = get_cycles(); 1305 cur_cycles = get_cycles();
1335 delta_cycles = cur_cycles - old_cycles; 1306 delta_cycles = cur_cycles - old_cycles;
1336 old_cycles = cur_cycles; 1307 old_cycles = cur_cycles;
@@ -1340,24 +1311,24 @@ Process_Incoming(void *v)
1340 * - there is no input waiting on any of the channels 1311 * - there is no input waiting on any of the channels
1341 * - we have received a signal to stop this thread 1312 * - we have received a signal to stop this thread
1342 */ 1313 */
1343 if (Incoming_ThreadInfo.should_stop) 1314 if (incoming_ti.should_stop)
1344 break; 1315 break;
1345 if (en_smart_wakeup == 0xFF) { 1316 if (en_smart_wakeup == 0xFF) {
1346 LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming"); 1317 LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
1347 break; 1318 break;
1348 } 1319 }
1349 /* wait for POLLJIFFIES_NORMAL jiffies, or until 1320 /* wait for POLLJIFFIES_NORMAL jiffies, or until
1350 * someone wakes up Wakeup_Polling_Device_Channels, 1321 * someone wakes up poll_dev_wake_q,
1351 * whichever comes first only do a wait when we have 1322 * whichever comes first only do a wait when we have
1352 * been idle for cycles_before_wait cycles. 1323 * been idle for cycles_before_wait cycles.
1353 */ 1324 */
1354 if (idle_cycles > cycles_before_wait) { 1325 if (idle_cycles > cycles_before_wait) {
1355 Go_Polling_Device_Channels = 0; 1326 poll_dev_start = 0;
1356 tot_wait_cnt++; 1327 tot_wait_cnt++;
1357 wait_event_timeout(Wakeup_Polling_Device_Channels, 1328 wait_event_timeout(poll_dev_wake_q,
1358 Go_Polling_Device_Channels, 1329 poll_dev_start,
1359 POLLJIFFIES_NORMAL); 1330 POLLJIFFIES_NORMAL);
1360 Go_Polling_Device_Channels = 1; 1331 poll_dev_start = 1;
1361 } else { 1332 } else {
1362 tot_schedule_cnt++; 1333 tot_schedule_cnt++;
1363 schedule(); 1334 schedule();
@@ -1365,25 +1336,25 @@ Process_Incoming(void *v)
1365 } 1336 }
1366 } 1337 }
1367 DBGINF("exiting.\n"); 1338 DBGINF("exiting.\n");
1368 complete_and_exit(&Incoming_ThreadInfo.has_stopped, 0); 1339 complete_and_exit(&incoming_ti.has_stopped, 0);
1369} 1340}
1370 1341
1371static BOOL 1342static BOOL
1372Initialize_incoming_thread(void) 1343initialize_incoming_thread(void)
1373{ 1344{
1374 if (Incoming_Thread_Started) 1345 if (incoming_started)
1375 return TRUE; 1346 return TRUE;
1376 if (!uisthread_start(&Incoming_ThreadInfo, 1347 if (!uisthread_start(&incoming_ti,
1377 &Process_Incoming, NULL, "dev_incoming")) { 1348 &process_incoming, NULL, "dev_incoming")) {
1378 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED"); 1349 LOGERR("uisthread_start initialize_incoming_thread ****FAILED");
1379 return FALSE; 1350 return FALSE;
1380 } 1351 }
1381 Incoming_Thread_Started = TRUE; 1352 incoming_started = TRUE;
1382 return TRUE; 1353 return TRUE;
1383} 1354}
1384 1355
1385/* Add a new device/channel to the list being processed by 1356/* Add a new device/channel to the list being processed by
1386 * Process_Incoming(). 1357 * process_incoming().
1387 * <interrupt> - indicates the function to call periodically. 1358 * <interrupt> - indicates the function to call periodically.
1388 * <interrupt_context> - indicates the data to pass to the <interrupt> 1359 * <interrupt_context> - indicates the data to pass to the <interrupt>
1389 * function. 1360 * function.
@@ -1397,23 +1368,23 @@ uislib_enable_channel_interrupts(u32 bus_no, u32 dev_no,
1397 1368
1398 dev = find_dev(bus_no, dev_no); 1369 dev = find_dev(bus_no, dev_no);
1399 if (!dev) { 1370 if (!dev) {
1400 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (bus_no), 1371 LOGERR("%s busNo=%d, devNo=%d", __func__, (int)(bus_no),
1401 (int) (dev_no)); 1372 (int)(dev_no));
1402 return; 1373 return;
1403 } 1374 }
1404 down(&Lock_Polling_Device_Channels); 1375 down(&poll_dev_lock);
1405 Initialize_incoming_thread(); 1376 initialize_incoming_thread();
1406 dev->interrupt = interrupt; 1377 dev->interrupt = interrupt;
1407 dev->interrupt_context = interrupt_context; 1378 dev->interrupt_context = interrupt_context;
1408 dev->polling = TRUE; 1379 dev->polling = TRUE;
1409 list_add_tail(&(dev->list_polling_device_channels), 1380 list_add_tail(&dev->list_polling_device_channels,
1410 &List_Polling_Device_Channels); 1381 &poll_dev_chan);
1411 up(&Lock_Polling_Device_Channels); 1382 up(&poll_dev_lock);
1412} 1383}
1413EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts); 1384EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
1414 1385
1415/* Remove a device/channel from the list being processed by 1386/* Remove a device/channel from the list being processed by
1416 * Process_Incoming(). 1387 * process_incoming().
1417 */ 1388 */
1418void 1389void
1419uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no) 1390uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no)
@@ -1422,31 +1393,31 @@ uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no)
1422 1393
1423 dev = find_dev(bus_no, dev_no); 1394 dev = find_dev(bus_no, dev_no);
1424 if (!dev) { 1395 if (!dev) {
1425 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (bus_no), 1396 LOGERR("%s busNo=%d, devNo=%d", __func__, (int)(bus_no),
1426 (int) (dev_no)); 1397 (int)(dev_no));
1427 return; 1398 return;
1428 } 1399 }
1429 down(&Lock_Polling_Device_Channels); 1400 down(&poll_dev_lock);
1430 list_del(&dev->list_polling_device_channels); 1401 list_del(&dev->list_polling_device_channels);
1431 dev->polling = FALSE; 1402 dev->polling = FALSE;
1432 dev->interrupt = NULL; 1403 dev->interrupt = NULL;
1433 up(&Lock_Polling_Device_Channels); 1404 up(&poll_dev_lock);
1434} 1405}
1435EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts); 1406EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts);
1436 1407
1437static void 1408static void
1438do_wakeup_polling_device_channels(struct work_struct *dummy) 1409do_wakeup_polling_device_channels(struct work_struct *dummy)
1439{ 1410{
1440 if (!Go_Polling_Device_Channels) { 1411 if (!poll_dev_start) {
1441 Go_Polling_Device_Channels = 1; 1412 poll_dev_start = 1;
1442 wake_up(&Wakeup_Polling_Device_Channels); 1413 wake_up(&poll_dev_wake_q);
1443 } 1414 }
1444} 1415}
1445 1416
1446static DECLARE_WORK(Work_wakeup_polling_device_channels, 1417static DECLARE_WORK(work_wakeup_polling_device_channels,
1447 do_wakeup_polling_device_channels); 1418 do_wakeup_polling_device_channels);
1448 1419
1449/* Call this function when you want to send a hint to Process_Incoming() that 1420/* Call this function when you want to send a hint to process_incoming() that
1450 * your device might have more requests. 1421 * your device might have more requests.
1451 */ 1422 */
1452void 1423void
@@ -1454,14 +1425,14 @@ uislib_force_channel_interrupt(u32 bus_no, u32 dev_no)
1454{ 1425{
1455 if (en_smart_wakeup == 0) 1426 if (en_smart_wakeup == 0)
1456 return; 1427 return;
1457 if (Go_Polling_Device_Channels) 1428 if (poll_dev_start)
1458 return; 1429 return;
1459 /* The point of using schedule_work() instead of just doing 1430 /* The point of using schedule_work() instead of just doing
1460 * the work inline is to force a slight delay before waking up 1431 * the work inline is to force a slight delay before waking up
1461 * the Process_Incoming() thread. 1432 * the process_incoming() thread.
1462 */ 1433 */
1463 tot_wakeup_cnt++; 1434 tot_wakeup_cnt++;
1464 schedule_work(&Work_wakeup_polling_device_channels); 1435 schedule_work(&work_wakeup_polling_device_channels);
1465} 1436}
1466EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt); 1437EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
1467 1438
@@ -1472,35 +1443,35 @@ EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
1472static int __init 1443static int __init
1473uislib_mod_init(void) 1444uislib_mod_init(void)
1474{ 1445{
1475
1476 if (!unisys_spar_platform) 1446 if (!unisys_spar_platform)
1477 return -ENODEV; 1447 return -ENODEV;
1478 1448
1479 LOGINF("MONITORAPIS"); 1449 LOGINF("MONITORAPIS");
1480 1450
1481 LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n", 1451 LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
1482 (ulong) sizeof(struct uiscmdrsp)); 1452 (ulong)sizeof(struct uiscmdrsp));
1483 LOGINF("sizeof(struct phys_info):%lu\n", 1453 LOGINF("sizeof(struct phys_info):%lu\n",
1484 (ulong) sizeof(struct phys_info)); 1454 (ulong)sizeof(struct phys_info));
1485 LOGINF("sizeof(uiscmdrsp_scsi):%lu\n", 1455 LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
1486 (ulong) sizeof(struct uiscmdrsp_scsi)); 1456 (ulong)sizeof(struct uiscmdrsp_scsi));
1487 LOGINF("sizeof(uiscmdrsp_net):%lu\n", 1457 LOGINF("sizeof(uiscmdrsp_net):%lu\n",
1488 (ulong) sizeof(struct uiscmdrsp_net)); 1458 (ulong)sizeof(struct uiscmdrsp_net));
1489 LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n", 1459 LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
1490 (ulong) sizeof(struct controlvm_message)); 1460 (ulong)sizeof(struct controlvm_message));
1491 LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n", 1461 LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n",
1492 (ulong) sizeof(struct spar_controlvm_channel_protocol)); 1462 (ulong)sizeof(struct spar_controlvm_channel_protocol));
1493 LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", 1463 LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
1494 (ulong) sizeof(struct channel_header)); 1464 (ulong)sizeof(struct channel_header));
1495 LOGINF("sizeof(struct spar_io_channel_protocol):%lu bytes\n", 1465 LOGINF("sizeof(struct spar_io_channel_protocol):%lu bytes\n",
1496 (ulong) sizeof(struct spar_io_channel_protocol)); 1466 (ulong)sizeof(struct spar_io_channel_protocol));
1497 LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP); 1467 LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP);
1498 LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL); 1468 LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL);
1499 1469
1500 /* initialize global pointers to NULL */ 1470 /* initialize global pointers to NULL */
1501 BusListHead = NULL; 1471 bus_list = NULL;
1502 BusListCount = MaxBusCount = 0; 1472 bus_list_count = 0;
1503 rwlock_init(&BusListLock); 1473 max_bus_count = 0;
1474 rwlock_init(&bus_list_lock);
1504 virt_control_chan_func = NULL; 1475 virt_control_chan_func = NULL;
1505 1476
1506 /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and 1477 /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
@@ -1515,7 +1486,7 @@ uislib_mod_init(void)
1515 1486
1516 platformnumber_debugfs_read = debugfs_create_u32( 1487 platformnumber_debugfs_read = debugfs_create_u32(
1517 PLATFORMNUMBER_DEBUGFS_ENTRY_FN, 0444, dir_debugfs, 1488 PLATFORMNUMBER_DEBUGFS_ENTRY_FN, 0444, dir_debugfs,
1518 &PlatformNumber); 1489 &platform_no);
1519 1490
1520 cycles_before_wait_debugfs_read = debugfs_create_u64( 1491 cycles_before_wait_debugfs_read = debugfs_create_u64(
1521 CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN, 0666, dir_debugfs, 1492 CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
@@ -1533,9 +1504,9 @@ uislib_mod_init(void)
1533static void __exit 1504static void __exit
1534uislib_mod_exit(void) 1505uislib_mod_exit(void)
1535{ 1506{
1536 if (ProcReadBuffer) { 1507 if (debug_buf) {
1537 vfree(ProcReadBuffer); 1508 vfree(debug_buf);
1538 ProcReadBuffer = NULL; 1509 debug_buf = NULL;
1539 } 1510 }
1540 1511
1541 debugfs_remove(info_debugfs_entry); 1512 debugfs_remove(info_debugfs_entry);
diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c
index f9f8442d58c5..71bb7b608e9a 100644
--- a/drivers/staging/unisys/uislib/uisqueue.c
+++ b/drivers/staging/unisys/uislib/uisqueue.c
@@ -21,8 +21,6 @@
21 21
22#include "uisutils.h" 22#include "uisutils.h"
23 23
24#include "chanstub.h"
25
26/* this is shorter than using __FILE__ (full path name) in 24/* this is shorter than using __FILE__ (full path name) in
27 * debug/info/error messages */ 25 * debug/info/error messages */
28#define CURRENT_FILE_PC UISLIB_PC_uisqueue_c 26#define CURRENT_FILE_PC UISLIB_PC_uisqueue_c
@@ -33,9 +31,202 @@
33/*****************************************************/ 31/*****************************************************/
34/* Exported functions */ 32/* Exported functions */
35/*****************************************************/ 33/*****************************************************/
34
35/*
36 * Routine Description:
37 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
38 * Queue of the Channel pointed to by pChannel
39 *
40 * Parameters:
41 * pChannel: (IN) points to the IO Channel
42 * Queue: (IN) nth Queue of the IO Channel
43 * pSignal: (IN) pointer to the signal
44 *
45 * Assumptions:
46 * - pChannel, Queue and pSignal are valid.
47 * - If insertion fails due to a full queue, the caller will determine the
48 * retry policy (e.g. wait & try again, report an error, etc.).
49 *
50 * Return value:
51 * 1 if the insertion succeeds, 0 if the queue was full.
52 */
53unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue,
54 void *sig)
55{
56 void __iomem *psignal;
57 unsigned int head, tail, nof;
58
59 struct signal_queue_header __iomem *pqhdr =
60 (struct signal_queue_header __iomem *)
61 ((char __iomem *)ch + readq(&ch->ch_space_offset))
62 + queue;
63
64 /* capture current head and tail */
65 head = readl(&pqhdr->head);
66 tail = readl(&pqhdr->tail);
67
68 /* queue is full if (head + 1) % n equals tail */
69 if (((head + 1) % readl(&pqhdr->max_slots)) == tail) {
70 nof = readq(&pqhdr->num_overflows) + 1;
71 writeq(nof, &pqhdr->num_overflows);
72 return 0;
73 }
74
75 /* increment the head index */
76 head = (head + 1) % readl(&pqhdr->max_slots);
77
78 /* copy signal to the head location from the area pointed to
79 * by pSignal
80 */
81 psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
82 (head * readl(&pqhdr->signal_size));
83 memcpy_toio(psignal, sig, readl(&pqhdr->signal_size));
84
85 mb(); /* channel synch */
86 writel(head, &pqhdr->head);
87
88 writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent);
89 return 1;
90}
91EXPORT_SYMBOL_GPL(spar_signal_insert);
92
93/*
94 * Routine Description:
95 * Removes one signal from Channel pChannel's nth Queue at the
96 * time of the call and copies it into the memory pointed to by
97 * pSignal.
98 *
99 * Parameters:
100 * pChannel: (IN) points to the IO Channel
101 * Queue: (IN) nth Queue of the IO Channel
102 * pSignal: (IN) pointer to where the signals are to be copied
103 *
104 * Assumptions:
105 * - pChannel and Queue are valid.
106 * - pSignal points to a memory area large enough to hold queue's SignalSize
107 *
108 * Return value:
109 * 1 if the removal succeeds, 0 if the queue was empty.
110 */
111unsigned char
112spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig)
113{
114 void __iomem *psource;
115 unsigned int head, tail;
116 struct signal_queue_header __iomem *pqhdr =
117 (struct signal_queue_header __iomem *)((char __iomem *)ch +
118 readq(&ch->ch_space_offset)) + queue;
119
120 /* capture current head and tail */
121 head = readl(&pqhdr->head);
122 tail = readl(&pqhdr->tail);
123
124 /* queue is empty if the head index equals the tail index */
125 if (head == tail) {
126 writeq(readq(&pqhdr->num_empty) + 1, &pqhdr->num_empty);
127 return 0;
128 }
129
130 /* advance past the 'empty' front slot */
131 tail = (tail + 1) % readl(&pqhdr->max_slots);
132
133 /* copy signal from tail location to the area pointed to by pSignal */
134 psource = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
135 (tail * readl(&pqhdr->signal_size));
136 memcpy_fromio(sig, psource, readl(&pqhdr->signal_size));
137
138 mb(); /* channel synch */
139 writel(tail, &pqhdr->tail);
140
141 writeq(readq(&pqhdr->num_received) + 1,
142 &pqhdr->num_received);
143 return 1;
144}
145EXPORT_SYMBOL_GPL(spar_signal_remove);
146
147/*
148 * Routine Description:
149 * Removes all signals present in Channel pChannel's nth Queue at the
150 * time of the call and copies them into the memory pointed to by
151 * pSignal. Returns the # of signals copied as the value of the routine.
152 *
153 * Parameters:
154 * pChannel: (IN) points to the IO Channel
155 * Queue: (IN) nth Queue of the IO Channel
156 * pSignal: (IN) pointer to where the signals are to be copied
157 *
158 * Assumptions:
159 * - pChannel and Queue are valid.
160 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
161 * # of signals, each of which is Queue's SignalSize.
162 *
163 * Return value:
164 * # of signals copied.
165 */
166unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
167 void *sig)
168{
169 void *psource;
170 unsigned int head, tail, count = 0;
171 struct signal_queue_header *pqhdr =
172 (struct signal_queue_header *)((char *)ch +
173 ch->ch_space_offset) + queue;
174
175 /* capture current head and tail */
176 head = pqhdr->head;
177 tail = pqhdr->tail;
178
179 /* queue is empty if the head index equals the tail index */
180 if (head == tail)
181 return 0;
182
183 while (head != tail) {
184 /* advance past the 'empty' front slot */
185 tail = (tail + 1) % pqhdr->max_slots;
186
187 /* copy signal from tail location to the area pointed
188 * to by pSignal
189 */
190 psource =
191 (char *)pqhdr + pqhdr->sig_base_offset +
192 (tail * pqhdr->signal_size);
193 memcpy((char *)sig + (pqhdr->signal_size * count),
194 psource, pqhdr->signal_size);
195
196 mb(); /* channel synch */
197 pqhdr->tail = tail;
198
199 count++;
200 pqhdr->num_received++;
201 }
202
203 return count;
204}
205
206/*
207 * Routine Description:
208 * Determine whether a signal queue is empty.
209 *
210 * Parameters:
211 * pChannel: (IN) points to the IO Channel
212 * Queue: (IN) nth Queue of the IO Channel
213 *
214 * Return value:
215 * 1 if the signal queue is empty, 0 otherwise.
216 */
217unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,
218 u32 queue)
219{
220 struct signal_queue_header __iomem *pqhdr =
221 (struct signal_queue_header __iomem *)((char __iomem *)ch +
222 readq(&ch->ch_space_offset)) + queue;
223 return readl(&pqhdr->head) == readl(&pqhdr->tail);
224}
225EXPORT_SYMBOL_GPL(spar_signalqueue_empty);
226
36unsigned long long 227unsigned long long
37uisqueue_interlocked_or(unsigned long long __iomem *tgt, 228uisqueue_interlocked_or(unsigned long long __iomem *tgt,
38 unsigned long long set) 229 unsigned long long set)
39{ 230{
40 unsigned long long i; 231 unsigned long long i;
41 unsigned long long j; 232 unsigned long long j;
@@ -53,7 +244,7 @@ EXPORT_SYMBOL_GPL(uisqueue_interlocked_or);
53 244
54unsigned long long 245unsigned long long
55uisqueue_interlocked_and(unsigned long long __iomem *tgt, 246uisqueue_interlocked_and(unsigned long long __iomem *tgt,
56 unsigned long long set) 247 unsigned long long set)
57{ 248{
58 unsigned long long i; 249 unsigned long long i;
59 unsigned long long j; 250 unsigned long long j;
@@ -72,22 +263,21 @@ EXPORT_SYMBOL_GPL(uisqueue_interlocked_and);
72static u8 263static u8
73do_locked_client_insert(struct uisqueue_info *queueinfo, 264do_locked_client_insert(struct uisqueue_info *queueinfo,
74 unsigned int whichqueue, 265 unsigned int whichqueue,
75 void *pSignal, 266 void *signal,
76 spinlock_t *lock, 267 spinlock_t *lock,
77 unsigned char issueInterruptIfEmpty, 268 u8 *channel_id)
78 u64 interruptHandle, u8 *channelId)
79{ 269{
80 unsigned long flags; 270 unsigned long flags;
81 u8 rc = 0; 271 u8 rc = 0;
82 272
83 spin_lock_irqsave(lock, flags); 273 spin_lock_irqsave(lock, flags);
84 if (!spar_channel_client_acquire_os(queueinfo->chan, channelId)) 274 if (!spar_channel_client_acquire_os(queueinfo->chan, channel_id))
85 goto unlock; 275 goto unlock;
86 if (spar_signal_insert(queueinfo->chan, whichqueue, pSignal)) { 276 if (spar_signal_insert(queueinfo->chan, whichqueue, signal)) {
87 queueinfo->packets_sent++; 277 queueinfo->packets_sent++;
88 rc = 1; 278 rc = 1;
89 } 279 }
90 spar_channel_client_release_os(queueinfo->chan, channelId); 280 spar_channel_client_release_os(queueinfo->chan, channel_id);
91unlock: 281unlock:
92 spin_unlock_irqrestore((spinlock_t *)lock, flags); 282 spin_unlock_irqrestore((spinlock_t *)lock, flags);
93 return rc; 283 return rc;
@@ -103,9 +293,8 @@ uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo,
103 char oktowait, u8 *channel_id) 293 char oktowait, u8 *channel_id)
104{ 294{
105 while (!do_locked_client_insert(queueinfo, whichqueue, cmdrsp, 295 while (!do_locked_client_insert(queueinfo, whichqueue, cmdrsp,
106 (spinlock_t *) insertlock, 296 (spinlock_t *)insertlock,
107 issue_irq_if_empty, 297 channel_id)) {
108 irq_handle, channel_id)) {
109 if (oktowait != OK_TO_WAIT) { 298 if (oktowait != OK_TO_WAIT) {
110 LOGERR("****FAILED visor_signal_insert failed; cannot wait; insert aborted\n"); 299 LOGERR("****FAILED visor_signal_insert failed; cannot wait; insert aborted\n");
111 return 0; /* failed to queue */ 300 return 0; /* failed to queue */
diff --git a/drivers/staging/unisys/uislib/uisthread.c b/drivers/staging/unisys/uislib/uisthread.c
index c0fc812f751e..25adf1a7307c 100644
--- a/drivers/staging/unisys/uislib/uisthread.c
+++ b/drivers/staging/unisys/uislib/uisthread.c
@@ -53,7 +53,6 @@ uisthread_start(struct uisthread_info *thrinfo,
53 wake_up_process(thrinfo->task); 53 wake_up_process(thrinfo->task);
54 LOGINF("started thread pid:%d\n", thrinfo->id); 54 LOGINF("started thread pid:%d\n", thrinfo->id);
55 return 1; 55 return 1;
56
57} 56}
58EXPORT_SYMBOL_GPL(uisthread_start); 57EXPORT_SYMBOL_GPL(uisthread_start);
59 58
diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c
index 4a5b86773927..31318d246252 100644
--- a/drivers/staging/unisys/uislib/uisutils.c
+++ b/drivers/staging/unisys/uislib/uisutils.c
@@ -42,14 +42,13 @@ atomic_t uisutils_registered_services = ATOMIC_INIT(0);
42 * uisctrl_register_req_handler() or 42 * uisctrl_register_req_handler() or
43 * uisctrl_register_req_handler_ex() */ 43 * uisctrl_register_req_handler_ex() */
44 44
45
46/*****************************************************/ 45/*****************************************************/
47/* Utility functions */ 46/* Utility functions */
48/*****************************************************/ 47/*****************************************************/
49 48
50int 49int
51uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, 50uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining,
52 char *format, ...) 51 char *format, ...)
53{ 52{
54 va_list args; 53 va_list args;
55 int len; 54 int len;
@@ -57,6 +56,7 @@ uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining,
57 DBGINF("buffer = 0x%p : *buffer = 0x%p.\n", buffer, *buffer); 56 DBGINF("buffer = 0x%p : *buffer = 0x%p.\n", buffer, *buffer);
58 va_start(args, format); 57 va_start(args, format);
59 len = vsnprintf(*buffer, *buffer_remaining, format, args); 58 len = vsnprintf(*buffer, *buffer_remaining, format, args);
59 va_end(args);
60 if (len >= *buffer_remaining) { 60 if (len >= *buffer_remaining) {
61 *buffer += *buffer_remaining; 61 *buffer += *buffer_remaining;
62 *total += *buffer_remaining; 62 *total += *buffer_remaining;
@@ -96,7 +96,7 @@ uisctrl_register_req_handler(int type, void *fptr,
96 } 96 }
97 if (chipset_driver_info) 97 if (chipset_driver_info)
98 bus_device_info_init(chipset_driver_info, "chipset", "uislib", 98 bus_device_info_init(chipset_driver_info, "chipset", "uislib",
99 VERSION, NULL); 99 VERSION, NULL);
100 100
101 return 1; 101 return 1;
102} 102}
@@ -113,66 +113,57 @@ uisctrl_register_req_handler_ex(uuid_le switch_uuid,
113 u32 client_str_len, u64 bytes), 113 u32 client_str_len, u64 bytes),
114 struct ultra_vbus_deviceinfo *chipset_driver_info) 114 struct ultra_vbus_deviceinfo *chipset_driver_info)
115{ 115{
116 struct req_handler_info *pReqHandlerInfo; 116 struct req_handler_info *req_handler;
117 int rc = 0; /* assume failure */
118 117
119 LOGINF("type=%pUL, controlfunc=0x%p.\n", 118 LOGINF("type=%pUL, controlfunc=0x%p.\n",
120 &switch_uuid, controlfunc); 119 &switch_uuid, controlfunc);
121 if (!controlfunc) { 120 if (!controlfunc) {
122 LOGERR("%pUL: controlfunc must be supplied\n", &switch_uuid); 121 LOGERR("%pUL: controlfunc must be supplied\n", &switch_uuid);
123 goto Away; 122 return 0;
124 } 123 }
125 if (!server_channel_ok) { 124 if (!server_channel_ok) {
126 LOGERR("%pUL: Server_Channel_Ok must be supplied\n", 125 LOGERR("%pUL: Server_Channel_Ok must be supplied\n",
127 &switch_uuid); 126 &switch_uuid);
128 goto Away; 127 return 0;
129 } 128 }
130 if (!server_channel_init) { 129 if (!server_channel_init) {
131 LOGERR("%pUL: Server_Channel_Init must be supplied\n", 130 LOGERR("%pUL: Server_Channel_Init must be supplied\n",
132 &switch_uuid); 131 &switch_uuid);
133 goto Away; 132 return 0;
134 } 133 }
135 pReqHandlerInfo = req_handler_add(switch_uuid, 134 req_handler = req_handler_add(switch_uuid,
136 switch_type_name, 135 switch_type_name,
137 controlfunc, 136 controlfunc,
138 min_channel_bytes, 137 min_channel_bytes,
139 server_channel_ok, server_channel_init); 138 server_channel_ok, server_channel_init);
140 if (!pReqHandlerInfo) { 139 if (!req_handler) {
141 LOGERR("failed to add %pUL to server list\n", &switch_uuid); 140 LOGERR("failed to add %pUL to server list\n", &switch_uuid);
142 goto Away; 141 return 0;
143 } 142 }
144 143
145 atomic_inc(&uisutils_registered_services); 144 atomic_inc(&uisutils_registered_services);
146 rc = 1; /* success */ 145 if (chipset_driver_info) {
147Away: 146 bus_device_info_init(chipset_driver_info, "chipset",
148 if (rc) { 147 "uislib", VERSION, NULL);
149 if (chipset_driver_info) 148 return 1;
150 bus_device_info_init(chipset_driver_info, "chipset", 149 }
151 "uislib", VERSION, NULL);
152 } else
153 LOGERR("failed to register type %pUL.\n", &switch_uuid);
154 150
155 return rc; 151 LOGERR("failed to register type %pUL.\n", &switch_uuid);
152 return 0;
156} 153}
157EXPORT_SYMBOL_GPL(uisctrl_register_req_handler_ex); 154EXPORT_SYMBOL_GPL(uisctrl_register_req_handler_ex);
158 155
159int 156int
160uisctrl_unregister_req_handler_ex(uuid_le switch_uuid) 157uisctrl_unregister_req_handler_ex(uuid_le switch_uuid)
161{ 158{
162 int rc = 0; /* assume failure */
163
164 LOGINF("type=%pUL.\n", &switch_uuid); 159 LOGINF("type=%pUL.\n", &switch_uuid);
165 if (req_handler_del(switch_uuid) < 0) { 160 if (req_handler_del(switch_uuid) < 0) {
166 LOGERR("failed to remove %pUL from server list\n", 161 LOGERR("failed to remove %pUL from server list\n",
167 &switch_uuid); 162 &switch_uuid);
168 goto Away; 163 return 0;
169 } 164 }
170 atomic_dec(&uisutils_registered_services); 165 atomic_dec(&uisutils_registered_services);
171 rc = 1; /* success */ 166 return 1;
172Away:
173 if (!rc)
174 LOGERR("failed to unregister type %pUL.\n", &switch_uuid);
175 return rc;
176} 167}
177EXPORT_SYMBOL_GPL(uisctrl_unregister_req_handler_ex); 168EXPORT_SYMBOL_GPL(uisctrl_unregister_req_handler_ex);
178 169
@@ -214,10 +205,10 @@ uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, void *skb_in,
214 frags[count].pi_pfn = 205 frags[count].pi_pfn =
215 page_to_pfn(virt_to_page(skb->data + offset)); 206 page_to_pfn(virt_to_page(skb->data + offset));
216 frags[count].pi_off = 207 frags[count].pi_off =
217 (unsigned long) (skb->data + offset) & PI_PAGE_MASK; 208 (unsigned long)(skb->data + offset) & PI_PAGE_MASK;
218 size = 209 size =
219 min(firstfraglen, 210 min(firstfraglen,
220 (unsigned int) (PI_PAGE_SIZE - frags[count].pi_off)); 211 (unsigned int)(PI_PAGE_SIZE - frags[count].pi_off));
221 /* can take smallest of firstfraglen(what's left) OR 212 /* can take smallest of firstfraglen(what's left) OR
222 * bytes left in the page 213 * bytes left in the page
223 */ 214 */
@@ -231,7 +222,7 @@ uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, void *skb_in,
231 222
232 if ((count + numfrags) > frags_max) { 223 if ((count + numfrags) > frags_max) {
233 LOGERR("**** FAILED %s frags array too small: max:%d count+nr_frags:%d\n", 224 LOGERR("**** FAILED %s frags array too small: max:%d count+nr_frags:%d\n",
234 calling_ctx, frags_max, count + numfrags); 225 calling_ctx, frags_max, count + numfrags);
235 return -1; /* failure */ 226 return -1; /* failure */
236 } 227 }
237 228
@@ -255,7 +246,6 @@ dolist: if (skb_shinfo(skb)->frag_list) {
255 246
256 for (skbinlist = skb_shinfo(skb)->frag_list; skbinlist; 247 for (skbinlist = skb_shinfo(skb)->frag_list; skbinlist;
257 skbinlist = skbinlist->next) { 248 skbinlist = skbinlist->next) {
258
259 c = uisutil_copy_fragsinfo_from_skb("recursive", 249 c = uisutil_copy_fragsinfo_from_skb("recursive",
260 skbinlist, 250 skbinlist,
261 skbinlist->len - skbinlist->data_len, 251 skbinlist->len - skbinlist->data_len,
@@ -272,17 +262,18 @@ dolist: if (skb_shinfo(skb)->frag_list) {
272} 262}
273EXPORT_SYMBOL_GPL(uisutil_copy_fragsinfo_from_skb); 263EXPORT_SYMBOL_GPL(uisutil_copy_fragsinfo_from_skb);
274 264
275static LIST_HEAD(ReqHandlerInfo_list); /* list of struct req_handler_info */ 265static LIST_HEAD(req_handler_info_list); /* list of struct req_handler_info */
276static DEFINE_SPINLOCK(ReqHandlerInfo_list_lock); 266static DEFINE_SPINLOCK(req_handler_info_list_lock);
277 267
278struct req_handler_info * 268struct req_handler_info *
279req_handler_add(uuid_le switch_uuid, 269req_handler_add(uuid_le switch_uuid,
280 const char *switch_type_name, 270 const char *switch_type_name,
281 int (*controlfunc)(struct io_msgs *), 271 int (*controlfunc)(struct io_msgs *),
282 unsigned long min_channel_bytes, 272 unsigned long min_channel_bytes,
283 int (*Server_Channel_Ok)(unsigned long channelBytes), 273 int (*server_channel_ok)(unsigned long channel_bytes),
284 int (*Server_Channel_Init) 274 int (*server_channel_init)
285 (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes)) 275 (void *x, unsigned char *clientstr, u32 clientstr_len,
276 u64 bytes))
286{ 277{
287 struct req_handler_info *rc = NULL; 278 struct req_handler_info *rc = NULL;
288 279
@@ -292,14 +283,14 @@ req_handler_add(uuid_le switch_uuid,
292 rc->switch_uuid = switch_uuid; 283 rc->switch_uuid = switch_uuid;
293 rc->controlfunc = controlfunc; 284 rc->controlfunc = controlfunc;
294 rc->min_channel_bytes = min_channel_bytes; 285 rc->min_channel_bytes = min_channel_bytes;
295 rc->server_channel_ok = Server_Channel_Ok; 286 rc->server_channel_ok = server_channel_ok;
296 rc->server_channel_init = Server_Channel_Init; 287 rc->server_channel_init = server_channel_init;
297 if (switch_type_name) 288 if (switch_type_name)
298 strncpy(rc->switch_type_name, switch_type_name, 289 strncpy(rc->switch_type_name, switch_type_name,
299 sizeof(rc->switch_type_name) - 1); 290 sizeof(rc->switch_type_name) - 1);
300 spin_lock(&ReqHandlerInfo_list_lock); 291 spin_lock(&req_handler_info_list_lock);
301 list_add_tail(&(rc->list_link), &ReqHandlerInfo_list); 292 list_add_tail(&rc->list_link, &req_handler_info_list);
302 spin_unlock(&ReqHandlerInfo_list_lock); 293 spin_unlock(&req_handler_info_list_lock);
303 294
304 return rc; 295 return rc;
305} 296}
@@ -310,15 +301,15 @@ req_handler_find(uuid_le switch_uuid)
310 struct list_head *lelt, *tmp; 301 struct list_head *lelt, *tmp;
311 struct req_handler_info *entry = NULL; 302 struct req_handler_info *entry = NULL;
312 303
313 spin_lock(&ReqHandlerInfo_list_lock); 304 spin_lock(&req_handler_info_list_lock);
314 list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { 305 list_for_each_safe(lelt, tmp, &req_handler_info_list) {
315 entry = list_entry(lelt, struct req_handler_info, list_link); 306 entry = list_entry(lelt, struct req_handler_info, list_link);
316 if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { 307 if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) {
317 spin_unlock(&ReqHandlerInfo_list_lock); 308 spin_unlock(&req_handler_info_list_lock);
318 return entry; 309 return entry;
319 } 310 }
320 } 311 }
321 spin_unlock(&ReqHandlerInfo_list_lock); 312 spin_unlock(&req_handler_info_list_lock);
322 return NULL; 313 return NULL;
323} 314}
324 315
@@ -329,8 +320,8 @@ req_handler_del(uuid_le switch_uuid)
329 struct req_handler_info *entry = NULL; 320 struct req_handler_info *entry = NULL;
330 int rc = -1; 321 int rc = -1;
331 322
332 spin_lock(&ReqHandlerInfo_list_lock); 323 spin_lock(&req_handler_info_list_lock);
333 list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { 324 list_for_each_safe(lelt, tmp, &req_handler_info_list) {
334 entry = list_entry(lelt, struct req_handler_info, list_link); 325 entry = list_entry(lelt, struct req_handler_info, list_link);
335 if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { 326 if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) {
336 list_del(lelt); 327 list_del(lelt);
@@ -338,6 +329,6 @@ req_handler_del(uuid_le switch_uuid)
338 rc++; 329 rc++;
339 } 330 }
340 } 331 }
341 spin_unlock(&ReqHandlerInfo_list_lock); 332 spin_unlock(&req_handler_info_list_lock);
342 return rc; 333 return rc;
343} 334}
diff --git a/drivers/staging/unisys/virthba/Kconfig b/drivers/staging/unisys/virthba/Kconfig
index c0d7986e78cb..9af98fc7acbc 100644
--- a/drivers/staging/unisys/virthba/Kconfig
+++ b/drivers/staging/unisys/virthba/Kconfig
@@ -4,7 +4,7 @@
4 4
5config UNISYS_VIRTHBA 5config UNISYS_VIRTHBA
6 tristate "Unisys virthba driver" 6 tristate "Unisys virthba driver"
7 depends on UNISYSSPAR && UNISYS_VISORCHIPSET && UNISYS_CHANNELSTUB && UNISYS_UISLIB && UNISYS_VIRTPCI && SCSI 7 depends on UNISYSSPAR && UNISYS_VISORCHIPSET && UNISYS_UISLIB && UNISYS_VIRTPCI && SCSI
8 ---help--- 8 ---help---
9 If you say Y here, you will enable the Unisys virthba driver. 9 If you say Y here, you will enable the Unisys virthba driver.
10 10
diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c
index d7a629b5f111..e6ecea560495 100644
--- a/drivers/staging/unisys/virthba/virthba.c
+++ b/drivers/staging/unisys/virthba/virthba.c
@@ -85,7 +85,8 @@ static int virthba_host_reset_handler(struct scsi_cmnd *scsicmd);
85static const char *virthba_get_info(struct Scsi_Host *shp); 85static const char *virthba_get_info(struct Scsi_Host *shp);
86static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg); 86static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
87static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd, 87static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
88 void (*virthba_cmnd_done)(struct scsi_cmnd *)); 88 void (*virthba_cmnd_done)
89 (struct scsi_cmnd *));
89 90
90static const struct x86_cpu_id unisys_spar_ids[] = { 91static const struct x86_cpu_id unisys_spar_ids[] = {
91 { X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY }, 92 { X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY },
@@ -107,19 +108,20 @@ static void virthba_slave_destroy(struct scsi_device *scsidev);
107static int process_incoming_rsps(void *); 108static int process_incoming_rsps(void *);
108static int virthba_serverup(struct virtpci_dev *virtpcidev); 109static int virthba_serverup(struct virtpci_dev *virtpcidev);
109static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state); 110static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state);
110static void doDiskAddRemove(struct work_struct *work); 111static void do_disk_add_remove(struct work_struct *work);
111static void virthba_serverdown_complete(struct work_struct *work); 112static void virthba_serverdown_complete(struct work_struct *work);
112static ssize_t info_debugfs_read(struct file *file, char __user *buf, 113static ssize_t info_debugfs_read(struct file *file, char __user *buf,
113 size_t len, loff_t *offset); 114 size_t len, loff_t *offset);
114static ssize_t enable_ints_write(struct file *file, 115static ssize_t enable_ints_write(struct file *file,
115 const char __user *buffer, size_t count, loff_t *ppos); 116 const char __user *buffer, size_t count,
117 loff_t *ppos);
116 118
117/*****************************************************/ 119/*****************************************************/
118/* Globals */ 120/* Globals */
119/*****************************************************/ 121/*****************************************************/
120 122
121static int rsltq_wait_usecs = 4000; /* Default 4ms */ 123static int rsltq_wait_usecs = 4000; /* Default 4ms */
122static unsigned int MaxBuffLen; 124static unsigned int max_buff_len;
123 125
124/* Module options */ 126/* Module options */
125static char *virthba_options = "NONE"; 127static char *virthba_options = "NONE";
@@ -165,6 +167,7 @@ struct virtdisk_info {
165 atomic_t error_count; 167 atomic_t error_count;
166 struct virtdisk_info *next; 168 struct virtdisk_info *next;
167}; 169};
170
168/* Each Scsi_Host has a host_data area that contains this struct. */ 171/* Each Scsi_Host has a host_data area that contains this struct. */
169struct virthba_info { 172struct virthba_info {
170 struct Scsi_Host *scsihost; 173 struct Scsi_Host *scsihost;
@@ -193,7 +196,7 @@ struct virthba_info {
193 struct virtdisk_info head; 196 struct virtdisk_info head;
194}; 197};
195 198
196/* Work Data for DARWorkQ */ 199/* Work Data for dar_work_queue */
197struct diskaddremove { 200struct diskaddremove {
198 u8 add; /* 0-remove, 1-add */ 201 u8 add; /* 0-remove, 1-add */
199 struct Scsi_Host *shost; /* Scsi Host for this virthba instance */ 202 struct Scsi_Host *shost; /* Scsi Host for this virthba instance */
@@ -244,7 +247,7 @@ static const struct file_operations debugfs_enable_ints_fops = {
244 247
245#define VIRTHBASOPENMAX 1 248#define VIRTHBASOPENMAX 1
246/* array of open devices maintained by open() and close(); */ 249/* array of open devices maintained by open() and close(); */
247static struct virthba_devices_open VirtHbasOpen[VIRTHBASOPENMAX]; 250static struct virthba_devices_open virthbas_open[VIRTHBASOPENMAX];
248static struct dentry *virthba_debugfs_dir; 251static struct dentry *virthba_debugfs_dir;
249 252
250/*****************************************************/ 253/*****************************************************/
@@ -260,7 +263,7 @@ add_scsipending_entry(struct virthba_info *vhbainfo, char cmdtype, void *new)
260 insert_location = vhbainfo->nextinsert; 263 insert_location = vhbainfo->nextinsert;
261 while (vhbainfo->pending[insert_location].sent != NULL) { 264 while (vhbainfo->pending[insert_location].sent != NULL) {
262 insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS; 265 insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS;
263 if (insert_location == (int) vhbainfo->nextinsert) { 266 if (insert_location == (int)vhbainfo->nextinsert) {
264 LOGERR("Queue should be full. insert_location<<%d>> Unable to find open slot for pending commands.\n", 267 LOGERR("Queue should be full. insert_location<<%d>> Unable to find open slot for pending commands.\n",
265 insert_location); 268 insert_location);
266 spin_unlock_irqrestore(&vhbainfo->privlock, flags); 269 spin_unlock_irqrestore(&vhbainfo->privlock, flags);
@@ -289,7 +292,7 @@ add_scsipending_entry_with_wait(struct virthba_info *vhbainfo, char cmdtype,
289 insert_location = add_scsipending_entry(vhbainfo, cmdtype, new); 292 insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
290 } 293 }
291 294
292 return (unsigned int) insert_location; 295 return (unsigned int)insert_location;
293} 296}
294 297
295static void * 298static void *
@@ -300,13 +303,13 @@ del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
300 303
301 if (del >= MAX_PENDING_REQUESTS) { 304 if (del >= MAX_PENDING_REQUESTS) {
302 LOGERR("Invalid queue position <<%lu>> given to delete. MAX_PENDING_REQUESTS <<%d>>\n", 305 LOGERR("Invalid queue position <<%lu>> given to delete. MAX_PENDING_REQUESTS <<%d>>\n",
303 (unsigned long) del, MAX_PENDING_REQUESTS); 306 (unsigned long)del, MAX_PENDING_REQUESTS);
304 } else { 307 } else {
305 spin_lock_irqsave(&vhbainfo->privlock, flags); 308 spin_lock_irqsave(&vhbainfo->privlock, flags);
306 309
307 if (vhbainfo->pending[del].sent == NULL) 310 if (vhbainfo->pending[del].sent == NULL)
308 LOGERR("Deleting already cleared queue entry at <<%lu>>.\n", 311 LOGERR("Deleting already cleared queue entry at <<%lu>>.\n",
309 (unsigned long) del); 312 (unsigned long)del);
310 313
311 sent = vhbainfo->pending[del].sent; 314 sent = vhbainfo->pending[del].sent;
312 315
@@ -318,30 +321,30 @@ del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
318 return sent; 321 return sent;
319} 322}
320 323
321/* DARWorkQ (Disk Add/Remove) */ 324/* dar_work_queue (Disk Add/Remove) */
322static struct work_struct DARWorkQ; 325static struct work_struct dar_work_queue;
323static struct diskaddremove *DARWorkQHead; 326static struct diskaddremove *dar_work_queue_head;
324static spinlock_t DARWorkQLock; 327static spinlock_t dar_work_queue_lock;
325static unsigned short DARWorkQSched; 328static unsigned short dar_work_queue_sched;
326#define QUEUE_DISKADDREMOVE(dar) { \ 329#define QUEUE_DISKADDREMOVE(dar) { \
327 spin_lock_irqsave(&DARWorkQLock, flags); \ 330 spin_lock_irqsave(&dar_work_queue_lock, flags); \
328 if (!DARWorkQHead) { \ 331 if (!dar_work_queue_head) { \
329 DARWorkQHead = dar; \ 332 dar_work_queue_head = dar; \
330 dar->next = NULL; \ 333 dar->next = NULL; \
331 } \ 334 } \
332 else { \ 335 else { \
333 dar->next = DARWorkQHead; \ 336 dar->next = dar_work_queue_head; \
334 DARWorkQHead = dar; \ 337 dar_work_queue_head = dar; \
335 } \ 338 } \
336 if (!DARWorkQSched) { \ 339 if (!dar_work_queue_sched) { \
337 schedule_work(&DARWorkQ); \ 340 schedule_work(&dar_work_queue); \
338 DARWorkQSched = 1; \ 341 dar_work_queue_sched = 1; \
339 } \ 342 } \
340 spin_unlock_irqrestore(&DARWorkQLock, flags); \ 343 spin_unlock_irqrestore(&dar_work_queue_lock, flags); \
341} 344}
342 345
343static inline void 346static inline void
344SendDiskAddRemove(struct diskaddremove *dar) 347send_disk_add_remove(struct diskaddremove *dar)
345{ 348{
346 struct scsi_device *sdev; 349 struct scsi_device *sdev;
347 int error; 350 int error;
@@ -365,31 +368,31 @@ SendDiskAddRemove(struct diskaddremove *dar)
365} 368}
366 369
367/*****************************************************/ 370/*****************************************************/
368/* DARWorkQ Handler Thread */ 371/* dar_work_queue Handler Thread */
369/*****************************************************/ 372/*****************************************************/
370static void 373static void
371doDiskAddRemove(struct work_struct *work) 374do_disk_add_remove(struct work_struct *work)
372{ 375{
373 struct diskaddremove *dar; 376 struct diskaddremove *dar;
374 struct diskaddremove *tmphead; 377 struct diskaddremove *tmphead;
375 int i = 0; 378 int i = 0;
376 unsigned long flags; 379 unsigned long flags;
377 380
378 spin_lock_irqsave(&DARWorkQLock, flags); 381 spin_lock_irqsave(&dar_work_queue_lock, flags);
379 tmphead = DARWorkQHead; 382 tmphead = dar_work_queue_head;
380 DARWorkQHead = NULL; 383 dar_work_queue_head = NULL;
381 DARWorkQSched = 0; 384 dar_work_queue_sched = 0;
382 spin_unlock_irqrestore(&DARWorkQLock, flags); 385 spin_unlock_irqrestore(&dar_work_queue_lock, flags);
383 while (tmphead) { 386 while (tmphead) {
384 dar = tmphead; 387 dar = tmphead;
385 tmphead = dar->next; 388 tmphead = dar->next;
386 SendDiskAddRemove(dar); 389 send_disk_add_remove(dar);
387 i++; 390 i++;
388 } 391 }
389} 392}
390 393
391/*****************************************************/ 394/*****************************************************/
392/* Routine to add entry to DARWorkQ */ 395/* Routine to add entry to dar_work_queue */
393/*****************************************************/ 396/*****************************************************/
394static void 397static void
395process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp) 398process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
@@ -397,7 +400,7 @@ process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
397 struct diskaddremove *dar; 400 struct diskaddremove *dar;
398 unsigned long flags; 401 unsigned long flags;
399 402
400 dar = kzalloc(sizeof(struct diskaddremove), GFP_ATOMIC); 403 dar = kzalloc(sizeof(*dar), GFP_ATOMIC);
401 if (dar) { 404 if (dar) {
402 dar->add = cmdrsp->disknotify.add; 405 dar->add = cmdrsp->disknotify.add;
403 dar->shost = shost; 406 dar->shost = shost;
@@ -416,10 +419,10 @@ process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
416/* Probe Remove Functions */ 419/* Probe Remove Functions */
417/*****************************************************/ 420/*****************************************************/
418static irqreturn_t 421static irqreturn_t
419virthba_ISR(int irq, void *dev_id) 422virthba_isr(int irq, void *dev_id)
420{ 423{
421 struct virthba_info *virthbainfo = (struct virthba_info *) dev_id; 424 struct virthba_info *virthbainfo = (struct virthba_info *)dev_id;
422 struct channel_header __iomem *pChannelHeader; 425 struct channel_header __iomem *channel_header;
423 struct signal_queue_header __iomem *pqhdr; 426 struct signal_queue_header __iomem *pqhdr;
424 u64 mask; 427 u64 mask;
425 unsigned long long rc1; 428 unsigned long long rc1;
@@ -427,23 +430,23 @@ virthba_ISR(int irq, void *dev_id)
427 if (virthbainfo == NULL) 430 if (virthbainfo == NULL)
428 return IRQ_NONE; 431 return IRQ_NONE;
429 virthbainfo->interrupts_rcvd++; 432 virthbainfo->interrupts_rcvd++;
430 pChannelHeader = virthbainfo->chinfo.queueinfo->chan; 433 channel_header = virthbainfo->chinfo.queueinfo->chan;
431 if (((readq(&pChannelHeader->features) 434 if (((readq(&channel_header->features)
432 & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) 435 & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) &&
433 && ((readq(&pChannelHeader->features) & 436 ((readq(&channel_header->features) &
434 ULTRA_IO_DRIVER_DISABLES_INTS) != 437 ULTRA_IO_DRIVER_DISABLES_INTS) !=
435 0)) { 438 0)) {
436 virthbainfo->interrupts_disabled++; 439 virthbainfo->interrupts_disabled++;
437 mask = ~ULTRA_CHANNEL_ENABLE_INTS; 440 mask = ~ULTRA_CHANNEL_ENABLE_INTS;
438 rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask); 441 rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask);
439 } 442 }
440 if (spar_signalqueue_empty(pChannelHeader, IOCHAN_FROM_IOPART)) { 443 if (spar_signalqueue_empty(channel_header, IOCHAN_FROM_IOPART)) {
441 virthbainfo->interrupts_notme++; 444 virthbainfo->interrupts_notme++;
442 return IRQ_NONE; 445 return IRQ_NONE;
443 } 446 }
444 pqhdr = (struct signal_queue_header __iomem *) 447 pqhdr = (struct signal_queue_header __iomem *)
445 ((char __iomem *) pChannelHeader + 448 ((char __iomem *)channel_header +
446 readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; 449 readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
447 writeq(readq(&pqhdr->num_irq_received) + 1, 450 writeq(readq(&pqhdr->num_irq_received) + 1,
448 &pqhdr->num_irq_received); 451 &pqhdr->num_irq_received);
449 atomic_set(&virthbainfo->interrupt_rcvd, 1); 452 atomic_set(&virthbainfo->interrupt_rcvd, 1);
@@ -459,8 +462,8 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
459 struct virthba_info *virthbainfo; 462 struct virthba_info *virthbainfo;
460 int rsp; 463 int rsp;
461 int i; 464 int i;
462 irq_handler_t handler = virthba_ISR; 465 irq_handler_t handler = virthba_isr;
463 struct channel_header __iomem *pChannelHeader; 466 struct channel_header __iomem *channel_header;
464 struct signal_queue_header __iomem *pqhdr; 467 struct signal_queue_header __iomem *pqhdr;
465 u64 mask; 468 u64 mask;
466 469
@@ -476,7 +479,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
476 * instance - this virthba that has just been created is an 479 * instance - this virthba that has just been created is an
477 * instance of a scsi host adapter. This scsi_host_alloc 480 * instance of a scsi host adapter. This scsi_host_alloc
478 * function allocates a new Scsi_Host struct & performs basic 481 * function allocates a new Scsi_Host struct & performs basic
479 * initializatoin. The host is not published to the scsi 482 * initialization. The host is not published to the scsi
480 * midlayer until scsi_add_host is called. 483 * midlayer until scsi_add_host is called.
481 */ 484 */
482 DBGINF("calling scsi_host_alloc.\n"); 485 DBGINF("calling scsi_host_alloc.\n");
@@ -501,19 +504,19 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
501 * the max-channel value. 504 * the max-channel value.
502 */ 505 */
503 LOGINF("virtpcidev->scsi.max.max_channel=%u, max_id=%u, max_lun=%u, cmd_per_lun=%u, max_io_size=%u\n", 506 LOGINF("virtpcidev->scsi.max.max_channel=%u, max_id=%u, max_lun=%u, cmd_per_lun=%u, max_io_size=%u\n",
504 (unsigned) virtpcidev->scsi.max.max_channel - 1, 507 (unsigned)virtpcidev->scsi.max.max_channel - 1,
505 (unsigned) virtpcidev->scsi.max.max_id, 508 (unsigned)virtpcidev->scsi.max.max_id,
506 (unsigned) virtpcidev->scsi.max.max_lun, 509 (unsigned)virtpcidev->scsi.max.max_lun,
507 (unsigned) virtpcidev->scsi.max.cmd_per_lun, 510 (unsigned)virtpcidev->scsi.max.cmd_per_lun,
508 (unsigned) virtpcidev->scsi.max.max_io_size); 511 (unsigned)virtpcidev->scsi.max.max_io_size);
509 scsihost->max_channel = (unsigned) virtpcidev->scsi.max.max_channel; 512 scsihost->max_channel = (unsigned)virtpcidev->scsi.max.max_channel;
510 scsihost->max_id = (unsigned) virtpcidev->scsi.max.max_id; 513 scsihost->max_id = (unsigned)virtpcidev->scsi.max.max_id;
511 scsihost->max_lun = (unsigned) virtpcidev->scsi.max.max_lun; 514 scsihost->max_lun = (unsigned)virtpcidev->scsi.max.max_lun;
512 scsihost->cmd_per_lun = (unsigned) virtpcidev->scsi.max.cmd_per_lun; 515 scsihost->cmd_per_lun = (unsigned)virtpcidev->scsi.max.cmd_per_lun;
513 scsihost->max_sectors = 516 scsihost->max_sectors =
514 (unsigned short) (virtpcidev->scsi.max.max_io_size >> 9); 517 (unsigned short)(virtpcidev->scsi.max.max_io_size >> 9);
515 scsihost->sg_tablesize = 518 scsihost->sg_tablesize =
516 (unsigned short) (virtpcidev->scsi.max.max_io_size / PAGE_SIZE); 519 (unsigned short)(virtpcidev->scsi.max.max_io_size / PAGE_SIZE);
517 if (scsihost->sg_tablesize > MAX_PHYS_INFO) 520 if (scsihost->sg_tablesize > MAX_PHYS_INFO)
518 scsihost->sg_tablesize = MAX_PHYS_INFO; 521 scsihost->sg_tablesize = MAX_PHYS_INFO;
519 LOGINF("scsihost->max_channel=%u, max_id=%u, max_lun=%llu, cmd_per_lun=%u, max_sectors=%hu, sg_tablesize=%hu\n", 522 LOGINF("scsihost->max_channel=%u, max_id=%u, max_lun=%llu, cmd_per_lun=%u, max_sectors=%hu, sg_tablesize=%hu\n",
@@ -544,11 +547,11 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
544 return -ENODEV; 547 return -ENODEV;
545 } 548 }
546 549
547 virthbainfo = (struct virthba_info *) scsihost->hostdata; 550 virthbainfo = (struct virthba_info *)scsihost->hostdata;
548 memset(virthbainfo, 0, sizeof(struct virthba_info)); 551 memset(virthbainfo, 0, sizeof(struct virthba_info));
549 for (i = 0; i < VIRTHBASOPENMAX; i++) { 552 for (i = 0; i < VIRTHBASOPENMAX; i++) {
550 if (VirtHbasOpen[i].virthbainfo == NULL) { 553 if (virthbas_open[i].virthbainfo == NULL) {
551 VirtHbasOpen[i].virthbainfo = virthbainfo; 554 virthbas_open[i].virthbainfo = virthbainfo;
552 break; 555 break;
553 } 556 }
554 } 557 }
@@ -584,10 +587,10 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
584 DBGINF("starting rsp thread -- queueinfo: 0x%p, threadinfo: 0x%p.\n", 587 DBGINF("starting rsp thread -- queueinfo: 0x%p, threadinfo: 0x%p.\n",
585 virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo); 588 virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo);
586 589
587 pChannelHeader = virthbainfo->chinfo.queueinfo->chan; 590 channel_header = virthbainfo->chinfo.queueinfo->chan;
588 pqhdr = (struct signal_queue_header __iomem *) 591 pqhdr = (struct signal_queue_header __iomem *)
589 ((char __iomem *)pChannelHeader + 592 ((char __iomem *)channel_header +
590 readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; 593 readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
591 virthbainfo->flags_addr = &pqhdr->features; 594 virthbainfo->flags_addr = &pqhdr->features;
592 595
593 if (!uisthread_start(&virthbainfo->chinfo.threadinfo, 596 if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
@@ -646,11 +649,11 @@ virthba_remove(struct virtpci_dev *virtpcidev)
646{ 649{
647 struct virthba_info *virthbainfo; 650 struct virthba_info *virthbainfo;
648 struct Scsi_Host *scsihost = 651 struct Scsi_Host *scsihost =
649 (struct Scsi_Host *) virtpcidev->scsi.scsihost; 652 (struct Scsi_Host *)virtpcidev->scsi.scsihost;
650 653
651 LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, 654 LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no,
652 virtpcidev->device_no); 655 virtpcidev->device_no);
653 virthbainfo = (struct virthba_info *) scsihost->hostdata; 656 virthbainfo = (struct virthba_info *)scsihost->hostdata;
654 if (virthbainfo->interrupt_vector != -1) 657 if (virthbainfo->interrupt_vector != -1)
655 free_irq(virthbainfo->interrupt_vector, virthbainfo); 658 free_irq(virthbainfo->interrupt_vector, virthbainfo);
656 LOGINF("Removing virtpcidev: 0x%p, virthbainfo: 0x%p\n", virtpcidev, 659 LOGINF("Removing virtpcidev: 0x%p, virthbainfo: 0x%p\n", virtpcidev,
@@ -679,7 +682,7 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
679{ 682{
680 struct uiscmdrsp *cmdrsp; 683 struct uiscmdrsp *cmdrsp;
681 struct virthba_info *virthbainfo = 684 struct virthba_info *virthbainfo =
682 (struct virthba_info *) scsihost->hostdata; 685 (struct virthba_info *)scsihost->hostdata;
683 int notifyresult = 0xffff; 686 int notifyresult = 0xffff;
684 wait_queue_head_t notifyevent; 687 wait_queue_head_t notifyevent;
685 688
@@ -706,8 +709,8 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
706 /* specify the event that has to be triggered when this cmd is 709 /* specify the event that has to be triggered when this cmd is
707 * complete 710 * complete
708 */ 711 */
709 cmdrsp->vdiskmgmt.notify = (void *) &notifyevent; 712 cmdrsp->vdiskmgmt.notify = (void *)&notifyevent;
710 cmdrsp->vdiskmgmt.notifyresult = (void *) &notifyresult; 713 cmdrsp->vdiskmgmt.notifyresult = (void *)&notifyresult;
711 714
712 /* save destination */ 715 /* save destination */
713 cmdrsp->vdiskmgmt.vdisktype = vdiskcmdtype; 716 cmdrsp->vdiskmgmt.vdisktype = vdiskcmdtype;
@@ -715,14 +718,14 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
715 cmdrsp->vdiskmgmt.vdest.id = vdest->id; 718 cmdrsp->vdiskmgmt.vdest.id = vdest->id;
716 cmdrsp->vdiskmgmt.vdest.lun = vdest->lun; 719 cmdrsp->vdiskmgmt.vdest.lun = vdest->lun;
717 cmdrsp->vdiskmgmt.scsicmd = 720 cmdrsp->vdiskmgmt.scsicmd =
718 (void *) (uintptr_t) 721 (void *)(uintptr_t)
719 add_scsipending_entry_with_wait(virthbainfo, CMD_VDISKMGMT_TYPE, 722 add_scsipending_entry_with_wait(virthbainfo, CMD_VDISKMGMT_TYPE,
720 (void *) cmdrsp); 723 (void *)cmdrsp);
721 724
722 uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo, 725 uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
723 cmdrsp, IOCHAN_TO_IOPART, 726 cmdrsp, IOCHAN_TO_IOPART,
724 &virthbainfo->chinfo.insertlock, 727 &virthbainfo->chinfo.insertlock,
725 DONT_ISSUE_INTERRUPT, (u64) NULL, 728 DONT_ISSUE_INTERRUPT, (u64)NULL,
726 OK_TO_WAIT, "vhba"); 729 OK_TO_WAIT, "vhba");
727 LOGINF("VdiskMgmt waiting on event notifyevent=0x%p\n", 730 LOGINF("VdiskMgmt waiting on event notifyevent=0x%p\n",
728 cmdrsp->scsitaskmgmt.notify); 731 cmdrsp->scsitaskmgmt.notify);
@@ -742,7 +745,7 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype,
742{ 745{
743 struct uiscmdrsp *cmdrsp; 746 struct uiscmdrsp *cmdrsp;
744 struct virthba_info *virthbainfo = 747 struct virthba_info *virthbainfo =
745 (struct virthba_info *) scsidev->host->hostdata; 748 (struct virthba_info *)scsidev->host->hostdata;
746 int notifyresult = 0xffff; 749 int notifyresult = 0xffff;
747 wait_queue_head_t notifyevent; 750 wait_queue_head_t notifyevent;
748 751
@@ -767,8 +770,8 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype,
767 cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE; 770 cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE;
768 /* specify the event that has to be triggered when this */ 771 /* specify the event that has to be triggered when this */
769 /* cmd is complete */ 772 /* cmd is complete */
770 cmdrsp->scsitaskmgmt.notify = (void *) &notifyevent; 773 cmdrsp->scsitaskmgmt.notify = (void *)&notifyevent;
771 cmdrsp->scsitaskmgmt.notifyresult = (void *) &notifyresult; 774 cmdrsp->scsitaskmgmt.notifyresult = (void *)&notifyresult;
772 775
773 /* save destination */ 776 /* save destination */
774 cmdrsp->scsitaskmgmt.tasktype = tasktype; 777 cmdrsp->scsitaskmgmt.tasktype = tasktype;
@@ -776,15 +779,15 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype,
776 cmdrsp->scsitaskmgmt.vdest.id = scsidev->id; 779 cmdrsp->scsitaskmgmt.vdest.id = scsidev->id;
777 cmdrsp->scsitaskmgmt.vdest.lun = scsidev->lun; 780 cmdrsp->scsitaskmgmt.vdest.lun = scsidev->lun;
778 cmdrsp->scsitaskmgmt.scsicmd = 781 cmdrsp->scsitaskmgmt.scsicmd =
779 (void *) (uintptr_t) 782 (void *)(uintptr_t)
780 add_scsipending_entry_with_wait(virthbainfo, 783 add_scsipending_entry_with_wait(virthbainfo,
781 CMD_SCSITASKMGMT_TYPE, 784 CMD_SCSITASKMGMT_TYPE,
782 (void *) cmdrsp); 785 (void *)cmdrsp);
783 786
784 uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo, 787 uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
785 cmdrsp, IOCHAN_TO_IOPART, 788 cmdrsp, IOCHAN_TO_IOPART,
786 &virthbainfo->chinfo.insertlock, 789 &virthbainfo->chinfo.insertlock,
787 DONT_ISSUE_INTERRUPT, (u64) NULL, 790 DONT_ISSUE_INTERRUPT, (u64)NULL,
788 OK_TO_WAIT, "vhba"); 791 OK_TO_WAIT, "vhba");
789 LOGINF("TaskMgmt waiting on event notifyevent=0x%p\n", 792 LOGINF("TaskMgmt waiting on event notifyevent=0x%p\n",
790 cmdrsp->scsitaskmgmt.notify); 793 cmdrsp->scsitaskmgmt.notify);
@@ -805,11 +808,11 @@ virthba_abort_handler(struct scsi_cmnd *scsicmd)
805 struct virtdisk_info *vdisk; 808 struct virtdisk_info *vdisk;
806 809
807 scsidev = scsicmd->device; 810 scsidev = scsicmd->device;
808 for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head; 811 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
809 vdisk->next; vdisk = vdisk->next) { 812 vdisk->next; vdisk = vdisk->next) {
810 if ((scsidev->channel == vdisk->channel) 813 if ((scsidev->channel == vdisk->channel) &&
811 && (scsidev->id == vdisk->id) 814 (scsidev->id == vdisk->id) &&
812 && (scsidev->lun == vdisk->lun)) { 815 (scsidev->lun == vdisk->lun)) {
813 if (atomic_read(&vdisk->error_count) < 816 if (atomic_read(&vdisk->error_count) <
814 VIRTHBA_ERROR_COUNT) { 817 VIRTHBA_ERROR_COUNT) {
815 atomic_inc(&vdisk->error_count); 818 atomic_inc(&vdisk->error_count);
@@ -831,11 +834,11 @@ virthba_bus_reset_handler(struct scsi_cmnd *scsicmd)
831 struct virtdisk_info *vdisk; 834 struct virtdisk_info *vdisk;
832 835
833 scsidev = scsicmd->device; 836 scsidev = scsicmd->device;
834 for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head; 837 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
835 vdisk->next; vdisk = vdisk->next) { 838 vdisk->next; vdisk = vdisk->next) {
836 if ((scsidev->channel == vdisk->channel) 839 if ((scsidev->channel == vdisk->channel) &&
837 && (scsidev->id == vdisk->id) 840 (scsidev->id == vdisk->id) &&
838 && (scsidev->lun == vdisk->lun)) { 841 (scsidev->lun == vdisk->lun)) {
839 if (atomic_read(&vdisk->error_count) < 842 if (atomic_read(&vdisk->error_count) <
840 VIRTHBA_ERROR_COUNT) { 843 VIRTHBA_ERROR_COUNT) {
841 atomic_inc(&vdisk->error_count); 844 atomic_inc(&vdisk->error_count);
@@ -857,11 +860,11 @@ virthba_device_reset_handler(struct scsi_cmnd *scsicmd)
857 struct virtdisk_info *vdisk; 860 struct virtdisk_info *vdisk;
858 861
859 scsidev = scsicmd->device; 862 scsidev = scsicmd->device;
860 for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head; 863 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
861 vdisk->next; vdisk = vdisk->next) { 864 vdisk->next; vdisk = vdisk->next) {
862 if ((scsidev->channel == vdisk->channel) 865 if ((scsidev->channel == vdisk->channel) &&
863 && (scsidev->id == vdisk->id) 866 (scsidev->id == vdisk->id) &&
864 && (scsidev->lun == vdisk->lun)) { 867 (scsidev->lun == vdisk->lun)) {
865 if (atomic_read(&vdisk->error_count) < 868 if (atomic_read(&vdisk->error_count) <
866 VIRTHBA_ERROR_COUNT) { 869 VIRTHBA_ERROR_COUNT) {
867 atomic_inc(&vdisk->error_count); 870 atomic_inc(&vdisk->error_count);
@@ -915,7 +918,7 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
915 struct uiscmdrsp *cmdrsp; 918 struct uiscmdrsp *cmdrsp;
916 unsigned int i; 919 unsigned int i;
917 struct virthba_info *virthbainfo = 920 struct virthba_info *virthbainfo =
918 (struct virthba_info *) scsihost->hostdata; 921 (struct virthba_info *)scsihost->hostdata;
919 struct scatterlist *sg = NULL; 922 struct scatterlist *sg = NULL;
920 struct scatterlist *sgl = NULL; 923 struct scatterlist *sgl = NULL;
921 int sg_failed = 0; 924 int sg_failed = 0;
@@ -940,9 +943,9 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
940 * will return the scsicmd pointer for completion 943 * will return the scsicmd pointer for completion
941 */ 944 */
942 insert_location = 945 insert_location =
943 add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *) scsicmd); 946 add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *)scsicmd);
944 if (insert_location != -1) { 947 if (insert_location != -1) {
945 cmdrsp->scsi.scsicmd = (void *) (uintptr_t) insert_location; 948 cmdrsp->scsi.scsicmd = (void *)(uintptr_t)insert_location;
946 } else { 949 } else {
947 LOGERR("Queue is full. Returning busy.\n"); 950 LOGERR("Queue is full. Returning busy.\n");
948 kfree(cmdrsp); 951 kfree(cmdrsp);
@@ -961,13 +964,13 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
961 cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd); 964 cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd);
962 965
963 /* keep track of the max buffer length so far. */ 966 /* keep track of the max buffer length so far. */
964 if (cmdrsp->scsi.bufflen > MaxBuffLen) 967 if (cmdrsp->scsi.bufflen > max_buff_len)
965 MaxBuffLen = cmdrsp->scsi.bufflen; 968 max_buff_len = cmdrsp->scsi.bufflen;
966 969
967 if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) { 970 if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) {
968 LOGERR("scsicmd use_sg:%d greater than MAX:%d\n", 971 LOGERR("scsicmd use_sg:%d greater than MAX:%d\n",
969 scsi_sg_count(scsicmd), MAX_PHYS_INFO); 972 scsi_sg_count(scsicmd), MAX_PHYS_INFO);
970 del_scsipending_entry(virthbainfo, (uintptr_t) insert_location); 973 del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
971 kfree(cmdrsp); 974 kfree(cmdrsp);
972 return 1; /* reject the command */ 975 return 1; /* reject the command */
973 } 976 }
@@ -989,22 +992,21 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
989 sgl = scsi_sglist(scsicmd); 992 sgl = scsi_sglist(scsicmd);
990 993
991 for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) { 994 for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) {
992
993 cmdrsp->scsi.gpi_list[i].address = sg_phys(sg); 995 cmdrsp->scsi.gpi_list[i].address = sg_phys(sg);
994 cmdrsp->scsi.gpi_list[i].length = sg->length; 996 cmdrsp->scsi.gpi_list[i].length = sg->length;
995 if ((i != 0) && (sg->offset != 0)) 997 if ((i != 0) && (sg->offset != 0))
996 LOGINF("Offset on a sg_entry other than zero =<<%d>>.\n", 998 LOGINF("Offset on a sg_entry other than zero =<<%d>>.\n",
997 sg->offset); 999 sg->offset);
998 } 1000 }
999 1001
1000 if (sg_failed) { 1002 if (sg_failed) {
1001 LOGERR("Start sg_list dump (entries %d, bufflen %d)...\n", 1003 LOGERR("Start sg_list dump (entries %d, bufflen %d)...\n",
1002 scsi_sg_count(scsicmd), cmdrsp->scsi.bufflen); 1004 scsi_sg_count(scsicmd), cmdrsp->scsi.bufflen);
1003 for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) { 1005 for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) {
1004 LOGERR(" Entry(%d): page->[0x%p], phys->[0x%Lx], off(%d), len(%d)\n", 1006 LOGERR(" Entry(%d): page->[0x%p], phys->[0x%Lx], off(%d), len(%d)\n",
1005 i, sg_page(sg), 1007 i, sg_page(sg),
1006 (unsigned long long) sg_phys(sg), 1008 (unsigned long long)sg_phys(sg),
1007 sg->offset, sg->length); 1009 sg->offset, sg->length);
1008 } 1010 }
1009 LOGERR("Done sg_list dump.\n"); 1011 LOGERR("Done sg_list dump.\n");
1010 /* BUG(); ***** For now, let it fail in uissd 1012 /* BUG(); ***** For now, let it fail in uissd
@@ -1022,12 +1024,12 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
1022 &virthbainfo->chinfo. 1024 &virthbainfo->chinfo.
1023 insertlock, 1025 insertlock,
1024 DONT_ISSUE_INTERRUPT, 1026 DONT_ISSUE_INTERRUPT,
1025 (u64) NULL, DONT_WAIT, "vhba"); 1027 (u64)NULL, DONT_WAIT, "vhba");
1026 if (i == 0) { 1028 if (i == 0) {
1027 /* queue must be full - and we said don't wait - return busy */ 1029 /* queue must be full - and we said don't wait - return busy */
1028 LOGERR("uisqueue_put_cmdrsp_with_lock ****FAILED\n"); 1030 LOGERR("uisqueue_put_cmdrsp_with_lock ****FAILED\n");
1029 kfree(cmdrsp); 1031 kfree(cmdrsp);
1030 del_scsipending_entry(virthbainfo, (uintptr_t) insert_location); 1032 del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
1031 return SCSI_MLQUEUE_DEVICE_BUSY; 1033 return SCSI_MLQUEUE_DEVICE_BUSY;
1032 } 1034 }
1033 1035
@@ -1047,9 +1049,9 @@ virthba_slave_alloc(struct scsi_device *scsidev)
1047 struct virtdisk_info *vdisk; 1049 struct virtdisk_info *vdisk;
1048 struct virtdisk_info *tmpvdisk; 1050 struct virtdisk_info *tmpvdisk;
1049 struct virthba_info *virthbainfo; 1051 struct virthba_info *virthbainfo;
1050 struct Scsi_Host *scsihost = (struct Scsi_Host *) scsidev->host; 1052 struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
1051 1053
1052 virthbainfo = (struct virthba_info *) scsihost->hostdata; 1054 virthbainfo = (struct virthba_info *)scsihost->hostdata;
1053 if (!virthbainfo) { 1055 if (!virthbainfo) {
1054 LOGERR("Could not find virthba_info for scsihost\n"); 1056 LOGERR("Could not find virthba_info for scsihost\n");
1055 return 0; /* even though we errored, treat as success */ 1057 return 0; /* even though we errored, treat as success */
@@ -1061,7 +1063,7 @@ virthba_slave_alloc(struct scsi_device *scsidev)
1061 (vdisk->next->lun == scsidev->lun)) 1063 (vdisk->next->lun == scsidev->lun))
1062 return 0; 1064 return 0;
1063 } 1065 }
1064 tmpvdisk = kzalloc(sizeof(struct virtdisk_info), GFP_ATOMIC); 1066 tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
1065 if (!tmpvdisk) { /* error allocating */ 1067 if (!tmpvdisk) { /* error allocating */
1066 LOGERR("Could not allocate memory for disk\n"); 1068 LOGERR("Could not allocate memory for disk\n");
1067 return 0; 1069 return 0;
@@ -1089,9 +1091,9 @@ virthba_slave_destroy(struct scsi_device *scsidev)
1089 */ 1091 */
1090 struct virtdisk_info *vdisk, *delvdisk; 1092 struct virtdisk_info *vdisk, *delvdisk;
1091 struct virthba_info *virthbainfo; 1093 struct virthba_info *virthbainfo;
1092 struct Scsi_Host *scsihost = (struct Scsi_Host *) scsidev->host; 1094 struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
1093 1095
1094 virthbainfo = (struct virthba_info *) scsihost->hostdata; 1096 virthbainfo = (struct virthba_info *)scsihost->hostdata;
1095 if (!virthbainfo) 1097 if (!virthbainfo)
1096 LOGERR("Could not find virthba_info for scsihost\n"); 1098 LOGERR("Could not find virthba_info for scsihost\n");
1097 for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) { 1099 for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) {
@@ -1120,7 +1122,7 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1120 1122
1121 scsidev = scsicmd->device; 1123 scsidev = scsicmd->device;
1122 memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE); 1124 memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE);
1123 sd = (struct sense_data *) scsicmd->sense_buffer; 1125 sd = (struct sense_data *)scsicmd->sense_buffer;
1124 1126
1125 /* Do not log errors for disk-not-present inquiries */ 1127 /* Do not log errors for disk-not-present inquiries */
1126 if ((cmdrsp->scsi.cmnd[0] == INQUIRY) && 1128 if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
@@ -1129,11 +1131,11 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1129 return; 1131 return;
1130 1132
1131 /* Okay see what our error_count is here.... */ 1133 /* Okay see what our error_count is here.... */
1132 for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head; 1134 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
1133 vdisk->next; vdisk = vdisk->next) { 1135 vdisk->next; vdisk = vdisk->next) {
1134 if ((scsidev->channel != vdisk->channel) 1136 if ((scsidev->channel != vdisk->channel) ||
1135 || (scsidev->id != vdisk->id) 1137 (scsidev->id != vdisk->id) ||
1136 || (scsidev->lun != vdisk->lun)) 1138 (scsidev->lun != vdisk->lun))
1137 continue; 1139 continue;
1138 1140
1139 if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) { 1141 if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) {
@@ -1148,8 +1150,8 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1148 if (atomic_read(&vdisk->error_count) == 1150 if (atomic_read(&vdisk->error_count) ==
1149 VIRTHBA_ERROR_COUNT) { 1151 VIRTHBA_ERROR_COUNT) {
1150 LOGERR("Throtling SCSICMD errors disk <%d:%d:%d:%llu>\n", 1152 LOGERR("Throtling SCSICMD errors disk <%d:%d:%d:%llu>\n",
1151 scsidev->host->host_no, scsidev->id, 1153 scsidev->host->host_no, scsidev->id,
1152 scsidev->channel, scsidev->lun); 1154 scsidev->channel, scsidev->lun);
1153 } 1155 }
1154 atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); 1156 atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
1155 } 1157 }
@@ -1169,8 +1171,8 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1169 struct virtdisk_info *vdisk; 1171 struct virtdisk_info *vdisk;
1170 1172
1171 scsidev = scsicmd->device; 1173 scsidev = scsicmd->device;
1172 if ((cmdrsp->scsi.cmnd[0] == INQUIRY) 1174 if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
1173 && (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) { 1175 (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
1174 if (cmdrsp->scsi.no_disk_result == 0) 1176 if (cmdrsp->scsi.no_disk_result == 0)
1175 return; 1177 return;
1176 1178
@@ -1198,21 +1200,20 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1198 sg = scsi_sglist(scsicmd); 1200 sg = scsi_sglist(scsicmd);
1199 for (i = 0; i < scsi_sg_count(scsicmd); i++) { 1201 for (i = 0; i < scsi_sg_count(scsicmd); i++) {
1200 DBGVER("copying OUT OF buf into 0x%p %d\n", 1202 DBGVER("copying OUT OF buf into 0x%p %d\n",
1201 sg_page(sg + i), sg[i].length); 1203 sg_page(sg + i), sg[i].length);
1202 thispage_orig = kmap_atomic(sg_page(sg + i)); 1204 thispage_orig = kmap_atomic(sg_page(sg + i));
1203 thispage = (void *) ((unsigned long)thispage_orig | 1205 thispage = (void *)((unsigned long)thispage_orig |
1204 sg[i].offset); 1206 sg[i].offset);
1205 memcpy(thispage, buf + bufind, sg[i].length); 1207 memcpy(thispage, buf + bufind, sg[i].length);
1206 kunmap_atomic(thispage_orig); 1208 kunmap_atomic(thispage_orig);
1207 bufind += sg[i].length; 1209 bufind += sg[i].length;
1208 } 1210 }
1209 } else { 1211 } else {
1210
1211 vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head; 1212 vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
1212 for ( ; vdisk->next; vdisk = vdisk->next) { 1213 for ( ; vdisk->next; vdisk = vdisk->next) {
1213 if ((scsidev->channel != vdisk->channel) 1214 if ((scsidev->channel != vdisk->channel) ||
1214 || (scsidev->id != vdisk->id) 1215 (scsidev->id != vdisk->id) ||
1215 || (scsidev->lun != vdisk->lun)) 1216 (scsidev->lun != vdisk->lun))
1216 continue; 1217 continue;
1217 1218
1218 if (atomic_read(&vdisk->ios_threshold) > 0) { 1219 if (atomic_read(&vdisk->ios_threshold) > 0) {
@@ -1249,8 +1250,8 @@ complete_vdiskmgmt_command(struct uiscmdrsp *cmdrsp)
1249{ 1250{
1250 /* copy the result of the taskmgmt and */ 1251 /* copy the result of the taskmgmt and */
1251 /* wake up the error handler that is waiting for this */ 1252 /* wake up the error handler that is waiting for this */
1252 *(int *) cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result; 1253 *(int *)cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result;
1253 wake_up_all((wait_queue_head_t *) cmdrsp->vdiskmgmt.notify); 1254 wake_up_all((wait_queue_head_t *)cmdrsp->vdiskmgmt.notify);
1254 LOGINF("set notify result to %d\n", cmdrsp->vdiskmgmt.result); 1255 LOGINF("set notify result to %d\n", cmdrsp->vdiskmgmt.result);
1255} 1256}
1256 1257
@@ -1259,15 +1260,15 @@ complete_taskmgmt_command(struct uiscmdrsp *cmdrsp)
1259{ 1260{
1260 /* copy the result of the taskmgmt and */ 1261 /* copy the result of the taskmgmt and */
1261 /* wake up the error handler that is waiting for this */ 1262 /* wake up the error handler that is waiting for this */
1262 *(int *) cmdrsp->scsitaskmgmt.notifyresult = 1263 *(int *)cmdrsp->scsitaskmgmt.notifyresult =
1263 cmdrsp->scsitaskmgmt.result; 1264 cmdrsp->scsitaskmgmt.result;
1264 wake_up_all((wait_queue_head_t *) cmdrsp->scsitaskmgmt.notify); 1265 wake_up_all((wait_queue_head_t *)cmdrsp->scsitaskmgmt.notify);
1265 LOGINF("set notify result to %d\n", cmdrsp->scsitaskmgmt.result); 1266 LOGINF("set notify result to %d\n", cmdrsp->scsitaskmgmt.result);
1266} 1267}
1267 1268
1268static void 1269static void
1269drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, 1270drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
1270 struct uiscmdrsp *cmdrsp) 1271 struct uiscmdrsp *cmdrsp)
1271{ 1272{
1272 unsigned long flags; 1273 unsigned long flags;
1273 int qrslt = 0; 1274 int qrslt = 0;
@@ -1277,7 +1278,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
1277 while (1) { 1278 while (1) {
1278 spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags); 1279 spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags);
1279 if (!spar_channel_client_acquire_os(dc->queueinfo->chan, 1280 if (!spar_channel_client_acquire_os(dc->queueinfo->chan,
1280 "vhba")) { 1281 "vhba")) {
1281 spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, 1282 spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock,
1282 flags); 1283 flags);
1283 virthbainfo->acquire_failed_cnt++; 1284 virthbainfo->acquire_failed_cnt++;
@@ -1294,14 +1295,15 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
1294 * deletion 1295 * deletion
1295 */ 1296 */
1296 scsicmd = del_scsipending_entry(virthbainfo, 1297 scsicmd = del_scsipending_entry(virthbainfo,
1297 (uintptr_t) cmdrsp->scsi.scsicmd); 1298 (uintptr_t)
1299 cmdrsp->scsi.scsicmd);
1298 if (!scsicmd) 1300 if (!scsicmd)
1299 break; 1301 break;
1300 /* complete the orig cmd */ 1302 /* complete the orig cmd */
1301 complete_scsi_command(cmdrsp, scsicmd); 1303 complete_scsi_command(cmdrsp, scsicmd);
1302 } else if (cmdrsp->cmdtype == CMD_SCSITASKMGMT_TYPE) { 1304 } else if (cmdrsp->cmdtype == CMD_SCSITASKMGMT_TYPE) {
1303 if (!del_scsipending_entry(virthbainfo, 1305 if (!del_scsipending_entry(virthbainfo,
1304 (uintptr_t) cmdrsp->scsitaskmgmt.scsicmd)) 1306 (uintptr_t)cmdrsp->scsitaskmgmt.scsicmd))
1305 break; 1307 break;
1306 complete_taskmgmt_command(cmdrsp); 1308 complete_taskmgmt_command(cmdrsp);
1307 } else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE) { 1309 } else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE) {
@@ -1313,7 +1315,8 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
1313 process_disk_notify(shost, cmdrsp); 1315 process_disk_notify(shost, cmdrsp);
1314 } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) { 1316 } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) {
1315 if (!del_scsipending_entry(virthbainfo, 1317 if (!del_scsipending_entry(virthbainfo,
1316 (uintptr_t) cmdrsp->vdiskmgmt.scsicmd)) 1318 (uintptr_t)
1319 cmdrsp->vdiskmgmt.scsicmd))
1317 break; 1320 break;
1318 complete_vdiskmgmt_command(cmdrsp); 1321 complete_vdiskmgmt_command(cmdrsp);
1319 } else 1322 } else
@@ -1347,7 +1350,7 @@ process_incoming_rsps(void *v)
1347 while (1) { 1350 while (1) {
1348 wait_event_interruptible_timeout(virthbainfo->rsp_queue, 1351 wait_event_interruptible_timeout(virthbainfo->rsp_queue,
1349 (atomic_read(&virthbainfo->interrupt_rcvd) == 1), 1352 (atomic_read(&virthbainfo->interrupt_rcvd) == 1),
1350 usecs_to_jiffies(rsltq_wait_usecs)); 1353 usecs_to_jiffies(rsltq_wait_usecs));
1351 atomic_set(&virthbainfo->interrupt_rcvd, 0); 1354 atomic_set(&virthbainfo->interrupt_rcvd, 0);
1352 /* drain queue */ 1355 /* drain queue */
1353 drain_queue(virthbainfo, dc, cmdrsp); 1356 drain_queue(virthbainfo, dc, cmdrsp);
@@ -1367,7 +1370,7 @@ process_incoming_rsps(void *v)
1367/*****************************************************/ 1370/*****************************************************/
1368 1371
1369static ssize_t info_debugfs_read(struct file *file, 1372static ssize_t info_debugfs_read(struct file *file,
1370 char __user *buf, size_t len, loff_t *offset) 1373 char __user *buf, size_t len, loff_t *offset)
1371{ 1374{
1372 ssize_t bytes_read = 0; 1375 ssize_t bytes_read = 0;
1373 int str_pos = 0; 1376 int str_pos = 0;
@@ -1383,13 +1386,14 @@ static ssize_t info_debugfs_read(struct file *file,
1383 return -ENOMEM; 1386 return -ENOMEM;
1384 1387
1385 for (i = 0; i < VIRTHBASOPENMAX; i++) { 1388 for (i = 0; i < VIRTHBASOPENMAX; i++) {
1386 if (VirtHbasOpen[i].virthbainfo == NULL) 1389 if (virthbas_open[i].virthbainfo == NULL)
1387 continue; 1390 continue;
1388 1391
1389 virthbainfo = VirtHbasOpen[i].virthbainfo; 1392 virthbainfo = virthbas_open[i].virthbainfo;
1390 1393
1391 str_pos += scnprintf(vbuf + str_pos, 1394 str_pos += scnprintf(vbuf + str_pos,
1392 len - str_pos, "MaxBuffLen:%u\n", MaxBuffLen); 1395 len - str_pos, "max_buff_len:%u\n",
1396 max_buff_len);
1393 1397
1394 str_pos += scnprintf(vbuf + str_pos, len - str_pos, 1398 str_pos += scnprintf(vbuf + str_pos, len - str_pos,
1395 "\nvirthba result queue poll wait:%d usecs.\n", 1399 "\nvirthba result queue poll wait:%d usecs.\n",
@@ -1418,14 +1422,14 @@ static ssize_t info_debugfs_read(struct file *file,
1418 return bytes_read; 1422 return bytes_read;
1419} 1423}
1420 1424
1421static ssize_t enable_ints_write(struct file *file, 1425static ssize_t enable_ints_write(struct file *file, const char __user *buffer,
1422 const char __user *buffer, size_t count, loff_t *ppos) 1426 size_t count, loff_t *ppos)
1423{ 1427{
1424 char buf[4]; 1428 char buf[4];
1425 int i, new_value; 1429 int i, new_value;
1426 struct virthba_info *virthbainfo; 1430 struct virthba_info *virthbainfo;
1427 1431
1428 u64 __iomem *Features_addr; 1432 u64 __iomem *features_addr;
1429 u64 mask; 1433 u64 mask;
1430 1434
1431 if (count >= ARRAY_SIZE(buf)) 1435 if (count >= ARRAY_SIZE(buf))
@@ -1434,37 +1438,37 @@ static ssize_t enable_ints_write(struct file *file,
1434 buf[count] = '\0'; 1438 buf[count] = '\0';
1435 if (copy_from_user(buf, buffer, count)) { 1439 if (copy_from_user(buf, buffer, count)) {
1436 LOGERR("copy_from_user failed. buf<<%.*s>> count<<%lu>>\n", 1440 LOGERR("copy_from_user failed. buf<<%.*s>> count<<%lu>>\n",
1437 (int) count, buf, count); 1441 (int)count, buf, count);
1438 return -EFAULT; 1442 return -EFAULT;
1439 } 1443 }
1440 1444
1441 i = kstrtoint(buf, 10 , &new_value); 1445 i = kstrtoint(buf, 10, &new_value);
1442 1446
1443 if (i != 0) { 1447 if (i != 0) {
1444 LOGERR("Failed to scan value for enable_ints, buf<<%.*s>>", 1448 LOGERR("Failed to scan value for enable_ints, buf<<%.*s>>",
1445 (int) count, buf); 1449 (int)count, buf);
1446 return -EFAULT; 1450 return -EFAULT;
1447 } 1451 }
1448 1452
1449 /* set all counts to new_value usually 0 */ 1453 /* set all counts to new_value usually 0 */
1450 for (i = 0; i < VIRTHBASOPENMAX; i++) { 1454 for (i = 0; i < VIRTHBASOPENMAX; i++) {
1451 if (VirtHbasOpen[i].virthbainfo != NULL) { 1455 if (virthbas_open[i].virthbainfo != NULL) {
1452 virthbainfo = VirtHbasOpen[i].virthbainfo; 1456 virthbainfo = virthbas_open[i].virthbainfo;
1453 Features_addr = 1457 features_addr =
1454 &virthbainfo->chinfo.queueinfo->chan->features; 1458 &virthbainfo->chinfo.queueinfo->chan->features;
1455 if (new_value == 1) { 1459 if (new_value == 1) {
1456 mask = ~(ULTRA_IO_CHANNEL_IS_POLLING | 1460 mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
1457 ULTRA_IO_DRIVER_DISABLES_INTS); 1461 ULTRA_IO_DRIVER_DISABLES_INTS);
1458 uisqueue_interlocked_and(Features_addr, mask); 1462 uisqueue_interlocked_and(features_addr, mask);
1459 mask = ULTRA_IO_DRIVER_ENABLES_INTS; 1463 mask = ULTRA_IO_DRIVER_ENABLES_INTS;
1460 uisqueue_interlocked_or(Features_addr, mask); 1464 uisqueue_interlocked_or(features_addr, mask);
1461 rsltq_wait_usecs = 4000000; 1465 rsltq_wait_usecs = 4000000;
1462 } else { 1466 } else {
1463 mask = ~(ULTRA_IO_DRIVER_ENABLES_INTS | 1467 mask = ~(ULTRA_IO_DRIVER_ENABLES_INTS |
1464 ULTRA_IO_DRIVER_DISABLES_INTS); 1468 ULTRA_IO_DRIVER_DISABLES_INTS);
1465 uisqueue_interlocked_and(Features_addr, mask); 1469 uisqueue_interlocked_and(features_addr, mask);
1466 mask = ULTRA_IO_CHANNEL_IS_POLLING; 1470 mask = ULTRA_IO_CHANNEL_IS_POLLING;
1467 uisqueue_interlocked_or(Features_addr, mask); 1471 uisqueue_interlocked_or(features_addr, mask);
1468 rsltq_wait_usecs = 4000; 1472 rsltq_wait_usecs = 4000;
1469 } 1473 }
1470 } 1474 }
@@ -1477,7 +1481,7 @@ static int
1477virthba_serverup(struct virtpci_dev *virtpcidev) 1481virthba_serverup(struct virtpci_dev *virtpcidev)
1478{ 1482{
1479 struct virthba_info *virthbainfo = 1483 struct virthba_info *virthbainfo =
1480 (struct virthba_info *) ((struct Scsi_Host *) virtpcidev->scsi. 1484 (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
1481 scsihost)->hostdata; 1485 scsihost)->hostdata;
1482 1486
1483 DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, 1487 DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no,
@@ -1535,26 +1539,26 @@ virthba_serverdown_complete(struct work_struct *work)
1535 /* Fail Commands that weren't completed */ 1539 /* Fail Commands that weren't completed */
1536 spin_lock_irqsave(&virthbainfo->privlock, flags); 1540 spin_lock_irqsave(&virthbainfo->privlock, flags);
1537 for (i = 0; i < MAX_PENDING_REQUESTS; i++) { 1541 for (i = 0; i < MAX_PENDING_REQUESTS; i++) {
1538 pendingdel = &(virthbainfo->pending[i]); 1542 pendingdel = &virthbainfo->pending[i];
1539 switch (pendingdel->cmdtype) { 1543 switch (pendingdel->cmdtype) {
1540 case CMD_SCSI_TYPE: 1544 case CMD_SCSI_TYPE:
1541 scsicmd = (struct scsi_cmnd *) pendingdel->sent; 1545 scsicmd = (struct scsi_cmnd *)pendingdel->sent;
1542 scsicmd->result = (DID_RESET << 16); 1546 scsicmd->result = (DID_RESET << 16);
1543 if (scsicmd->scsi_done) 1547 if (scsicmd->scsi_done)
1544 scsicmd->scsi_done(scsicmd); 1548 scsicmd->scsi_done(scsicmd);
1545 break; 1549 break;
1546 case CMD_SCSITASKMGMT_TYPE: 1550 case CMD_SCSITASKMGMT_TYPE:
1547 cmdrsp = (struct uiscmdrsp *) pendingdel->sent; 1551 cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
1548 DBGINF("cmdrsp=0x%x, notify=0x%x\n", cmdrsp, 1552 DBGINF("cmdrsp=0x%x, notify=0x%x\n", cmdrsp,
1549 cmdrsp->scsitaskmgmt.notify); 1553 cmdrsp->scsitaskmgmt.notify);
1550 *(int *) cmdrsp->scsitaskmgmt.notifyresult = 1554 *(int *)cmdrsp->scsitaskmgmt.notifyresult =
1551 TASK_MGMT_FAILED; 1555 TASK_MGMT_FAILED;
1552 wake_up_all((wait_queue_head_t *) 1556 wake_up_all((wait_queue_head_t *)
1553 cmdrsp->scsitaskmgmt.notify); 1557 cmdrsp->scsitaskmgmt.notify);
1554 break; 1558 break;
1555 case CMD_VDISKMGMT_TYPE: 1559 case CMD_VDISKMGMT_TYPE:
1556 cmdrsp = (struct uiscmdrsp *) pendingdel->sent; 1560 cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
1557 *(int *) cmdrsp->vdiskmgmt.notifyresult = 1561 *(int *)cmdrsp->vdiskmgmt.notifyresult =
1558 VDISK_MGMT_FAILED; 1562 VDISK_MGMT_FAILED;
1559 wake_up_all((wait_queue_head_t *) 1563 wake_up_all((wait_queue_head_t *)
1560 cmdrsp->vdiskmgmt.notify); 1564 cmdrsp->vdiskmgmt.notify);
@@ -1584,8 +1588,10 @@ virthba_serverdown_complete(struct work_struct *work)
1584static int 1588static int
1585virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state) 1589virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
1586{ 1590{
1591 int stat = 1;
1592
1587 struct virthba_info *virthbainfo = 1593 struct virthba_info *virthbainfo =
1588 (struct virthba_info *) ((struct Scsi_Host *) virtpcidev->scsi. 1594 (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
1589 scsihost)->hostdata; 1595 scsihost)->hostdata;
1590 1596
1591 DBGINF("virthba_serverdown"); 1597 DBGINF("virthba_serverdown");
@@ -1598,11 +1604,12 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
1598 &virthbainfo->serverdown_completion); 1604 &virthbainfo->serverdown_completion);
1599 } else if (virthbainfo->serverchangingstate) { 1605 } else if (virthbainfo->serverchangingstate) {
1600 LOGERR("Server already processing change state message\n"); 1606 LOGERR("Server already processing change state message\n");
1601 return 0; 1607 stat = 0;
1602 } else 1608 } else {
1603 LOGERR("Server already down, but another server down message received."); 1609 LOGERR("Server already down, but another server down message received.");
1610 }
1604 1611
1605 return 1; 1612 return stat;
1606} 1613}
1607 1614
1608/*****************************************************/ 1615/*****************************************************/
@@ -1655,23 +1662,22 @@ virthba_mod_init(void)
1655 POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error, 1662 POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error,
1656 POSTCODE_SEVERITY_ERR); 1663 POSTCODE_SEVERITY_ERR);
1657 } else { 1664 } else {
1658
1659 /* create the debugfs directories and entries */ 1665 /* create the debugfs directories and entries */
1660 virthba_debugfs_dir = debugfs_create_dir("virthba", NULL); 1666 virthba_debugfs_dir = debugfs_create_dir("virthba", NULL);
1661 debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir, 1667 debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir,
1662 NULL, &debugfs_info_fops); 1668 NULL, &debugfs_info_fops);
1663 debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR, 1669 debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR,
1664 virthba_debugfs_dir, &rsltq_wait_usecs); 1670 virthba_debugfs_dir, &rsltq_wait_usecs);
1665 debugfs_create_file("enable_ints", S_IWUSR, 1671 debugfs_create_file("enable_ints", S_IWUSR,
1666 virthba_debugfs_dir, NULL, 1672 virthba_debugfs_dir, NULL,
1667 &debugfs_enable_ints_fops); 1673 &debugfs_enable_ints_fops);
1668 /* Initialize DARWorkQ */ 1674 /* Initialize dar_work_queue */
1669 INIT_WORK(&DARWorkQ, doDiskAddRemove); 1675 INIT_WORK(&dar_work_queue, do_disk_add_remove);
1670 spin_lock_init(&DARWorkQLock); 1676 spin_lock_init(&dar_work_queue_lock);
1671 1677
1672 /* clear out array */ 1678 /* clear out array */
1673 for (i = 0; i < VIRTHBASOPENMAX; i++) 1679 for (i = 0; i < VIRTHBASOPENMAX; i++)
1674 VirtHbasOpen[i].virthbainfo = NULL; 1680 virthbas_open[i].virthbainfo = NULL;
1675 /* Initialize the serverdown workqueue */ 1681 /* Initialize the serverdown workqueue */
1676 virthba_serverdown_workqueue = 1682 virthba_serverdown_workqueue =
1677 create_singlethread_workqueue("virthba_serverdown"); 1683 create_singlethread_workqueue("virthba_serverdown");
@@ -1746,7 +1752,6 @@ virthba_mod_exit(void)
1746 1752
1747 debugfs_remove_recursive(virthba_debugfs_dir); 1753 debugfs_remove_recursive(virthba_debugfs_dir);
1748 LOGINF("Leaving virthba_mod_exit\n"); 1754 LOGINF("Leaving virthba_mod_exit\n");
1749
1750} 1755}
1751 1756
1752/* specify function to be run at module insertion time */ 1757/* specify function to be run at module insertion time */
diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c
index 39b828dce503..8fdfd6f3605f 100644
--- a/drivers/staging/unisys/virtpci/virtpci.c
+++ b/drivers/staging/unisys/virtpci/virtpci.c
@@ -104,8 +104,6 @@ static ssize_t virtpci_driver_attr_store(struct kobject *kobj,
104 const char *buf, size_t count); 104 const char *buf, size_t count);
105static int virtpci_bus_match(struct device *dev, struct device_driver *drv); 105static int virtpci_bus_match(struct device *dev, struct device_driver *drv);
106static int virtpci_uevent(struct device *dev, struct kobj_uevent_env *env); 106static int virtpci_uevent(struct device *dev, struct kobj_uevent_env *env);
107static int virtpci_device_suspend(struct device *dev, pm_message_t state);
108static int virtpci_device_resume(struct device *dev);
109static int virtpci_device_probe(struct device *dev); 107static int virtpci_device_probe(struct device *dev);
110static int virtpci_device_remove(struct device *dev); 108static int virtpci_device_remove(struct device *dev);
111 109
@@ -128,8 +126,6 @@ static struct bus_type virtpci_bus_type = {
128 .name = "uisvirtpci", 126 .name = "uisvirtpci",
129 .match = virtpci_bus_match, 127 .match = virtpci_bus_match,
130 .uevent = virtpci_uevent, 128 .uevent = virtpci_uevent,
131 .suspend = virtpci_device_suspend,
132 .resume = virtpci_device_resume,
133}; 129};
134 130
135static struct device virtpci_rootbus_device = { 131static struct device virtpci_rootbus_device = {
@@ -279,9 +275,9 @@ static int add_vbus(struct add_vbus_guestpart *addparams)
279 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); 275 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
280 return 0; 276 return 0;
281 } 277 }
282 write_vbus_chp_info(vbus->platform_data /* chanptr */ , 278 write_vbus_chp_info(vbus->platform_data /* chanptr */,
283 &chipset_driver_info); 279 &chipset_driver_info);
284 write_vbus_bus_info(vbus->platform_data /* chanptr */ , 280 write_vbus_bus_info(vbus->platform_data /* chanptr */,
285 &bus_driver_info); 281 &bus_driver_info);
286 LOGINF("Added vbus %d; device %s created successfully\n", 282 LOGINF("Added vbus %d; device %s created successfully\n",
287 addparams->bus_no, BUS_ID(vbus)); 283 addparams->bus_no, BUS_ID(vbus));
@@ -466,7 +462,7 @@ static int pause_vhba(struct pause_virt_guestpart *pauseparams)
466 GET_SCSIADAPINFO_FROM_CHANPTR(pauseparams->chanptr); 462 GET_SCSIADAPINFO_FROM_CHANPTR(pauseparams->chanptr);
467 463
468 LOGINF("Pausing vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2); 464 LOGINF("Pausing vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2);
469 i = virtpci_device_serverdown(NULL /*no parent bus */ , VIRTHBA_TYPE, 465 i = virtpci_device_serverdown(NULL /*no parent bus */, VIRTHBA_TYPE,
470 &scsi.wwnn, NULL); 466 &scsi.wwnn, NULL);
471 if (i) 467 if (i)
472 LOGINF("Paused vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, 468 LOGINF("Paused vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1,
@@ -487,7 +483,7 @@ static int pause_vnic(struct pause_virt_guestpart *pauseparams)
487 LOGINF("Pausing vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", 483 LOGINF("Pausing vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
488 net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], 484 net.mac_addr[0], net.mac_addr[1], net.mac_addr[2],
489 net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); 485 net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]);
490 i = virtpci_device_serverdown(NULL /*no parent bus */ , VIRTNIC_TYPE, 486 i = virtpci_device_serverdown(NULL /*no parent bus */, VIRTNIC_TYPE,
491 NULL, net.mac_addr); 487 NULL, net.mac_addr);
492 if (i) { 488 if (i) {
493 LOGINF(" Paused vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", 489 LOGINF(" Paused vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -508,7 +504,7 @@ static int resume_vhba(struct resume_virt_guestpart *resumeparams)
508 GET_SCSIADAPINFO_FROM_CHANPTR(resumeparams->chanptr); 504 GET_SCSIADAPINFO_FROM_CHANPTR(resumeparams->chanptr);
509 505
510 LOGINF("Resuming vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2); 506 LOGINF("Resuming vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2);
511 i = virtpci_device_serverup(NULL /*no parent bus */ , VIRTHBA_TYPE, 507 i = virtpci_device_serverup(NULL /*no parent bus */, VIRTHBA_TYPE,
512 &scsi.wwnn, NULL); 508 &scsi.wwnn, NULL);
513 if (i) 509 if (i)
514 LOGINF("Resumed vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, 510 LOGINF("Resumed vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1,
@@ -530,7 +526,7 @@ resume_vnic(struct resume_virt_guestpart *resumeparams)
530 LOGINF("Resuming vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", 526 LOGINF("Resuming vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
531 net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], 527 net.mac_addr[0], net.mac_addr[1], net.mac_addr[2],
532 net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); 528 net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]);
533 i = virtpci_device_serverup(NULL /*no parent bus */ , VIRTNIC_TYPE, 529 i = virtpci_device_serverup(NULL /*no parent bus */, VIRTNIC_TYPE,
534 NULL, net.mac_addr); 530 NULL, net.mac_addr);
535 if (i) { 531 if (i) {
536 LOGINF(" Resumed vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", 532 LOGINF(" Resumed vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -551,7 +547,7 @@ static int delete_vhba(struct del_virt_guestpart *delparams)
551 GET_SCSIADAPINFO_FROM_CHANPTR(delparams->chanptr); 547 GET_SCSIADAPINFO_FROM_CHANPTR(delparams->chanptr);
552 548
553 LOGINF("Deleting vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2); 549 LOGINF("Deleting vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2);
554 i = virtpci_device_del(NULL /*no parent bus */ , VIRTHBA_TYPE, 550 i = virtpci_device_del(NULL /*no parent bus */, VIRTHBA_TYPE,
555 &scsi.wwnn, NULL); 551 &scsi.wwnn, NULL);
556 if (i) { 552 if (i) {
557 LOGINF("Deleted vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, 553 LOGINF("Deleted vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1,
@@ -574,7 +570,7 @@ static int delete_vnic(struct del_virt_guestpart *delparams)
574 LOGINF("Deleting vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", 570 LOGINF("Deleting vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
575 net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], 571 net.mac_addr[0], net.mac_addr[1], net.mac_addr[2],
576 net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); 572 net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]);
577 i = virtpci_device_del(NULL /*no parent bus */ , VIRTNIC_TYPE, NULL, 573 i = virtpci_device_del(NULL /*no parent bus */, VIRTNIC_TYPE, NULL,
578 net.mac_addr); 574 net.mac_addr);
579 if (i) { 575 if (i) {
580 LOGINF("Deleted vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", 576 LOGINF("Deleted vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -757,18 +753,6 @@ static int virtpci_uevent(struct device *dev, struct kobj_uevent_env *env)
757 return 0; 753 return 0;
758} 754}
759 755
760static int virtpci_device_suspend(struct device *dev, pm_message_t state)
761{
762 DBGINF("In virtpci_device_suspend -NYI ****\n");
763 return 0;
764}
765
766static int virtpci_device_resume(struct device *dev)
767{
768 DBGINF("In virtpci_device_resume -NYI ****\n");
769 return 0;
770}
771
772/* For a child device just created on a client bus, fill in 756/* For a child device just created on a client bus, fill in
773 * information about the driver that is controlling this device into 757 * information about the driver that is controlling this device into
774 * the appropriate slot within the vbus channel of the bus 758 * the appropriate slot within the vbus channel of the bus
@@ -1338,18 +1322,13 @@ static ssize_t virtpci_driver_attr_show(struct kobject *kobj,
1338 ssize_t ret = 0; 1322 ssize_t ret = 0;
1339 1323
1340 struct driver_private *dprivate = to_driver(kobj); 1324 struct driver_private *dprivate = to_driver(kobj);
1341 struct device_driver *driver; 1325 struct device_driver *driver = dprivate->driver;
1342 1326
1343 if (dprivate != NULL) 1327 DBGINF("In virtpci_driver_attr_show driver->name:%s\n", driver->name);
1344 driver = dprivate->driver; 1328
1345 else 1329 if (dattr->show)
1346 driver = NULL; 1330 ret = dattr->show(driver, buf);
1347 1331
1348 DBGINF("In virtpci_driver_attr_show driver->name:%s\n", driver->name);
1349 if (driver) {
1350 if (dattr->show)
1351 ret = dattr->show(driver, buf);
1352 }
1353 return ret; 1332 return ret;
1354} 1333}
1355 1334
@@ -1361,19 +1340,13 @@ static ssize_t virtpci_driver_attr_store(struct kobject *kobj,
1361 ssize_t ret = 0; 1340 ssize_t ret = 0;
1362 1341
1363 struct driver_private *dprivate = to_driver(kobj); 1342 struct driver_private *dprivate = to_driver(kobj);
1364 struct device_driver *driver; 1343 struct device_driver *driver = dprivate->driver;
1365
1366 if (dprivate != NULL)
1367 driver = dprivate->driver;
1368 else
1369 driver = NULL;
1370 1344
1371 DBGINF("In virtpci_driver_attr_store driver->name:%s\n", driver->name); 1345 DBGINF("In virtpci_driver_attr_store driver->name:%s\n", driver->name);
1372 1346
1373 if (driver) { 1347 if (dattr->store)
1374 if (dattr->store) 1348 ret = dattr->store(driver, buf, count);
1375 ret = dattr->store(driver, buf, count); 1349
1376 }
1377 return ret; 1350 return ret;
1378} 1351}
1379 1352
diff --git a/drivers/staging/unisys/visorchannel/visorchannel.h b/drivers/staging/unisys/visorchannel/visorchannel.h
index 5061edff959a..63f1b9760373 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel.h
+++ b/drivers/staging/unisys/visorchannel/visorchannel.h
@@ -29,49 +29,48 @@
29#define BOOL int 29#define BOOL int
30#endif 30#endif
31 31
32/* VISORCHANNEL is an opaque structure to users.
33 * Fields are declared only in the implementation .c files.
34 */
35typedef struct VISORCHANNEL_Tag VISORCHANNEL;
36
37/* Note that for visorchannel_create() and visorchannel_create_overlapped(), 32/* Note that for visorchannel_create() and visorchannel_create_overlapped(),
38 * <channelBytes> and <guid> arguments may be 0 if we are a channel CLIENT. 33 * <channel_bytes> and <guid> arguments may be 0 if we are a channel CLIENT.
39 * In this case, the values can simply be read from the channel header. 34 * In this case, the values can simply be read from the channel header.
40 */ 35 */
41VISORCHANNEL *visorchannel_create(HOSTADDRESS physaddr, 36struct visorchannel *visorchannel_create(HOSTADDRESS physaddr,
42 ulong channelBytes, uuid_le guid); 37 ulong channel_bytes, uuid_le guid);
43VISORCHANNEL *visorchannel_create_overlapped(ulong channelBytes, 38struct visorchannel *visorchannel_create_overlapped(ulong channel_bytes,
44 VISORCHANNEL *parent, ulong off, 39 struct visorchannel *parent,
45 uuid_le guid); 40 ulong off, uuid_le guid);
46VISORCHANNEL *visorchannel_create_with_lock(HOSTADDRESS physaddr, 41struct visorchannel *visorchannel_create_with_lock(HOSTADDRESS physaddr,
47 ulong channelBytes, uuid_le guid); 42 ulong channel_bytes,
48VISORCHANNEL *visorchannel_create_overlapped_with_lock(ulong channelBytes, 43 uuid_le guid);
49 VISORCHANNEL *parent, 44struct visorchannel *visorchannel_create_overlapped_with_lock(
50 ulong off, uuid_le guid); 45 ulong channel_bytes,
51void visorchannel_destroy(VISORCHANNEL *channel); 46 struct visorchannel *parent,
52int visorchannel_read(VISORCHANNEL *channel, ulong offset, 47 ulong off, uuid_le guid);
48void visorchannel_destroy(struct visorchannel *channel);
49int visorchannel_read(struct visorchannel *channel, ulong offset,
53 void *local, ulong nbytes); 50 void *local, ulong nbytes);
54int visorchannel_write(VISORCHANNEL *channel, ulong offset, 51int visorchannel_write(struct visorchannel *channel, ulong offset,
55 void *local, ulong nbytes); 52 void *local, ulong nbytes);
56int visorchannel_clear(VISORCHANNEL *channel, ulong offset, 53int visorchannel_clear(struct visorchannel *channel, ulong offset,
57 u8 ch, ulong nbytes); 54 u8 ch, ulong nbytes);
58BOOL visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg); 55BOOL visorchannel_signalremove(struct visorchannel *channel, u32 queue,
59BOOL visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg); 56 void *msg);
60int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue); 57BOOL visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
61int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue); 58 void *msg);
62 59int visorchannel_signalqueue_slots_avail(struct visorchannel *channel,
63HOSTADDRESS visorchannel_get_physaddr(VISORCHANNEL *channel); 60 u32 queue);
64ulong visorchannel_get_nbytes(VISORCHANNEL *channel); 61int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue);
65char *visorchannel_id(VISORCHANNEL *channel, char *s); 62HOSTADDRESS visorchannel_get_physaddr(struct visorchannel *channel);
66char *visorchannel_zoneid(VISORCHANNEL *channel, char *s); 63ulong visorchannel_get_nbytes(struct visorchannel *channel);
67u64 visorchannel_get_clientpartition(VISORCHANNEL *channel); 64char *visorchannel_id(struct visorchannel *channel, char *s);
68uuid_le visorchannel_get_uuid(VISORCHANNEL *channel); 65char *visorchannel_zoneid(struct visorchannel *channel, char *s);
69struct memregion *visorchannel_get_memregion(VISORCHANNEL *channel); 66u64 visorchannel_get_clientpartition(struct visorchannel *channel);
67uuid_le visorchannel_get_uuid(struct visorchannel *channel);
68struct memregion *visorchannel_get_memregion(struct visorchannel *channel);
70char *visorchannel_uuid_id(uuid_le *guid, char *s); 69char *visorchannel_uuid_id(uuid_le *guid, char *s);
71void visorchannel_debug(VISORCHANNEL *channel, int nQueues, 70void visorchannel_debug(struct visorchannel *channel, int num_queues,
72 struct seq_file *seq, u32 off); 71 struct seq_file *seq, u32 off);
73void visorchannel_dump_section(VISORCHANNEL *chan, char *s, 72void visorchannel_dump_section(struct visorchannel *chan, char *s,
74 int off, int len, struct seq_file *seq); 73 int off, int len, struct seq_file *seq);
75void __iomem *visorchannel_get_header(VISORCHANNEL *channel); 74void __iomem *visorchannel_get_header(struct visorchannel *channel);
76 75
77#endif 76#endif
diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
index 36559d5fa673..0188ef866fdd 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
+++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
@@ -28,14 +28,15 @@
28 28
29#define MYDRVNAME "visorchannel" 29#define MYDRVNAME "visorchannel"
30 30
31struct VISORCHANNEL_Tag { 31struct visorchannel {
32 struct memregion *memregion; /* from visor_memregion_create() */ 32 struct memregion *memregion; /* from visor_memregion_create() */
33 struct channel_header chan_hdr; 33 struct channel_header chan_hdr;
34 uuid_le guid; 34 uuid_le guid;
35 ulong size; 35 ulong size;
36 BOOL needs_lock; 36 BOOL needs_lock; /* channel creator knows if more than one
37 spinlock_t insert_lock; 37 * thread will be inserting or removing */
38 spinlock_t remove_lock; 38 spinlock_t insert_lock; /* protect head writes in chan_hdr */
39 spinlock_t remove_lock; /* protect tail writes in chan_hdr */
39 40
40 struct { 41 struct {
41 struct signal_queue_header req_queue; 42 struct signal_queue_header req_queue;
@@ -45,18 +46,18 @@ struct VISORCHANNEL_Tag {
45 } safe_uis_queue; 46 } safe_uis_queue;
46}; 47};
47 48
48/* Creates the VISORCHANNEL abstraction for a data area in memory, but does 49/* Creates the struct visorchannel abstraction for a data area in memory,
49 * NOT modify this data area. 50 * but does NOT modify this data area.
50 */ 51 */
51static VISORCHANNEL * 52static struct visorchannel *
52visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, 53visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes,
53 VISORCHANNEL *parent, ulong off, uuid_le guid, 54 struct visorchannel *parent, ulong off, uuid_le guid,
54 BOOL needs_lock) 55 BOOL needs_lock)
55{ 56{
56 VISORCHANNEL *p = NULL; 57 struct visorchannel *p = NULL;
57 void *rc = NULL; 58 void *rc = NULL;
58 59
59 p = kmalloc(sizeof(VISORCHANNEL), GFP_KERNEL|__GFP_NORETRY); 60 p = kmalloc(sizeof(*p), GFP_KERNEL|__GFP_NORETRY);
60 if (p == NULL) { 61 if (p == NULL) {
61 ERRDRV("allocation failed: (status=0)\n"); 62 ERRDRV("allocation failed: (status=0)\n");
62 rc = NULL; 63 rc = NULL;
@@ -87,18 +88,18 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes,
87 rc = NULL; 88 rc = NULL;
88 goto cleanup; 89 goto cleanup;
89 } 90 }
90 if (channelBytes == 0) 91 if (channel_bytes == 0)
91 /* we had better be a CLIENT of this channel */ 92 /* we had better be a CLIENT of this channel */
92 channelBytes = (ulong)p->chan_hdr.size; 93 channel_bytes = (ulong)p->chan_hdr.size;
93 if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) 94 if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
94 /* we had better be a CLIENT of this channel */ 95 /* we had better be a CLIENT of this channel */
95 guid = p->chan_hdr.chtype; 96 guid = p->chan_hdr.chtype;
96 if (visor_memregion_resize(p->memregion, channelBytes) < 0) { 97 if (visor_memregion_resize(p->memregion, channel_bytes) < 0) {
97 ERRDRV("visor_memregion_resize failed: (status=0)\n"); 98 ERRDRV("visor_memregion_resize failed: (status=0)\n");
98 rc = NULL; 99 rc = NULL;
99 goto cleanup; 100 goto cleanup;
100 } 101 }
101 p->size = channelBytes; 102 p->size = channel_bytes;
102 p->guid = guid; 103 p->guid = guid;
103 104
104 rc = p; 105 rc = p;
@@ -113,44 +114,45 @@ cleanup:
113 return rc; 114 return rc;
114} 115}
115 116
116VISORCHANNEL * 117struct visorchannel *
117visorchannel_create(HOSTADDRESS physaddr, ulong channelBytes, uuid_le guid) 118visorchannel_create(HOSTADDRESS physaddr, ulong channel_bytes, uuid_le guid)
118{ 119{
119 return visorchannel_create_guts(physaddr, channelBytes, NULL, 0, guid, 120 return visorchannel_create_guts(physaddr, channel_bytes, NULL, 0, guid,
120 FALSE); 121 FALSE);
121} 122}
122EXPORT_SYMBOL_GPL(visorchannel_create); 123EXPORT_SYMBOL_GPL(visorchannel_create);
123 124
124VISORCHANNEL * 125struct visorchannel *
125visorchannel_create_with_lock(HOSTADDRESS physaddr, ulong channelBytes, 126visorchannel_create_with_lock(HOSTADDRESS physaddr, ulong channel_bytes,
126 uuid_le guid) 127 uuid_le guid)
127{ 128{
128 return visorchannel_create_guts(physaddr, channelBytes, NULL, 0, guid, 129 return visorchannel_create_guts(physaddr, channel_bytes, NULL, 0, guid,
129 TRUE); 130 TRUE);
130} 131}
131EXPORT_SYMBOL_GPL(visorchannel_create_with_lock); 132EXPORT_SYMBOL_GPL(visorchannel_create_with_lock);
132 133
133VISORCHANNEL * 134struct visorchannel *
134visorchannel_create_overlapped(ulong channelBytes, 135visorchannel_create_overlapped(ulong channel_bytes,
135 VISORCHANNEL *parent, ulong off, uuid_le guid) 136 struct visorchannel *parent, ulong off,
137 uuid_le guid)
136{ 138{
137 return visorchannel_create_guts(0, channelBytes, parent, off, guid, 139 return visorchannel_create_guts(0, channel_bytes, parent, off, guid,
138 FALSE); 140 FALSE);
139} 141}
140EXPORT_SYMBOL_GPL(visorchannel_create_overlapped); 142EXPORT_SYMBOL_GPL(visorchannel_create_overlapped);
141 143
142VISORCHANNEL * 144struct visorchannel *
143visorchannel_create_overlapped_with_lock(ulong channelBytes, 145visorchannel_create_overlapped_with_lock(ulong channel_bytes,
144 VISORCHANNEL *parent, ulong off, 146 struct visorchannel *parent, ulong off,
145 uuid_le guid) 147 uuid_le guid)
146{ 148{
147 return visorchannel_create_guts(0, channelBytes, parent, off, guid, 149 return visorchannel_create_guts(0, channel_bytes, parent, off, guid,
148 TRUE); 150 TRUE);
149} 151}
150EXPORT_SYMBOL_GPL(visorchannel_create_overlapped_with_lock); 152EXPORT_SYMBOL_GPL(visorchannel_create_overlapped_with_lock);
151 153
152void 154void
153visorchannel_destroy(VISORCHANNEL *channel) 155visorchannel_destroy(struct visorchannel *channel)
154{ 156{
155 if (channel == NULL) 157 if (channel == NULL)
156 return; 158 return;
@@ -163,14 +165,14 @@ visorchannel_destroy(VISORCHANNEL *channel)
163EXPORT_SYMBOL_GPL(visorchannel_destroy); 165EXPORT_SYMBOL_GPL(visorchannel_destroy);
164 166
165HOSTADDRESS 167HOSTADDRESS
166visorchannel_get_physaddr(VISORCHANNEL *channel) 168visorchannel_get_physaddr(struct visorchannel *channel)
167{ 169{
168 return visor_memregion_get_physaddr(channel->memregion); 170 return visor_memregion_get_physaddr(channel->memregion);
169} 171}
170EXPORT_SYMBOL_GPL(visorchannel_get_physaddr); 172EXPORT_SYMBOL_GPL(visorchannel_get_physaddr);
171 173
172ulong 174ulong
173visorchannel_get_nbytes(VISORCHANNEL *channel) 175visorchannel_get_nbytes(struct visorchannel *channel)
174{ 176{
175 return channel->size; 177 return channel->size;
176} 178}
@@ -185,42 +187,42 @@ visorchannel_uuid_id(uuid_le *guid, char *s)
185EXPORT_SYMBOL_GPL(visorchannel_uuid_id); 187EXPORT_SYMBOL_GPL(visorchannel_uuid_id);
186 188
187char * 189char *
188visorchannel_id(VISORCHANNEL *channel, char *s) 190visorchannel_id(struct visorchannel *channel, char *s)
189{ 191{
190 return visorchannel_uuid_id(&channel->guid, s); 192 return visorchannel_uuid_id(&channel->guid, s);
191} 193}
192EXPORT_SYMBOL_GPL(visorchannel_id); 194EXPORT_SYMBOL_GPL(visorchannel_id);
193 195
194char * 196char *
195visorchannel_zoneid(VISORCHANNEL *channel, char *s) 197visorchannel_zoneid(struct visorchannel *channel, char *s)
196{ 198{
197 return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s); 199 return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s);
198} 200}
199EXPORT_SYMBOL_GPL(visorchannel_zoneid); 201EXPORT_SYMBOL_GPL(visorchannel_zoneid);
200 202
201HOSTADDRESS 203HOSTADDRESS
202visorchannel_get_clientpartition(VISORCHANNEL *channel) 204visorchannel_get_clientpartition(struct visorchannel *channel)
203{ 205{
204 return channel->chan_hdr.partition_handle; 206 return channel->chan_hdr.partition_handle;
205} 207}
206EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition); 208EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition);
207 209
208uuid_le 210uuid_le
209visorchannel_get_uuid(VISORCHANNEL *channel) 211visorchannel_get_uuid(struct visorchannel *channel)
210{ 212{
211 return channel->guid; 213 return channel->guid;
212} 214}
213EXPORT_SYMBOL_GPL(visorchannel_get_uuid); 215EXPORT_SYMBOL_GPL(visorchannel_get_uuid);
214 216
215struct memregion * 217struct memregion *
216visorchannel_get_memregion(VISORCHANNEL *channel) 218visorchannel_get_memregion(struct visorchannel *channel)
217{ 219{
218 return channel->memregion; 220 return channel->memregion;
219} 221}
220EXPORT_SYMBOL_GPL(visorchannel_get_memregion); 222EXPORT_SYMBOL_GPL(visorchannel_get_memregion);
221 223
222int 224int
223visorchannel_read(VISORCHANNEL *channel, ulong offset, 225visorchannel_read(struct visorchannel *channel, ulong offset,
224 void *local, ulong nbytes) 226 void *local, ulong nbytes)
225{ 227{
226 int rc = visor_memregion_read(channel->memregion, offset, 228 int rc = visor_memregion_read(channel->memregion, offset,
@@ -235,7 +237,7 @@ visorchannel_read(VISORCHANNEL *channel, ulong offset,
235EXPORT_SYMBOL_GPL(visorchannel_read); 237EXPORT_SYMBOL_GPL(visorchannel_read);
236 238
237int 239int
238visorchannel_write(VISORCHANNEL *channel, ulong offset, 240visorchannel_write(struct visorchannel *channel, ulong offset,
239 void *local, ulong nbytes) 241 void *local, ulong nbytes)
240{ 242{
241 if (offset == 0 && nbytes >= sizeof(struct channel_header)) 243 if (offset == 0 && nbytes >= sizeof(struct channel_header))
@@ -246,7 +248,8 @@ visorchannel_write(VISORCHANNEL *channel, ulong offset,
246EXPORT_SYMBOL_GPL(visorchannel_write); 248EXPORT_SYMBOL_GPL(visorchannel_write);
247 249
248int 250int
249visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes) 251visorchannel_clear(struct visorchannel *channel, ulong offset, u8 ch,
252 ulong nbytes)
250{ 253{
251 int rc = -1; 254 int rc = -1;
252 int bufsize = 65536; 255 int bufsize = 65536;
@@ -285,7 +288,7 @@ cleanup:
285EXPORT_SYMBOL_GPL(visorchannel_clear); 288EXPORT_SYMBOL_GPL(visorchannel_clear);
286 289
287void __iomem * 290void __iomem *
288visorchannel_get_header(VISORCHANNEL *channel) 291visorchannel_get_header(struct visorchannel *channel)
289{ 292{
290 return (void __iomem *)&channel->chan_hdr; 293 return (void __iomem *)&channel->chan_hdr;
291} 294}
@@ -316,7 +319,7 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header);
316 sizeof((sig_hdr)->FIELD)) >= 0) 319 sizeof((sig_hdr)->FIELD)) >= 0)
317 320
318static BOOL 321static BOOL
319sig_read_header(VISORCHANNEL *channel, u32 queue, 322sig_read_header(struct visorchannel *channel, u32 queue,
320 struct signal_queue_header *sig_hdr) 323 struct signal_queue_header *sig_hdr)
321{ 324{
322 BOOL rc = FALSE; 325 BOOL rc = FALSE;
@@ -344,7 +347,7 @@ cleanup:
344} 347}
345 348
346static BOOL 349static BOOL
347sig_do_data(VISORCHANNEL *channel, u32 queue, 350sig_do_data(struct visorchannel *channel, u32 queue,
348 struct signal_queue_header *sig_hdr, u32 slot, void *data, 351 struct signal_queue_header *sig_hdr, u32 slot, void *data,
349 BOOL is_write) 352 BOOL is_write)
350{ 353{
@@ -373,14 +376,14 @@ cleanup:
373} 376}
374 377
375static inline BOOL 378static inline BOOL
376sig_read_data(VISORCHANNEL *channel, u32 queue, 379sig_read_data(struct visorchannel *channel, u32 queue,
377 struct signal_queue_header *sig_hdr, u32 slot, void *data) 380 struct signal_queue_header *sig_hdr, u32 slot, void *data)
378{ 381{
379 return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE); 382 return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE);
380} 383}
381 384
382static inline BOOL 385static inline BOOL
383sig_write_data(VISORCHANNEL *channel, u32 queue, 386sig_write_data(struct visorchannel *channel, u32 queue,
384 struct signal_queue_header *sig_hdr, u32 slot, void *data) 387 struct signal_queue_header *sig_hdr, u32 slot, void *data)
385{ 388{
386 return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE); 389 return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE);
@@ -408,27 +411,21 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh,
408 return 1; 411 return 1;
409} /* end safe_sig_queue_validate */ 412} /* end safe_sig_queue_validate */
410 413
411BOOL 414static BOOL
412visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) 415signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
413{ 416{
414 BOOL rc = FALSE;
415 struct signal_queue_header sig_hdr; 417 struct signal_queue_header sig_hdr;
416 418
417 if (channel->needs_lock)
418 spin_lock(&channel->remove_lock);
419
420 if (!sig_read_header(channel, queue, &sig_hdr)) { 419 if (!sig_read_header(channel, queue, &sig_hdr)) {
421 rc = FALSE; 420 return FALSE;
422 goto cleanup;
423 }
424 if (sig_hdr.head == sig_hdr.tail) {
425 rc = FALSE; /* no signals to remove */
426 goto cleanup;
427 } 421 }
422 if (sig_hdr.head == sig_hdr.tail)
423 return FALSE; /* no signals to remove */
424
428 sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; 425 sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
429 if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { 426 if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) {
430 ERRDRV("sig_read_data failed: (status=%d)\n", rc); 427 ERRDRV("sig_read_data failed\n");
431 goto cleanup; 428 return FALSE;
432 } 429 }
433 sig_hdr.num_received++; 430 sig_hdr.num_received++;
434 431
@@ -437,53 +434,54 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg)
437 */ 434 */
438 mb(); /* required for channel synch */ 435 mb(); /* required for channel synch */
439 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { 436 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) {
440 ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", 437 ERRDRV("visor_memregion_write of Tail failed\n");
441 rc); 438 return FALSE;
442 goto cleanup;
443 } 439 }
444 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { 440 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) {
445 ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", 441 ERRDRV("visor_memregion_write of NumSignalsReceived failed\n");
446 rc); 442 return FALSE;
447 goto cleanup;
448 } 443 }
449 rc = TRUE; 444 return TRUE;
450cleanup: 445}
451 if (channel->needs_lock) 446
447BOOL
448visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
449{
450 BOOL rc;
451
452 if (channel->needs_lock) {
453 spin_lock(&channel->remove_lock);
454 rc = signalremove_inner(channel, queue, msg);
452 spin_unlock(&channel->remove_lock); 455 spin_unlock(&channel->remove_lock);
456 } else {
457 rc = signalremove_inner(channel, queue, msg);
458 }
453 459
454 return rc; 460 return rc;
455} 461}
456EXPORT_SYMBOL_GPL(visorchannel_signalremove); 462EXPORT_SYMBOL_GPL(visorchannel_signalremove);
457 463
458BOOL 464static BOOL
459visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) 465signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
460{ 466{
461 BOOL rc = FALSE;
462 struct signal_queue_header sig_hdr; 467 struct signal_queue_header sig_hdr;
463 468
464 if (channel->needs_lock)
465 spin_lock(&channel->insert_lock);
466
467 if (!sig_read_header(channel, queue, &sig_hdr)) { 469 if (!sig_read_header(channel, queue, &sig_hdr)) {
468 rc = FALSE; 470 return FALSE;
469 goto cleanup;
470 } 471 }
471 472
472 sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); 473 sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
473 if (sig_hdr.head == sig_hdr.tail) { 474 if (sig_hdr.head == sig_hdr.tail) {
474 sig_hdr.num_overflows++; 475 sig_hdr.num_overflows++;
475 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { 476 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows))
476 ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", 477 ERRDRV("visor_memregion_write of NumOverflows failed\n");
477 rc); 478
478 goto cleanup; 479 return FALSE;
479 }
480 rc = FALSE;
481 goto cleanup;
482 } 480 }
483 481
484 if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { 482 if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) {
485 ERRDRV("sig_write_data failed: (status=%d)\n", rc); 483 ERRDRV("sig_write_data failed\n");
486 goto cleanup; 484 return FALSE;
487 } 485 }
488 sig_hdr.num_sent++; 486 sig_hdr.num_sent++;
489 487
@@ -492,26 +490,36 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg)
492 */ 490 */
493 mb(); /* required for channel synch */ 491 mb(); /* required for channel synch */
494 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { 492 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) {
495 ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", 493 ERRDRV("visor_memregion_write of Head failed\n");
496 rc); 494 return FALSE;
497 goto cleanup;
498 } 495 }
499 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { 496 if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) {
500 ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", 497 ERRDRV("visor_memregion_write of NumSignalsSent failed\n");
501 rc); 498 return FALSE;
502 goto cleanup;
503 } 499 }
504 rc = TRUE; 500
505cleanup: 501 return TRUE;
506 if (channel->needs_lock) 502}
503
504BOOL
505visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
506{
507 BOOL rc;
508
509 if (channel->needs_lock) {
510 spin_lock(&channel->insert_lock);
511 rc = signalinsert_inner(channel, queue, msg);
507 spin_unlock(&channel->insert_lock); 512 spin_unlock(&channel->insert_lock);
513 } else {
514 rc = signalinsert_inner(channel, queue, msg);
515 }
508 516
509 return rc; 517 return rc;
510} 518}
511EXPORT_SYMBOL_GPL(visorchannel_signalinsert); 519EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
512 520
513int 521int
514visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) 522visorchannel_signalqueue_slots_avail(struct visorchannel *channel, u32 queue)
515{ 523{
516 struct signal_queue_header sig_hdr; 524 struct signal_queue_header sig_hdr;
517 u32 slots_avail, slots_used; 525 u32 slots_avail, slots_used;
@@ -530,7 +538,7 @@ visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue)
530EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail); 538EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail);
531 539
532int 540int
533visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) 541visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue)
534{ 542{
535 struct signal_queue_header sig_hdr; 543 struct signal_queue_header sig_hdr;
536 544
@@ -565,7 +573,7 @@ sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq)
565} 573}
566 574
567void 575void
568visorchannel_debug(VISORCHANNEL *channel, int nQueues, 576visorchannel_debug(struct visorchannel *channel, int num_queues,
569 struct seq_file *seq, u32 off) 577 struct seq_file *seq, u32 off)
570{ 578{
571 HOSTADDRESS addr = 0; 579 HOSTADDRESS addr = 0;
@@ -625,7 +633,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues,
625 if ((phdr->ch_space_offset == 0) || (errcode < 0)) 633 if ((phdr->ch_space_offset == 0) || (errcode < 0))
626 ; 634 ;
627 else 635 else
628 for (i = 0; i < nQueues; i++) { 636 for (i = 0; i < num_queues; i++) {
629 struct signal_queue_header q; 637 struct signal_queue_header q;
630 638
631 errcode = visorchannel_read(channel, 639 errcode = visorchannel_read(channel,
@@ -647,7 +655,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues,
647EXPORT_SYMBOL_GPL(visorchannel_debug); 655EXPORT_SYMBOL_GPL(visorchannel_debug);
648 656
649void 657void
650visorchannel_dump_section(VISORCHANNEL *chan, char *s, 658visorchannel_dump_section(struct visorchannel *chan, char *s,
651 int off, int len, struct seq_file *seq) 659 int off, int len, struct seq_file *seq)
652{ 660{
653 char *buf, *tbuf, *fmtbuf; 661 char *buf, *tbuf, *fmtbuf;
diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c
index 373fa36b7119..e51fd4e3fa2d 100644
--- a/drivers/staging/unisys/visorchipset/file.c
+++ b/drivers/staging/unisys/visorchipset/file.c
@@ -28,85 +28,75 @@
28 28
29#define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c 29#define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c
30 30
31static struct cdev Cdev; 31static struct cdev file_cdev;
32static VISORCHANNEL **PControlVm_channel; 32static struct visorchannel **file_controlvm_channel;
33static dev_t MajorDev = -1; /**< indicates major num for device */ 33static dev_t majordev = -1; /**< indicates major num for device */
34static BOOL Registered = FALSE; 34static BOOL registered = FALSE;
35 35
36static int visorchipset_open(struct inode *inode, struct file *file); 36static int visorchipset_open(struct inode *inode, struct file *file);
37static int visorchipset_release(struct inode *inode, struct file *file); 37static int visorchipset_release(struct inode *inode, struct file *file);
38static int visorchipset_mmap(struct file *file, struct vm_area_struct *vma); 38static int visorchipset_mmap(struct file *file, struct vm_area_struct *vma);
39#ifdef HAVE_UNLOCKED_IOCTL
40long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 39long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
41#else
42int visorchipset_ioctl(struct inode *inode, struct file *file,
43 unsigned int cmd, unsigned long arg);
44#endif
45 40
46static const struct file_operations visorchipset_fops = { 41static const struct file_operations visorchipset_fops = {
47 .owner = THIS_MODULE, 42 .owner = THIS_MODULE,
48 .open = visorchipset_open, 43 .open = visorchipset_open,
49 .read = NULL, 44 .read = NULL,
50 .write = NULL, 45 .write = NULL,
51#ifdef HAVE_UNLOCKED_IOCTL
52 .unlocked_ioctl = visorchipset_ioctl, 46 .unlocked_ioctl = visorchipset_ioctl,
53#else
54 .ioctl = visorchipset_ioctl,
55#endif
56 .release = visorchipset_release, 47 .release = visorchipset_release,
57 .mmap = visorchipset_mmap, 48 .mmap = visorchipset_mmap,
58}; 49};
59 50
60int 51int
61visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel) 52visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
62{ 53{
63 int rc = -1; 54 int rc = 0;
64 55
65 PControlVm_channel = pControlVm_channel; 56 file_controlvm_channel = controlvm_channel;
66 MajorDev = majorDev; 57 majordev = major_dev;
67 cdev_init(&Cdev, &visorchipset_fops); 58 cdev_init(&file_cdev, &visorchipset_fops);
68 Cdev.owner = THIS_MODULE; 59 file_cdev.owner = THIS_MODULE;
69 if (MAJOR(MajorDev) == 0) { 60 if (MAJOR(majordev) == 0) {
70 /* dynamic major device number registration required */ 61 /* dynamic major device number registration required */
71 if (alloc_chrdev_region(&MajorDev, 0, 1, MYDRVNAME) < 0) { 62 if (alloc_chrdev_region(&majordev, 0, 1, MYDRVNAME) < 0) {
72 ERRDRV("Unable to allocate+register char device %s", 63 ERRDRV("Unable to allocate+register char device %s",
73 MYDRVNAME); 64 MYDRVNAME);
74 goto Away; 65 return -1;
75 } 66 }
76 Registered = TRUE; 67 registered = TRUE;
77 INFODRV("New major number %d registered\n", MAJOR(MajorDev)); 68 INFODRV("New major number %d registered\n", MAJOR(majordev));
78 } else { 69 } else {
79 /* static major device number registration required */ 70 /* static major device number registration required */
80 if (register_chrdev_region(MajorDev, 1, MYDRVNAME) < 0) { 71 if (register_chrdev_region(majordev, 1, MYDRVNAME) < 0) {
81 ERRDRV("Unable to register char device %s", MYDRVNAME); 72 ERRDRV("Unable to register char device %s", MYDRVNAME);
82 goto Away; 73 return -1;
83 } 74 }
84 Registered = TRUE; 75 registered = TRUE;
85 INFODRV("Static major number %d registered\n", MAJOR(MajorDev)); 76 INFODRV("Static major number %d registered\n", MAJOR(majordev));
86 } 77 }
87 if (cdev_add(&Cdev, MKDEV(MAJOR(MajorDev), 0), 1) < 0) { 78 rc = cdev_add(&file_cdev, MKDEV(MAJOR(majordev), 0), 1);
79 if (rc < 0) {
88 ERRDRV("failed to create char device: (status=%d)\n", rc); 80 ERRDRV("failed to create char device: (status=%d)\n", rc);
89 goto Away; 81 return -1;
90 } 82 }
91 INFODRV("Registered char device for %s (major=%d)", 83 INFODRV("Registered char device for %s (major=%d)",
92 MYDRVNAME, MAJOR(MajorDev)); 84 MYDRVNAME, MAJOR(majordev));
93 rc = 0; 85 return 0;
94Away:
95 return rc;
96} 86}
97 87
98void 88void
99visorchipset_file_cleanup(void) 89visorchipset_file_cleanup(void)
100{ 90{
101 if (Cdev.ops != NULL) 91 if (file_cdev.ops != NULL)
102 cdev_del(&Cdev); 92 cdev_del(&file_cdev);
103 Cdev.ops = NULL; 93 file_cdev.ops = NULL;
104 if (Registered) { 94 if (registered) {
105 if (MAJOR(MajorDev) >= 0) { 95 if (MAJOR(majordev) >= 0) {
106 unregister_chrdev_region(MajorDev, 1); 96 unregister_chrdev_region(majordev, 1);
107 MajorDev = MKDEV(0, 0); 97 majordev = MKDEV(0, 0);
108 } 98 }
109 Registered = FALSE; 99 registered = FALSE;
110 } 100 }
111} 101}
112 102
@@ -114,17 +104,12 @@ static int
114visorchipset_open(struct inode *inode, struct file *file) 104visorchipset_open(struct inode *inode, struct file *file)
115{ 105{
116 unsigned minor_number = iminor(inode); 106 unsigned minor_number = iminor(inode);
117 int rc = -ENODEV;
118 107
119 DEBUGDRV("%s", __func__); 108 DEBUGDRV("%s", __func__);
120 if (minor_number != 0) 109 if (minor_number != 0)
121 goto Away; 110 return -ENODEV;
122 file->private_data = NULL; 111 file->private_data = NULL;
123 rc = 0; 112 return 0;
124Away:
125 if (rc < 0)
126 ERRDRV("%s minor=%d failed", __func__, minor_number);
127 return rc;
128} 113}
129 114
130static int 115static int
@@ -137,7 +122,7 @@ visorchipset_release(struct inode *inode, struct file *file)
137static int 122static int
138visorchipset_mmap(struct file *file, struct vm_area_struct *vma) 123visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
139{ 124{
140 ulong physAddr = 0; 125 ulong physaddr = 0;
141 ulong offset = vma->vm_pgoff << PAGE_SHIFT; 126 ulong offset = vma->vm_pgoff << PAGE_SHIFT;
142 GUEST_PHYSICAL_ADDRESS addr = 0; 127 GUEST_PHYSICAL_ADDRESS addr = 0;
143 128
@@ -150,11 +135,11 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
150 switch (offset) { 135 switch (offset) {
151 case VISORCHIPSET_MMAP_CONTROLCHANOFFSET: 136 case VISORCHIPSET_MMAP_CONTROLCHANOFFSET:
152 vma->vm_flags |= VM_IO; 137 vma->vm_flags |= VM_IO;
153 if (*PControlVm_channel == NULL) { 138 if (*file_controlvm_channel == NULL) {
154 ERRDRV("%s no controlvm channel yet", __func__); 139 ERRDRV("%s no controlvm channel yet", __func__);
155 return -ENXIO; 140 return -ENXIO;
156 } 141 }
157 visorchannel_read(*PControlVm_channel, 142 visorchannel_read(*file_controlvm_channel,
158 offsetof(struct spar_controlvm_channel_protocol, 143 offsetof(struct spar_controlvm_channel_protocol,
159 gp_control_channel), 144 gp_control_channel),
160 &addr, sizeof(addr)); 145 &addr, sizeof(addr));
@@ -162,10 +147,10 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
162 ERRDRV("%s control channel address is 0", __func__); 147 ERRDRV("%s control channel address is 0", __func__);
163 return -ENXIO; 148 return -ENXIO;
164 } 149 }
165 physAddr = (ulong) (addr); 150 physaddr = (ulong)addr;
166 DEBUGDRV("mapping physical address = 0x%lx", physAddr); 151 DEBUGDRV("mapping physical address = 0x%lx", physaddr);
167 if (remap_pfn_range(vma, vma->vm_start, 152 if (remap_pfn_range(vma, vma->vm_start,
168 physAddr >> PAGE_SHIFT, 153 physaddr >> PAGE_SHIFT,
169 vma->vm_end - vma->vm_start, 154 vma->vm_end - vma->vm_start,
170 /*pgprot_noncached */ 155 /*pgprot_noncached */
171 (vma->vm_page_prot))) { 156 (vma->vm_page_prot))) {
@@ -180,16 +165,8 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
180 return 0; 165 return 0;
181} 166}
182 167
183#ifdef HAVE_UNLOCKED_IOCTL 168long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
184long
185visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
186#else
187int
188visorchipset_ioctl(struct inode *inode, struct file *file,
189 unsigned int cmd, unsigned long arg)
190#endif
191{ 169{
192 int rc = SUCCESS;
193 s64 adjustment; 170 s64 adjustment;
194 s64 vrtc_offset; 171 s64 vrtc_offset;
195 172
@@ -200,28 +177,21 @@ visorchipset_ioctl(struct inode *inode, struct file *file,
200 vrtc_offset = issue_vmcall_query_guest_virtual_time_offset(); 177 vrtc_offset = issue_vmcall_query_guest_virtual_time_offset();
201 if (copy_to_user 178 if (copy_to_user
202 ((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset))) { 179 ((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset))) {
203 rc = -EFAULT; 180 return -EFAULT;
204 goto Away;
205 } 181 }
206 DBGINF("insde visorchipset_ioctl, cmd=%d, vrtc_offset=%lld", 182 DBGINF("insde visorchipset_ioctl, cmd=%d, vrtc_offset=%lld",
207 cmd, vrtc_offset); 183 cmd, vrtc_offset);
208 break; 184 return SUCCESS;
209 case VMCALL_UPDATE_PHYSICAL_TIME: 185 case VMCALL_UPDATE_PHYSICAL_TIME:
210 if (copy_from_user 186 if (copy_from_user
211 (&adjustment, (void __user *)arg, sizeof(adjustment))) { 187 (&adjustment, (void __user *)arg, sizeof(adjustment))) {
212 rc = -EFAULT; 188 return -EFAULT;
213 goto Away;
214 } 189 }
215 DBGINF("insde visorchipset_ioctl, cmd=%d, adjustment=%lld", cmd, 190 DBGINF("insde visorchipset_ioctl, cmd=%d, adjustment=%lld", cmd,
216 adjustment); 191 adjustment);
217 rc = issue_vmcall_update_physical_time(adjustment); 192 return issue_vmcall_update_physical_time(adjustment);
218 break;
219 default: 193 default:
220 LOGERR("visorchipset_ioctl received invalid command"); 194 LOGERR("visorchipset_ioctl received invalid command");
221 rc = -EFAULT; 195 return -EFAULT;
222 break;
223 } 196 }
224Away:
225 DBGINF("exiting %d!", rc);
226 return rc;
227} 197}
diff --git a/drivers/staging/unisys/visorchipset/file.h b/drivers/staging/unisys/visorchipset/file.h
index 21bb906242e1..dc7a19556b3f 100644
--- a/drivers/staging/unisys/visorchipset/file.h
+++ b/drivers/staging/unisys/visorchipset/file.h
@@ -20,7 +20,8 @@
20 20
21#include "globals.h" 21#include "globals.h"
22 22
23int visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel); 23int visorchipset_file_init(dev_t majorDev,
24 struct visorchannel **pControlVm_channel);
24void visorchipset_file_cleanup(void); 25void visorchipset_file_cleanup(void);
25 26
26#endif 27#endif
diff --git a/drivers/staging/unisys/visorchipset/globals.h b/drivers/staging/unisys/visorchipset/globals.h
index 0fe14599f185..a1d35d4bef2e 100644
--- a/drivers/staging/unisys/visorchipset/globals.h
+++ b/drivers/staging/unisys/visorchipset/globals.h
@@ -15,7 +15,6 @@
15 * details. 15 * details.
16 */ 16 */
17 17
18
19#ifndef __VISORCHIPSET_GLOBALS_H__ 18#ifndef __VISORCHIPSET_GLOBALS_H__
20#define __VISORCHIPSET_GLOBALS_H__ 19#define __VISORCHIPSET_GLOBALS_H__
21 20
@@ -28,7 +27,6 @@
28 27
29#define MYDRVNAME "visorchipset" 28#define MYDRVNAME "visorchipset"
30 29
31
32/* module parameters */ 30/* module parameters */
33 31
34extern int visorchipset_testvnic; 32extern int visorchipset_testvnic;
diff --git a/drivers/staging/unisys/visorchipset/testing.h b/drivers/staging/unisys/visorchipset/testing.h
deleted file mode 100644
index 573aa8b5ba6a..000000000000
--- a/drivers/staging/unisys/visorchipset/testing.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/* testing.h
2 *
3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
15 * details.
16 */
17
18#ifndef __VISORCHIPSET_TESTING_H__
19#define __VISORCHIPSET_TESTING_H__
20
21#define VISORCHIPSET_TEST_PROC
22#include <linux/uuid.h>
23#include "globals.h"
24#include "controlvmchannel.h"
25
26void test_produce_test_message(struct controlvm_message *msg,
27 int isLocalTestAddr);
28BOOL test_consume_test_message(struct controlvm_message *msg);
29void test_manufacture_vnic_client_add(void *p);
30void test_manufacture_vnic_client_add_phys(HOSTADDRESS addr);
31void test_manufacture_preamble_messages(void);
32void test_manufacture_device_attach(ulong busNo, ulong devNo);
33void test_manufacture_device_add(ulong busNo, ulong devNo, uuid_le dataTypeGuid,
34 void *pChannel);
35void test_manufacture_add_bus(ulong busNo, ulong maxDevices,
36 uuid_le id, u8 *name, BOOL isServer);
37void test_manufacture_device_destroy(ulong busNo, ulong devNo);
38void test_manufacture_bus_destroy(ulong busNo);
39void test_manufacture_detach_externalPort(ulong switchNo, ulong externalPortNo);
40void test_manufacture_detach_internalPort(ulong switchNo, ulong internalPortNo);
41void test_cleanup(void);
42
43#endif
diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h
index 46dad63fa2c8..98f3ba4c13ac 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset.h
@@ -158,61 +158,6 @@ findbus(struct list_head *list, u32 bus_no)
158 return NULL; 158 return NULL;
159} 159}
160 160
161/** Attributes for a particular Supervisor switch.
162 */
163struct visorchipset_switch_info {
164 u32 switch_no;
165 struct visorchipset_state state;
166 uuid_le switch_type_uuid;
167 u8 *authservice1;
168 u8 *authservice2;
169 u8 *authservice3;
170 u8 *security_context;
171 u64 reserved;
172 u32 reserved2; /* control_vm_id */
173 struct device dev;
174 BOOL dev_exists;
175 struct controlvm_message_header pending_msg_hdr;
176};
177
178/** Attributes for a particular Supervisor external port, which is connected
179 * to a specific switch.
180 */
181struct visorchipset_externalport_info {
182 u32 switch_no;
183 u32 external_port_no;
184 struct visorchipset_state state;
185 uuid_le network_zone_uuid;
186 int pd_port;
187 u8 *ip;
188 u8 *ip_netmask;
189 u8 *ip_broadcast;
190 u8 *ip_network;
191 u8 *ip_gateway;
192 u8 *ip_dns;
193 u64 reserved1;
194 u32 reserved2; /* control_vm_id */
195 struct device dev;
196 BOOL dev_exists;
197 struct controlvm_message_header pending_msg_hdr;
198};
199
200/** Attributes for a particular Supervisor internal port, which is how a
201 * device connects to a particular switch.
202 */
203struct visorchipset_internalport_info {
204 u32 switch_no;
205 u32 internal_port_no;
206 struct visorchipset_state state;
207 u32 bus_no; /* valid only when state.attached == 1 */
208 u32 dev_no; /* valid only when state.attached == 1 */
209 u64 reserved1;
210 u32 reserved2; /* CONTROLVM_ID */
211 struct controlvm_message_header pending_msg_hdr;
212 MYPROCOBJECT *proc_object;
213
214};
215
216/* These functions will be called from within visorchipset when certain 161/* These functions will be called from within visorchipset when certain
217 * events happen. (The implementation of these functions is outside of 162 * events happen. (The implementation of these functions is outside of
218 * visorchipset.) 163 * visorchipset.)
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index 7e6be32cf7bb..f606ee9e0de9 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -20,7 +20,6 @@
20#include "procobjecttree.h" 20#include "procobjecttree.h"
21#include "visorchannel.h" 21#include "visorchannel.h"
22#include "periodic_work.h" 22#include "periodic_work.h"
23#include "testing.h"
24#include "file.h" 23#include "file.h"
25#include "parser.h" 24#include "parser.h"
26#include "uniklog.h" 25#include "uniklog.h"
@@ -102,7 +101,7 @@ static struct controlvm_message_packet g_DeviceChangeStatePacket;
102static LIST_HEAD(BusInfoList); 101static LIST_HEAD(BusInfoList);
103static LIST_HEAD(DevInfoList); 102static LIST_HEAD(DevInfoList);
104 103
105static VISORCHANNEL *ControlVm_channel; 104static struct visorchannel *ControlVm_channel;
106 105
107typedef struct { 106typedef struct {
108 u8 __iomem *ptr; /* pointer to base address of payload pool */ 107 u8 __iomem *ptr; /* pointer to base address of payload pool */
@@ -1595,7 +1594,7 @@ parahotplug_next_id(void)
1595static unsigned long 1594static unsigned long
1596parahotplug_next_expiration(void) 1595parahotplug_next_expiration(void)
1597{ 1596{
1598 return jiffies + PARAHOTPLUG_TIMEOUT_MS * HZ / 1000; 1597 return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS);
1599} 1598}
1600 1599
1601/* 1600/*
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_umode.h b/drivers/staging/unisys/visorchipset/visorchipset_umode.h
index 06ba5b7e4254..6cf6eccb3f4a 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_umode.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset_umode.h
@@ -26,8 +26,6 @@
26#ifndef __VISORCHIPSET_UMODE_H 26#ifndef __VISORCHIPSET_UMODE_H
27#define __VISORCHIPSET_UMODE_H 27#define __VISORCHIPSET_UMODE_H
28 28
29
30
31/** The user-mode program can access the control channel buffer directly 29/** The user-mode program can access the control channel buffer directly
32 * via this memory map. 30 * via this memory map.
33 */ 31 */
diff --git a/drivers/staging/unisys/visorutil/charqueue.c b/drivers/staging/unisys/visorutil/charqueue.c
index 1ce7003c3a90..ac7acb7c5b79 100644
--- a/drivers/staging/unisys/visorutil/charqueue.c
+++ b/drivers/staging/unisys/visorutil/charqueue.c
@@ -28,7 +28,7 @@
28struct charqueue { 28struct charqueue {
29 int alloc_size; 29 int alloc_size;
30 int nslots; 30 int nslots;
31 spinlock_t lock; 31 spinlock_t lock; /* read/write lock for this structure */
32 int head, tail; 32 int head, tail;
33 unsigned char buf[0]; 33 unsigned char buf[0];
34}; 34};
diff --git a/drivers/staging/unisys/visorutil/procobjecttree.c b/drivers/staging/unisys/visorutil/procobjecttree.c
index 195772d22c9e..82279ca5fbe1 100644
--- a/drivers/staging/unisys/visorutil/procobjecttree.c
+++ b/drivers/staging/unisys/visorutil/procobjecttree.c
@@ -25,12 +25,12 @@
25 * need in order to call the callback function that supplies the /proc read 25 * need in order to call the callback function that supplies the /proc read
26 * info for that file. 26 * info for that file.
27 */ 27 */
28typedef struct { 28struct proc_dir_entry_context {
29 void (*show_property)(struct seq_file *, void *, int); 29 void (*show_property)(struct seq_file *, void *, int);
30 MYPROCOBJECT *procObject; 30 MYPROCOBJECT *procObject;
31 int propertyIndex; 31 int propertyIndex;
32 32
33} PROCDIRENTRYCONTEXT; 33};
34 34
35/** This describes the attributes of a tree rooted at 35/** This describes the attributes of a tree rooted at
36 * <procDirRoot>/<name[0]>/<name[1]>/... 36 * <procDirRoot>/<name[0]>/<name[1]>/...
@@ -86,7 +86,7 @@ struct MYPROCOBJECT_Tag {
86 86
87 /** this is a holding area for the context information that is needed 87 /** this is a holding area for the context information that is needed
88 * to run the /proc callback function */ 88 * to run the /proc callback function */
89 PROCDIRENTRYCONTEXT *procDirPropertyContexts; 89 struct proc_dir_entry_context *procDirPropertyContexts;
90}; 90};
91 91
92 92
@@ -254,15 +254,16 @@ MYPROCOBJECT *visor_proc_CreateObject(MYPROCTYPE *type,
254 goto Away; 254 goto Away;
255 } 255 }
256 obj->procDirPropertyContexts = 256 obj->procDirPropertyContexts =
257 kzalloc((type->nProperties + 1) * sizeof(PROCDIRENTRYCONTEXT), 257 kzalloc((type->nProperties + 1) *
258 sizeof(struct proc_dir_entry_context),
258 GFP_KERNEL | __GFP_NORETRY); 259 GFP_KERNEL | __GFP_NORETRY);
259 if (obj->procDirPropertyContexts == NULL) { 260 if (obj->procDirPropertyContexts == NULL) {
260 ERRDRV("out of memory\n"); 261 ERRDRV("out of memory\n");
261 goto Away; 262 goto Away;
262 } 263 }
263 obj->procDirProperties = 264 obj->procDirProperties = kzalloc((type->nProperties + 1) *
264 kzalloc((type->nProperties + 1) * sizeof(struct proc_dir_entry *), 265 sizeof(struct proc_dir_entry *),
265 GFP_KERNEL | __GFP_NORETRY); 266 GFP_KERNEL | __GFP_NORETRY);
266 if (obj->procDirProperties == NULL) { 267 if (obj->procDirProperties == NULL) {
267 ERRDRV("out of memory\n"); 268 ERRDRV("out of memory\n");
268 goto Away; 269 goto Away;
@@ -276,8 +277,8 @@ MYPROCOBJECT *visor_proc_CreateObject(MYPROCTYPE *type,
276 /* only create properties that have names */ 277 /* only create properties that have names */
277 obj->procDirProperties[i] = 278 obj->procDirProperties[i] =
278 createProcFile(type->propertyNames[i], 279 createProcFile(type->propertyNames[i],
279 obj->procDir, &proc_fops, 280 obj->procDir, &proc_fops,
280 &obj->procDirPropertyContexts[i]); 281 &obj->procDirPropertyContexts[i]);
281 if (obj->procDirProperties[i] == NULL) { 282 if (obj->procDirProperties[i] == NULL) {
282 rc = NULL; 283 rc = NULL;
283 goto Away; 284 goto Away;
@@ -340,7 +341,7 @@ EXPORT_SYMBOL_GPL(visor_proc_DestroyObject);
340 341
341static int seq_show(struct seq_file *seq, void *offset) 342static int seq_show(struct seq_file *seq, void *offset)
342{ 343{
343 PROCDIRENTRYCONTEXT *ctx = (PROCDIRENTRYCONTEXT *)(seq->private); 344 struct proc_dir_entry_context *ctx = seq->private;
344 345
345 if (ctx == NULL) { 346 if (ctx == NULL) {
346 ERRDRV("I don't have a freakin' clue..."); 347 ERRDRV("I don't have a freakin' clue...");
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index f8c5fc371c4c..565ba189afb2 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -27,7 +27,8 @@
27 * 27 *
28 * Functions: 28 * Functions:
29 * BBuGetFrameTime - Calculate data frame transmitting time 29 * BBuGetFrameTime - Calculate data frame transmitting time
30 * BBvCaculateParameter - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx 30 * BBvCaculateParameter - Caculate PhyLength, PhyService and Phy Signal
31 * parameter for baseband Tx
31 * BBbReadEmbedded - Embedded read baseband register via MAC 32 * BBbReadEmbedded - Embedded read baseband register via MAC
32 * BBbWriteEmbedded - Embedded write baseband register via MAC 33 * BBbWriteEmbedded - Embedded write baseband register via MAC
33 * BBbVT3253Init - VIA VT3253 baseband chip init code 34 * BBbVT3253Init - VIA VT3253 baseband chip init code
@@ -1698,46 +1699,6 @@ static const unsigned short awcFrameTime[MAX_RATE] = {
1698 10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216 1699 10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216
1699}; 1700};
1700 1701
1701/*--------------------- Static Functions --------------------------*/
1702
1703static
1704unsigned long
1705s_ulGetRatio(struct vnt_private *priv);
1706
1707static
1708void
1709s_vChangeAntenna(
1710 struct vnt_private *priv
1711);
1712
1713static
1714void
1715s_vChangeAntenna(
1716 struct vnt_private *priv
1717)
1718{
1719 if (priv->dwRxAntennaSel == 0) {
1720 priv->dwRxAntennaSel = 1;
1721 if (priv->bTxRxAntInv == true)
1722 BBvSetRxAntennaMode(priv, ANT_A);
1723 else
1724 BBvSetRxAntennaMode(priv, ANT_B);
1725 } else {
1726 priv->dwRxAntennaSel = 0;
1727 if (priv->bTxRxAntInv == true)
1728 BBvSetRxAntennaMode(priv, ANT_B);
1729 else
1730 BBvSetRxAntennaMode(priv, ANT_A);
1731 }
1732 if (priv->dwTxAntennaSel == 0) {
1733 priv->dwTxAntennaSel = 1;
1734 BBvSetTxAntennaMode(priv, ANT_B);
1735 } else {
1736 priv->dwTxAntennaSel = 0;
1737 BBvSetTxAntennaMode(priv, ANT_A);
1738 }
1739}
1740
1741/*--------------------- Export Variables --------------------------*/ 1702/*--------------------- Export Variables --------------------------*/
1742/* 1703/*
1743 * Description: Calculate data frame transmitting time 1704 * Description: Calculate data frame transmitting time
@@ -2412,303 +2373,3 @@ BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID)
2412 BBbWriteEmbedded(priv, 0x0C, 0x00); /* CR12 */ 2373 BBbWriteEmbedded(priv, 0x0C, 0x00); /* CR12 */
2413 BBbWriteEmbedded(priv, 0x0D, 0x01); /* CR13 */ 2374 BBbWriteEmbedded(priv, 0x0D, 0x01); /* CR13 */
2414} 2375}
2415
2416static
2417unsigned long
2418s_ulGetRatio(struct vnt_private *priv)
2419{
2420 unsigned long ulRatio = 0;
2421 unsigned long ulMaxPacket;
2422 unsigned long ulPacketNum;
2423
2424 /* This is a thousand-ratio */
2425 ulMaxPacket = priv->uNumSQ3[RATE_54M];
2426 if (priv->uNumSQ3[RATE_54M] != 0) {
2427 ulPacketNum = priv->uNumSQ3[RATE_54M];
2428 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2429 ulRatio += TOP_RATE_54M;
2430 }
2431 if (priv->uNumSQ3[RATE_48M] > ulMaxPacket) {
2432 ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M];
2433 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2434 ulRatio += TOP_RATE_48M;
2435 ulMaxPacket = priv->uNumSQ3[RATE_48M];
2436 }
2437 if (priv->uNumSQ3[RATE_36M] > ulMaxPacket) {
2438 ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
2439 priv->uNumSQ3[RATE_36M];
2440 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2441 ulRatio += TOP_RATE_36M;
2442 ulMaxPacket = priv->uNumSQ3[RATE_36M];
2443 }
2444 if (priv->uNumSQ3[RATE_24M] > ulMaxPacket) {
2445 ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
2446 priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M];
2447 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2448 ulRatio += TOP_RATE_24M;
2449 ulMaxPacket = priv->uNumSQ3[RATE_24M];
2450 }
2451 if (priv->uNumSQ3[RATE_18M] > ulMaxPacket) {
2452 ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
2453 priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M] +
2454 priv->uNumSQ3[RATE_18M];
2455 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2456 ulRatio += TOP_RATE_18M;
2457 ulMaxPacket = priv->uNumSQ3[RATE_18M];
2458 }
2459 if (priv->uNumSQ3[RATE_12M] > ulMaxPacket) {
2460 ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
2461 priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M] +
2462 priv->uNumSQ3[RATE_18M] + priv->uNumSQ3[RATE_12M];
2463 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2464 ulRatio += TOP_RATE_12M;
2465 ulMaxPacket = priv->uNumSQ3[RATE_12M];
2466 }
2467 if (priv->uNumSQ3[RATE_11M] > ulMaxPacket) {
2468 ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
2469 priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M] -
2470 priv->uNumSQ3[RATE_6M] - priv->uNumSQ3[RATE_9M];
2471 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2472 ulRatio += TOP_RATE_11M;
2473 ulMaxPacket = priv->uNumSQ3[RATE_11M];
2474 }
2475 if (priv->uNumSQ3[RATE_9M] > ulMaxPacket) {
2476 ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
2477 priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M] -
2478 priv->uNumSQ3[RATE_6M];
2479 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2480 ulRatio += TOP_RATE_9M;
2481 ulMaxPacket = priv->uNumSQ3[RATE_9M];
2482 }
2483 if (priv->uNumSQ3[RATE_6M] > ulMaxPacket) {
2484 ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
2485 priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M];
2486 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2487 ulRatio += TOP_RATE_6M;
2488 ulMaxPacket = priv->uNumSQ3[RATE_6M];
2489 }
2490 if (priv->uNumSQ3[RATE_5M] > ulMaxPacket) {
2491 ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
2492 priv->uNumSQ3[RATE_2M];
2493 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2494 ulRatio += TOP_RATE_55M;
2495 ulMaxPacket = priv->uNumSQ3[RATE_5M];
2496 }
2497 if (priv->uNumSQ3[RATE_2M] > ulMaxPacket) {
2498 ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M];
2499 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2500 ulRatio += TOP_RATE_2M;
2501 ulMaxPacket = priv->uNumSQ3[RATE_2M];
2502 }
2503 if (priv->uNumSQ3[RATE_1M] > ulMaxPacket) {
2504 ulPacketNum = priv->uDiversityCnt;
2505 ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
2506 ulRatio += TOP_RATE_1M;
2507 }
2508
2509 return ulRatio;
2510}
2511
2512void
2513BBvClearAntDivSQ3Value(struct vnt_private *priv)
2514{
2515 unsigned int ii;
2516
2517 priv->uDiversityCnt = 0;
2518 for (ii = 0; ii < MAX_RATE; ii++)
2519 priv->uNumSQ3[ii] = 0;
2520}
2521
2522/*
2523 * Description: Antenna Diversity
2524 *
2525 * Parameters:
2526 * In:
2527 * priv - Device Structure
2528 * byRSR - RSR from received packet
2529 * bySQ3 - SQ3 value from received packet
2530 * Out:
2531 * none
2532 *
2533 * Return Value: none
2534 *
2535 */
2536
2537void BBvAntennaDiversity(struct vnt_private *priv,
2538 unsigned char byRxRate, unsigned char bySQ3)
2539{
2540 if ((byRxRate >= MAX_RATE) || (priv->wAntDiversityMaxRate >= MAX_RATE))
2541 return;
2542
2543 priv->uDiversityCnt++;
2544
2545 priv->uNumSQ3[byRxRate]++;
2546
2547 if (priv->byAntennaState == 0) {
2548 if (priv->uDiversityCnt > priv->ulDiversityNValue) {
2549 pr_debug("ulDiversityNValue=[%d],54M-[%d]\n",
2550 (int)priv->ulDiversityNValue,
2551 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate]);
2552
2553 if (priv->uNumSQ3[priv->wAntDiversityMaxRate] < priv->uDiversityCnt/2) {
2554 priv->ulRatio_State0 = s_ulGetRatio(priv);
2555 pr_debug("SQ3_State0, rate = [%08x]\n",
2556 (int)priv->ulRatio_State0);
2557
2558 if (priv->byTMax == 0)
2559 return;
2560 pr_debug("1.[%08x], uNumSQ3[%d]=%d, %d\n",
2561 (int)priv->ulRatio_State0,
2562 (int)priv->wAntDiversityMaxRate,
2563 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate],
2564 (int)priv->uDiversityCnt);
2565
2566 s_vChangeAntenna(priv);
2567 priv->byAntennaState = 1;
2568 del_timer(&priv->TimerSQ3Tmax3);
2569 del_timer(&priv->TimerSQ3Tmax2);
2570 priv->TimerSQ3Tmax1.expires = RUN_AT(priv->byTMax * HZ);
2571 add_timer(&priv->TimerSQ3Tmax1);
2572
2573 } else {
2574 priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ);
2575 add_timer(&priv->TimerSQ3Tmax3);
2576 }
2577 BBvClearAntDivSQ3Value(priv);
2578
2579 }
2580 } else { /* byAntennaState == 1 */
2581
2582 if (priv->uDiversityCnt > priv->ulDiversityMValue) {
2583 del_timer(&priv->TimerSQ3Tmax1);
2584
2585 priv->ulRatio_State1 = s_ulGetRatio(priv);
2586 pr_debug("RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n",
2587 (int)priv->ulRatio_State0,
2588 (int)priv->ulRatio_State1);
2589
2590 if (priv->ulRatio_State1 < priv->ulRatio_State0) {
2591 pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
2592 (int)priv->ulRatio_State0,
2593 (int)priv->ulRatio_State1,
2594 (int)priv->wAntDiversityMaxRate,
2595 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate],
2596 (int)priv->uDiversityCnt);
2597
2598 s_vChangeAntenna(priv);
2599 priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ);
2600 priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ);
2601 add_timer(&priv->TimerSQ3Tmax3);
2602 add_timer(&priv->TimerSQ3Tmax2);
2603 }
2604 priv->byAntennaState = 0;
2605 BBvClearAntDivSQ3Value(priv);
2606 }
2607 } /* byAntennaState */
2608}
2609
2610/*+
2611 *
2612 * Description:
2613 * Timer for SQ3 antenna diversity
2614 *
2615 * Parameters:
2616 * In:
2617 * Out:
2618 * none
2619 *
2620 * Return Value: none
2621 *
2622 -*/
2623
2624void
2625TimerSQ3CallBack(
2626 unsigned long data
2627)
2628{
2629 struct vnt_private *priv = (struct vnt_private *)data;
2630 unsigned long flags;
2631
2632 pr_debug("TimerSQ3CallBack...\n");
2633
2634 spin_lock_irqsave(&priv->lock, flags);
2635
2636 pr_debug("3.[%08x][%08x], %d\n",
2637 (int)priv->ulRatio_State0, (int)priv->ulRatio_State1,
2638 (int)priv->uDiversityCnt);
2639
2640 s_vChangeAntenna(priv);
2641 priv->byAntennaState = 0;
2642 BBvClearAntDivSQ3Value(priv);
2643
2644 priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ);
2645 priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ);
2646 add_timer(&priv->TimerSQ3Tmax3);
2647 add_timer(&priv->TimerSQ3Tmax2);
2648
2649 spin_unlock_irqrestore(&priv->lock, flags);
2650}
2651
2652/*+
2653 *
2654 * Description:
2655 * Timer for SQ3 antenna diversity
2656 *
2657 * Parameters:
2658 * In:
2659 * pvSysSpec1
2660 * hDeviceContext - Pointer to the adapter
2661 * pvSysSpec2
2662 * pvSysSpec3
2663 * Out:
2664 * none
2665 *
2666 * Return Value: none
2667 *
2668 -*/
2669
2670void
2671TimerState1CallBack(
2672 unsigned long data
2673)
2674{
2675 struct vnt_private *priv = (struct vnt_private *)data;
2676 unsigned long flags;
2677
2678 pr_debug("TimerState1CallBack...\n");
2679
2680 spin_lock_irqsave(&priv->lock, flags);
2681
2682 if (priv->uDiversityCnt < priv->ulDiversityMValue/100) {
2683 s_vChangeAntenna(priv);
2684 priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ);
2685 priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ);
2686 add_timer(&priv->TimerSQ3Tmax3);
2687 add_timer(&priv->TimerSQ3Tmax2);
2688 } else {
2689 priv->ulRatio_State1 = s_ulGetRatio(priv);
2690 pr_debug("SQ3_State1, rate0 = %08x,rate1 = %08x\n",
2691 (int)priv->ulRatio_State0,
2692 (int)priv->ulRatio_State1);
2693
2694 if (priv->ulRatio_State1 < priv->ulRatio_State0) {
2695 pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
2696 (int)priv->ulRatio_State0,
2697 (int)priv->ulRatio_State1,
2698 (int)priv->wAntDiversityMaxRate,
2699 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate],
2700 (int)priv->uDiversityCnt);
2701
2702 s_vChangeAntenna(priv);
2703
2704 priv->TimerSQ3Tmax3.expires = RUN_AT(priv->byTMax3 * HZ);
2705 priv->TimerSQ3Tmax2.expires = RUN_AT(priv->byTMax2 * HZ);
2706 add_timer(&priv->TimerSQ3Tmax3);
2707 add_timer(&priv->TimerSQ3Tmax2);
2708 }
2709 }
2710 priv->byAntennaState = 0;
2711 BBvClearAntDivSQ3Value(priv);
2712
2713 spin_unlock_irqrestore(&priv->lock, flags);
2714}
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
index d9f6d63e4ab7..43a4fb1f3570 100644
--- a/drivers/staging/vt6655/baseband.h
+++ b/drivers/staging/vt6655/baseband.h
@@ -93,21 +93,4 @@ void BBvSetRxAntennaMode(struct vnt_private *, unsigned char byAntennaMode);
93void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID); 93void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID);
94void BBvExitDeepSleep(struct vnt_private *, unsigned char byLocalID); 94void BBvExitDeepSleep(struct vnt_private *, unsigned char byLocalID);
95 95
96/* timer for antenna diversity */
97
98void
99TimerSQ3CallBack(
100 unsigned long
101);
102
103void
104TimerState1CallBack(
105 unsigned long
106);
107
108void BBvAntennaDiversity(struct vnt_private *,
109 unsigned char byRxRate, unsigned char bySQ3);
110void
111BBvClearAntDivSQ3Value(struct vnt_private *);
112
113#endif /* __BASEBAND_H__ */ 96#endif /* __BASEBAND_H__ */
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index a0796405c308..1cdcf49b2445 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -68,8 +68,8 @@
68 68
69/*--------------------- Static Variables --------------------------*/ 69/*--------------------- Static Variables --------------------------*/
70 70
71static const unsigned short cwRXBCNTSFOff[MAX_RATE] = 71static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
72{17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3}; 72 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
73 73
74/*--------------------- Static Functions --------------------------*/ 74/*--------------------- Static Functions --------------------------*/
75 75
@@ -670,6 +670,9 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type)
670{ 670{
671 union vnt_phy_field_swap phy; 671 union vnt_phy_field_swap phy;
672 unsigned char byTxRate, byRsvTime; /* For OFDM */ 672 unsigned char byTxRate, byRsvTime; /* For OFDM */
673 unsigned long flags;
674
675 spin_lock_irqsave(&pDevice->lock, flags);
673 676
674 /* Set to Page1 */ 677 /* Set to Page1 */
675 MACvSelectPage1(pDevice->PortOffset); 678 MACvSelectPage1(pDevice->PortOffset);
@@ -767,6 +770,8 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type)
767 VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); 770 VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime));
768 /* Set to Page0 */ 771 /* Set to Page0 */
769 MACvSelectPage0(pDevice->PortOffset); 772 MACvSelectPage0(pDevice->PortOffset);
773
774 spin_unlock_irqrestore(&pDevice->lock, flags);
770} 775}
771 776
772void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) 777void CARDvUpdateBasicTopRate(struct vnt_private *pDevice)
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
index 70f870541f92..3c17725d5910 100644
--- a/drivers/staging/vt6655/channel.c
+++ b/drivers/staging/vt6655/channel.c
@@ -174,12 +174,12 @@ void vnt_init_bands(struct vnt_private *priv)
174 * Return Value: true if succeeded; false if failed. 174 * Return Value: true if succeeded; false if failed.
175 * 175 *
176 */ 176 */
177bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) 177bool set_channel(void *pDeviceHandler, struct ieee80211_channel *ch)
178{ 178{
179 struct vnt_private *pDevice = pDeviceHandler; 179 struct vnt_private *pDevice = pDeviceHandler;
180 bool bResult = true; 180 bool bResult = true;
181 181
182 if (pDevice->byCurrentCh == uConnectionChannel) 182 if (pDevice->byCurrentCh == ch->hw_value)
183 return bResult; 183 return bResult;
184 184
185 /* Set VGA to max sensitivity */ 185 /* Set VGA to max sensitivity */
@@ -197,19 +197,23 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
197 197
198 if (pDevice->byRFType == RF_AIROHA7230) 198 if (pDevice->byRFType == RF_AIROHA7230)
199 RFbAL7230SelectChannelPostProcess(pDevice, pDevice->byCurrentCh, 199 RFbAL7230SelectChannelPostProcess(pDevice, pDevice->byCurrentCh,
200 (unsigned char)uConnectionChannel); 200 ch->hw_value);
201 201
202 pDevice->byCurrentCh = (unsigned char)uConnectionChannel; 202 pDevice->byCurrentCh = ch->hw_value;
203 bResult &= RFbSelectChannel(pDevice, pDevice->byRFType, 203 bResult &= RFbSelectChannel(pDevice, pDevice->byRFType,
204 (unsigned char)uConnectionChannel); 204 ch->hw_value);
205 205
206 /* Init Synthesizer Table */ 206 /* Init Synthesizer Table */
207 if (pDevice->bEnablePSMode) 207 if (pDevice->bEnablePSMode)
208 RFvWriteWakeProgSyn(pDevice, pDevice->byRFType, uConnectionChannel); 208 RFvWriteWakeProgSyn(pDevice, pDevice->byRFType, ch->hw_value);
209 209
210 BBvSoftwareReset(pDevice); 210 BBvSoftwareReset(pDevice);
211 211
212 if (pDevice->byLocalID > REV_ID_VT3253_B1) { 212 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
213 unsigned long flags;
214
215 spin_lock_irqsave(&pDevice->lock, flags);
216
213 /* set HW default power register */ 217 /* set HW default power register */
214 MACvSelectPage1(pDevice->PortOffset); 218 MACvSelectPage1(pDevice->PortOffset);
215 RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); 219 RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
@@ -217,6 +221,8 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
217 RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh); 221 RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
218 VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr); 222 VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr);
219 MACvSelectPage0(pDevice->PortOffset); 223 MACvSelectPage0(pDevice->PortOffset);
224
225 spin_unlock_irqrestore(&pDevice->lock, flags);
220 } 226 }
221 227
222 if (pDevice->byBBType == BB_TYPE_11B) 228 if (pDevice->byBBType == BB_TYPE_11B)
diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h
index 4f4264e23462..e2be6fca5f26 100644
--- a/drivers/staging/vt6655/channel.h
+++ b/drivers/staging/vt6655/channel.h
@@ -27,6 +27,6 @@
27 27
28void vnt_init_bands(struct vnt_private *); 28void vnt_init_bands(struct vnt_private *);
29 29
30bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel); 30bool set_channel(void *pDeviceHandler, struct ieee80211_channel *);
31 31
32#endif /* _CHANNEL_H_ */ 32#endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
index 83efbfb57c79..440537e47121 100644
--- a/drivers/staging/vt6655/device.h
+++ b/drivers/staging/vt6655/device.h
@@ -367,7 +367,7 @@ struct vnt_private {
367 bool bIsBeaconBufReadySet; 367 bool bIsBeaconBufReadySet;
368 unsigned int cbBeaconBufReadySetCnt; 368 unsigned int cbBeaconBufReadySetCnt;
369 bool bFixRate; 369 bool bFixRate;
370 unsigned char byCurrentCh; 370 u16 byCurrentCh;
371 371
372 bool bAES; 372 bool bAES;
373 373
@@ -407,29 +407,6 @@ struct vnt_private {
407 unsigned char byBBCR88; 407 unsigned char byBBCR88;
408 unsigned char byBBCR09; 408 unsigned char byBBCR09;
409 409
410 bool bDiversityRegCtlON;
411 bool bDiversityEnable;
412 unsigned long ulDiversityNValue;
413 unsigned long ulDiversityMValue;
414 unsigned char byTMax;
415 unsigned char byTMax2;
416 unsigned char byTMax3;
417 unsigned long ulSQ3TH;
418
419 /* ANT diversity */
420 unsigned long uDiversityCnt;
421 unsigned char byAntennaState;
422 unsigned long ulRatio_State0;
423 unsigned long ulRatio_State1;
424
425 /* SQ3 functions for antenna diversity */
426 struct timer_list TimerSQ3Tmax1;
427 struct timer_list TimerSQ3Tmax2;
428 struct timer_list TimerSQ3Tmax3;
429
430 unsigned long uNumSQ3[MAX_RATE];
431 unsigned short wAntDiversityMaxRate;
432
433 unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */ 410 unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */
434 411
435 unsigned short wBeaconInterval; 412 unsigned short wBeaconInterval;
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index cd1a277d853b..4324282afe49 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -126,10 +126,6 @@ DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
126 126
127DEVICE_PARAM(BasebandType, "baseband type"); 127DEVICE_PARAM(BasebandType, "baseband type");
128 128
129#define DIVERSITY_ANT_DEF 0
130
131DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
132
133// 129//
134// Static vars definitions 130// Static vars definitions
135// 131//
@@ -152,7 +148,6 @@ static void vt6655_init_info(struct pci_dev *pcid,
152static void device_free_info(struct vnt_private *pDevice); 148static void device_free_info(struct vnt_private *pDevice);
153static bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid); 149static bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid);
154static void device_print_info(struct vnt_private *pDevice); 150static void device_print_info(struct vnt_private *pDevice);
155static void device_init_diversity_timer(struct vnt_private *pDevice);
156static irqreturn_t device_intr(int irq, void *dev_instance); 151static irqreturn_t device_intr(int irq, void *dev_instance);
157 152
158#ifdef CONFIG_PM 153#ifdef CONFIG_PM
@@ -216,7 +211,6 @@ static void device_get_options(struct vnt_private *pDevice)
216 pOpts->short_retry = SHORT_RETRY_DEF; 211 pOpts->short_retry = SHORT_RETRY_DEF;
217 pOpts->long_retry = LONG_RETRY_DEF; 212 pOpts->long_retry = LONG_RETRY_DEF;
218 pOpts->bbp_type = BBP_TYPE_DEF; 213 pOpts->bbp_type = BBP_TYPE_DEF;
219 pOpts->flags |= DEVICE_FLAGS_DiversityANT;
220} 214}
221 215
222static void 216static void
@@ -224,7 +218,6 @@ device_set_options(struct vnt_private *pDevice)
224{ 218{
225 pDevice->byShortRetryLimit = pDevice->sOpts.short_retry; 219 pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
226 pDevice->byLongRetryLimit = pDevice->sOpts.long_retry; 220 pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
227 pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
228 pDevice->byBBType = pDevice->sOpts.bbp_type; 221 pDevice->byBBType = pDevice->sOpts.bbp_type;
229 pDevice->byPacketType = pDevice->byBBType; 222 pDevice->byPacketType = pDevice->byBBType;
230 pDevice->byAutoFBCtrl = AUTO_FB_0; 223 pDevice->byAutoFBCtrl = AUTO_FB_0;
@@ -236,8 +229,6 @@ device_set_options(struct vnt_private *pDevice)
236 pr_debug(" byPreambleType= %d\n", (int)pDevice->byPreambleType); 229 pr_debug(" byPreambleType= %d\n", (int)pDevice->byPreambleType);
237 pr_debug(" byShortPreamble= %d\n", (int)pDevice->byShortPreamble); 230 pr_debug(" byShortPreamble= %d\n", (int)pDevice->byShortPreamble);
238 pr_debug(" byBBType= %d\n", (int)pDevice->byBBType); 231 pr_debug(" byBBType= %d\n", (int)pDevice->byBBType);
239 pr_debug(" pDevice->bDiversityRegCtlON= %d\n",
240 (int)pDevice->bDiversityRegCtlON);
241} 232}
242 233
243// 234//
@@ -249,7 +240,6 @@ static void device_init_registers(struct vnt_private *pDevice)
249 unsigned long flags; 240 unsigned long flags;
250 unsigned int ii; 241 unsigned int ii;
251 unsigned char byValue; 242 unsigned char byValue;
252 unsigned char byValue1;
253 unsigned char byCCKPwrdBm = 0; 243 unsigned char byCCKPwrdBm = 0;
254 unsigned char byOFDMPwrdBm = 0; 244 unsigned char byOFDMPwrdBm = 0;
255 245
@@ -301,13 +291,6 @@ static void device_init_registers(struct vnt_private *pDevice)
301 if (byValue == 0) 291 if (byValue == 0)
302 byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); 292 byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
303 293
304 pDevice->ulDiversityNValue = 100*260;
305 pDevice->ulDiversityMValue = 100*16;
306 pDevice->byTMax = 1;
307 pDevice->byTMax2 = 4;
308 pDevice->ulSQ3TH = 0;
309 pDevice->byTMax3 = 64;
310
311 if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { 294 if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
312 pDevice->byAntennaCount = 2; 295 pDevice->byAntennaCount = 2;
313 pDevice->byTxAntennaMode = ANT_B; 296 pDevice->byTxAntennaMode = ANT_B;
@@ -318,16 +301,7 @@ static void device_init_registers(struct vnt_private *pDevice)
318 pDevice->byRxAntennaMode = ANT_A; 301 pDevice->byRxAntennaMode = ANT_A;
319 else 302 else
320 pDevice->byRxAntennaMode = ANT_B; 303 pDevice->byRxAntennaMode = ANT_B;
321
322 byValue1 = SROMbyReadEmbedded(pDevice->PortOffset,
323 EEP_OFS_ANTENNA);
324
325 if ((byValue1 & 0x08) == 0)
326 pDevice->bDiversityEnable = false;
327 else
328 pDevice->bDiversityEnable = true;
329 } else { 304 } else {
330 pDevice->bDiversityEnable = false;
331 pDevice->byAntennaCount = 1; 305 pDevice->byAntennaCount = 1;
332 pDevice->dwTxAntennaSel = 0; 306 pDevice->dwTxAntennaSel = 0;
333 pDevice->dwRxAntennaSel = 0; 307 pDevice->dwRxAntennaSel = 0;
@@ -349,10 +323,9 @@ static void device_init_registers(struct vnt_private *pDevice)
349 } 323 }
350 } 324 }
351 325
352 pr_debug("bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n", 326 /* Set initial antenna mode */
353 pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, 327 BBvSetTxAntennaMode(pDevice, pDevice->byTxAntennaMode);
354 (int)pDevice->ulDiversityMValue, pDevice->byTMax, 328 BBvSetRxAntennaMode(pDevice, pDevice->byRxAntennaMode);
355 pDevice->byTMax2);
356 329
357 /* zonetype initial */ 330 /* zonetype initial */
358 pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; 331 pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
@@ -493,24 +466,6 @@ static void device_init_registers(struct vnt_private *pDevice)
493 MACvStart(pDevice->PortOffset); 466 MACvStart(pDevice->PortOffset);
494} 467}
495 468
496static void device_init_diversity_timer(struct vnt_private *pDevice)
497{
498 init_timer(&pDevice->TimerSQ3Tmax1);
499 pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
500 pDevice->TimerSQ3Tmax1.function = TimerSQ3CallBack;
501 pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
502
503 init_timer(&pDevice->TimerSQ3Tmax2);
504 pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
505 pDevice->TimerSQ3Tmax2.function = TimerSQ3CallBack;
506 pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
507
508 init_timer(&pDevice->TimerSQ3Tmax3);
509 pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
510 pDevice->TimerSQ3Tmax3.function = TimerState1CallBack;
511 pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
512}
513
514static void device_print_info(struct vnt_private *pDevice) 469static void device_print_info(struct vnt_private *pDevice)
515{ 470{
516 dev_info(&pDevice->pcid->dev, "%s\n", get_chip_name(pDevice->chip_id)); 471 dev_info(&pDevice->pcid->dev, "%s\n", get_chip_name(pDevice->chip_id));
@@ -1053,6 +1008,58 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc)
1053 pTDInfo->byFlags = 0; 1008 pTDInfo->byFlags = 0;
1054} 1009}
1055 1010
1011static void vnt_check_bb_vga(struct vnt_private *priv)
1012{
1013 long dbm;
1014 int i;
1015
1016 if (!priv->bUpdateBBVGA)
1017 return;
1018
1019 if (priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
1020 return;
1021
1022 if (!(priv->vif->bss_conf.assoc && priv->uCurrRSSI))
1023 return;
1024
1025 RFvRSSITodBm(priv, (u8)priv->uCurrRSSI, &dbm);
1026
1027 for (i = 0; i < BB_VGA_LEVEL; i++) {
1028 if (dbm < priv->ldBmThreshold[i]) {
1029 priv->byBBVGANew = priv->abyBBVGA[i];
1030 break;
1031 }
1032 }
1033
1034 if (priv->byBBVGANew == priv->byBBVGACurrent) {
1035 priv->uBBVGADiffCount = 1;
1036 return;
1037 }
1038
1039 priv->uBBVGADiffCount++;
1040
1041 if (priv->uBBVGADiffCount == 1) {
1042 /* first VGA diff gain */
1043 BBvSetVGAGainOffset(priv, priv->byBBVGANew);
1044
1045 dev_dbg(&priv->pcid->dev,
1046 "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
1047 (int)dbm, priv->byBBVGANew,
1048 priv->byBBVGACurrent,
1049 (int)priv->uBBVGADiffCount);
1050 }
1051
1052 if (priv->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
1053 dev_dbg(&priv->pcid->dev,
1054 "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
1055 (int)dbm, priv->byBBVGANew,
1056 priv->byBBVGACurrent,
1057 (int)priv->uBBVGADiffCount);
1058
1059 BBvSetVGAGainOffset(priv, priv->byBBVGANew);
1060 }
1061}
1062
1056static irqreturn_t device_intr(int irq, void *dev_instance) 1063static irqreturn_t device_intr(int irq, void *dev_instance)
1057{ 1064{
1058 struct vnt_private *pDevice = dev_instance; 1065 struct vnt_private *pDevice = dev_instance;
@@ -1060,7 +1067,6 @@ static irqreturn_t device_intr(int irq, void *dev_instance)
1060 unsigned long dwMIBCounter = 0; 1067 unsigned long dwMIBCounter = 0;
1061 unsigned char byOrgPageSel = 0; 1068 unsigned char byOrgPageSel = 0;
1062 int handled = 0; 1069 int handled = 0;
1063 int ii = 0;
1064 unsigned long flags; 1070 unsigned long flags;
1065 1071
1066 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); 1072 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
@@ -1090,7 +1096,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance)
1090 // Must do this after doing rx/tx, cause ISR bit is slow 1096 // Must do this after doing rx/tx, cause ISR bit is slow
1091 // than RD/TD write back 1097 // than RD/TD write back
1092 // update ISR counter 1098 // update ISR counter
1093 STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter); 1099 STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, dwMIBCounter);
1094 while (pDevice->dwIsr != 0) { 1100 while (pDevice->dwIsr != 0) {
1095 STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr); 1101 STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
1096 MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr); 1102 MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
@@ -1104,44 +1110,8 @@ static irqreturn_t device_intr(int irq, void *dev_instance)
1104 1110
1105 if (pDevice->dwIsr & ISR_TBTT) { 1111 if (pDevice->dwIsr & ISR_TBTT) {
1106 if (pDevice->vif && 1112 if (pDevice->vif &&
1107 pDevice->op_mode != NL80211_IFTYPE_ADHOC) { 1113 pDevice->op_mode != NL80211_IFTYPE_ADHOC)
1108 if (pDevice->bUpdateBBVGA && 1114 vnt_check_bb_vga(pDevice);
1109 !(pDevice->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
1110 pDevice->vif->bss_conf.assoc &&
1111 pDevice->uCurrRSSI) {
1112 long ldBm;
1113
1114 RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
1115 for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
1116 if (ldBm < pDevice->ldBmThreshold[ii]) {
1117 pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
1118 break;
1119 }
1120 }
1121 if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
1122 pDevice->uBBVGADiffCount++;
1123 if (pDevice->uBBVGADiffCount == 1) {
1124 // first VGA diff gain
1125 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
1126 pr_debug("First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
1127 (int)ldBm,
1128 pDevice->byBBVGANew,
1129 pDevice->byBBVGACurrent,
1130 (int)pDevice->uBBVGADiffCount);
1131 }
1132 if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
1133 pr_debug("RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
1134 (int)ldBm,
1135 pDevice->byBBVGANew,
1136 pDevice->byBBVGACurrent,
1137 (int)pDevice->uBBVGADiffCount);
1138 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
1139 }
1140 } else {
1141 pDevice->uBBVGADiffCount = 1;
1142 }
1143 }
1144 }
1145 1115
1146 pDevice->bBeaconSent = false; 1116 pDevice->bBeaconSent = false;
1147 if (pDevice->bEnablePSMode) 1117 if (pDevice->bEnablePSMode)
@@ -1262,12 +1232,15 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
1262 head_td->m_td1TD1.wReqCount = 1232 head_td->m_td1TD1.wReqCount =
1263 cpu_to_le16((u16)head_td->pTDInfo->dwReqCount); 1233 cpu_to_le16((u16)head_td->pTDInfo->dwReqCount);
1264 1234
1265 head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; 1235 head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma);
1236
1237 if (dma_idx == TYPE_AC0DMA) {
1238 head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
1266 1239
1267 if (dma_idx == TYPE_AC0DMA)
1268 MACvTransmitAC0(priv->PortOffset); 1240 MACvTransmitAC0(priv->PortOffset);
1269 else 1241 } else {
1270 MACvTransmit0(priv->PortOffset); 1242 MACvTransmit0(priv->PortOffset);
1243 }
1271 1244
1272 spin_unlock_irqrestore(&priv->lock, flags); 1245 spin_unlock_irqrestore(&priv->lock, flags);
1273 1246
@@ -1348,8 +1321,6 @@ static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1348 1321
1349 switch (vif->type) { 1322 switch (vif->type) {
1350 case NL80211_IFTYPE_STATION: 1323 case NL80211_IFTYPE_STATION:
1351 if (priv->bDiversityRegCtlON)
1352 device_init_diversity_timer(priv);
1353 break; 1324 break;
1354 case NL80211_IFTYPE_ADHOC: 1325 case NL80211_IFTYPE_ADHOC:
1355 MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST); 1326 MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST);
@@ -1379,11 +1350,6 @@ static void vnt_remove_interface(struct ieee80211_hw *hw,
1379 1350
1380 switch (vif->type) { 1351 switch (vif->type) {
1381 case NL80211_IFTYPE_STATION: 1352 case NL80211_IFTYPE_STATION:
1382 if (priv->bDiversityRegCtlON) {
1383 del_timer(&priv->TimerSQ3Tmax1);
1384 del_timer(&priv->TimerSQ3Tmax2);
1385 del_timer(&priv->TimerSQ3Tmax3);
1386 }
1387 break; 1353 break;
1388 case NL80211_IFTYPE_ADHOC: 1354 case NL80211_IFTYPE_ADHOC:
1389 MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); 1355 MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
@@ -1420,7 +1386,7 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed)
1420 1386
1421 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || 1387 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
1422 (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { 1388 (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
1423 set_channel(priv, conf->chandef.chan->hw_value); 1389 set_channel(priv, conf->chandef.chan);
1424 1390
1425 if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ) 1391 if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
1426 bb_type = BB_TYPE_11A; 1392 bb_type = BB_TYPE_11A;
@@ -1572,6 +1538,10 @@ static void vnt_configure(struct ieee80211_hw *hw,
1572 1538
1573 if (changed_flags & FIF_ALLMULTI) { 1539 if (changed_flags & FIF_ALLMULTI) {
1574 if (*total_flags & FIF_ALLMULTI) { 1540 if (*total_flags & FIF_ALLMULTI) {
1541 unsigned long flags;
1542
1543 spin_lock_irqsave(&priv->lock, flags);
1544
1575 if (priv->mc_list_count > 2) { 1545 if (priv->mc_list_count > 2) {
1576 MACvSelectPage1(priv->PortOffset); 1546 MACvSelectPage1(priv->PortOffset);
1577 1547
@@ -1593,6 +1563,8 @@ static void vnt_configure(struct ieee80211_hw *hw,
1593 MACvSelectPage0(priv->PortOffset); 1563 MACvSelectPage0(priv->PortOffset);
1594 } 1564 }
1595 1565
1566 spin_unlock_irqrestore(&priv->lock, flags);
1567
1596 rx_mode |= RCR_MULTICAST | RCR_BROADCAST; 1568 rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
1597 } else { 1569 } else {
1598 rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST); 1570 rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
@@ -1676,7 +1648,7 @@ static const struct ieee80211_ops vnt_mac_ops = {
1676 .reset_tsf = vnt_reset_tsf, 1648 .reset_tsf = vnt_reset_tsf,
1677}; 1649};
1678 1650
1679int vnt_init(struct vnt_private *priv) 1651static int vnt_init(struct vnt_private *priv)
1680{ 1652{
1681 SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr); 1653 SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr);
1682 1654
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
index 977683cb7391..3c5b87ffdcac 100644
--- a/drivers/staging/vt6655/dpc.c
+++ b/drivers/staging/vt6655/dpc.c
@@ -91,6 +91,8 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
91 new_rsr = skb_data + bytes_received - 3; 91 new_rsr = skb_data + bytes_received - 3;
92 rssi = skb_data + bytes_received - 2; 92 rssi = skb_data + bytes_received - 2;
93 rsr = skb_data + bytes_received - 1; 93 rsr = skb_data + bytes_received - 1;
94 if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
95 return false;
94 96
95 RFvRSSITodBm(priv, *rssi, &rx_dbm); 97 RFvRSSITodBm(priv, *rssi, &rx_dbm);
96 98
@@ -106,6 +108,9 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
106 rx_status.flag = 0; 108 rx_status.flag = 0;
107 rx_status.freq = hw->conf.chandef.chan->center_freq; 109 rx_status.freq = hw->conf.chandef.chan->center_freq;
108 110
111 if (!(*rsr & RSR_CRCOK))
112 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
113
109 hdr = (struct ieee80211_hdr *)(skb->data); 114 hdr = (struct ieee80211_hdr *)(skb->data);
110 fc = hdr->frame_control; 115 fc = hdr->frame_control;
111 116
@@ -113,13 +118,11 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
113 118
114 if (ieee80211_has_protected(fc)) { 119 if (ieee80211_has_protected(fc)) {
115 if (priv->byLocalID > REV_ID_VT3253_A1) 120 if (priv->byLocalID > REV_ID_VT3253_A1)
116 rx_status.flag = RX_FLAG_DECRYPTED; 121 rx_status.flag |= RX_FLAG_DECRYPTED;
117 }
118 122
119 if (priv->vif && priv->bDiversityEnable) { 123 /* Drop packet */
120 if (ieee80211_is_data(fc) && 124 if (!(*new_rsr & NEWRSR_DECRYPTOK))
121 (frame_size > 50) && priv->vif->bss_conf.assoc) 125 return false;
122 BBvAntennaDiversity(priv, priv->rx_rate, 0);
123 } 126 }
124 127
125 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 128 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
index 8f0d652fea7c..3653a2bd1e36 100644
--- a/drivers/staging/vt6655/mac.c
+++ b/drivers/staging/vt6655/mac.c
@@ -30,7 +30,6 @@
30 * MACbIsRegBitsOff - Test if All test Bits Off 30 * MACbIsRegBitsOff - Test if All test Bits Off
31 * MACbIsIntDisable - Test if MAC interrupt disable 31 * MACbIsIntDisable - Test if MAC interrupt disable
32 * MACvSetShortRetryLimit - Set 802.11 Short Retry limit 32 * MACvSetShortRetryLimit - Set 802.11 Short Retry limit
33 * MACvGetShortRetryLimit - Get 802.11 Short Retry limit
34 * MACvSetLongRetryLimit - Set 802.11 Long Retry limit 33 * MACvSetLongRetryLimit - Set 802.11 Long Retry limit
35 * MACvSetLoopbackMode - Set MAC Loopback Mode 34 * MACvSetLoopbackMode - Set MAC Loopback Mode
36 * MACvSaveContext - Save Context of MAC Registers 35 * MACvSaveContext - Save Context of MAC Registers
@@ -146,24 +145,6 @@ void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit)
146 VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit); 145 VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
147} 146}
148 147
149/*
150 * Description:
151 * Get 802.11 Short Retry Limit
152 *
153 * Parameters:
154 * In:
155 * dwIoBase - Base Address for MAC
156 * Out:
157 * pbyRetryLimit - Retry Limit Get
158 *
159 * Return Value: none
160 *
161 */
162void MACvGetShortRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit)
163{
164 // get SRT
165 VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
166}
167 148
168/* 149/*
169 * Description: 150 * Description:
@@ -356,7 +337,7 @@ bool MACbSafeSoftwareReset(void __iomem *dwIoBase)
356 337
357/* 338/*
358 * Description: 339 * Description:
359 * Trun Off MAC Rx 340 * Turn Off MAC Rx
360 * 341 *
361 * Parameters: 342 * Parameters:
362 * In: 343 * In:
@@ -417,7 +398,7 @@ bool MACbSafeRxOff(void __iomem *dwIoBase)
417 398
418/* 399/*
419 * Description: 400 * Description:
420 * Trun Off MAC Tx 401 * Turn Off MAC Tx
421 * 402 *
422 * Parameters: 403 * Parameters:
423 * In: 404 * In:
@@ -808,7 +789,7 @@ bool MACbPSWakeup(void __iomem *dwIoBase)
808 789
809 // Check if SyncFlushOK 790 // Check if SyncFlushOK
810 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { 791 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
811 VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue); 792 VNSvInPortB(dwIoBase + MAC_REG_PSCTL, &byOrgValue);
812 if (byOrgValue & PSCTL_WAKEDONE) 793 if (byOrgValue & PSCTL_WAKEDONE)
813 break; 794 break;
814 } 795 }
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
index e1e7e10435f6..8e0200a78b19 100644
--- a/drivers/staging/vt6655/mac.h
+++ b/drivers/staging/vt6655/mac.h
@@ -38,13 +38,11 @@
38#include "upc.h" 38#include "upc.h"
39 39
40/*--------------------- Export Definitions -------------------------*/ 40/*--------------------- Export Definitions -------------------------*/
41// 41/* Registers in the MAC */
42// Registers in the MAC
43//
44#define MAC_MAX_CONTEXT_SIZE_PAGE0 256 42#define MAC_MAX_CONTEXT_SIZE_PAGE0 256
45#define MAC_MAX_CONTEXT_SIZE_PAGE1 128 43#define MAC_MAX_CONTEXT_SIZE_PAGE1 128
46 44
47// Registers not related to 802.11b 45/* Registers not related to 802.11b */
48#define MAC_REG_BCFG0 0x00 46#define MAC_REG_BCFG0 0x00
49#define MAC_REG_BCFG1 0x01 47#define MAC_REG_BCFG1 0x01
50#define MAC_REG_FCR0 0x02 48#define MAC_REG_FCR0 0x02
@@ -69,15 +67,16 @@
69#define MAC_REG_TMCTL0 0x18 67#define MAC_REG_TMCTL0 0x18
70#define MAC_REG_TMCTL1 0x19 68#define MAC_REG_TMCTL1 0x19
71#define MAC_REG_TMDATA0 0x1C 69#define MAC_REG_TMDATA0 0x1C
72// MAC Parameter related 70
73#define MAC_REG_LRT 0x20 // 71/* MAC Parameter related */
74#define MAC_REG_SRT 0x21 // 72#define MAC_REG_LRT 0x20
75#define MAC_REG_SIFS 0x22 // 73#define MAC_REG_SRT 0x21
76#define MAC_REG_DIFS 0x23 // 74#define MAC_REG_SIFS 0x22
77#define MAC_REG_EIFS 0x24 // 75#define MAC_REG_DIFS 0x23
78#define MAC_REG_SLOT 0x25 // 76#define MAC_REG_EIFS 0x24
79#define MAC_REG_BI 0x26 // 77#define MAC_REG_SLOT 0x25
80#define MAC_REG_CWMAXMIN0 0x28 // 78#define MAC_REG_BI 0x26
79#define MAC_REG_CWMAXMIN0 0x28
81#define MAC_REG_LINKOFFTOTM 0x2A 80#define MAC_REG_LINKOFFTOTM 0x2A
82#define MAC_REG_SWTMOT 0x2B 81#define MAC_REG_SWTMOT 0x2B
83#define MAC_REG_MIBCNTR 0x2C 82#define MAC_REG_MIBCNTR 0x2C
@@ -85,26 +84,29 @@
85#define MAC_REG_RTSFAILCNT 0x2D 84#define MAC_REG_RTSFAILCNT 0x2D
86#define MAC_REG_ACKFAILCNT 0x2E 85#define MAC_REG_ACKFAILCNT 0x2E
87#define MAC_REG_FCSERRCNT 0x2F 86#define MAC_REG_FCSERRCNT 0x2F
88// TSF Related 87
89#define MAC_REG_TSFCNTR 0x30 // 88/* TSF Related */
90#define MAC_REG_NEXTTBTT 0x38 // 89#define MAC_REG_TSFCNTR 0x30
91#define MAC_REG_TSFOFST 0x40 // 90#define MAC_REG_NEXTTBTT 0x38
92#define MAC_REG_TFTCTL 0x48 // 91#define MAC_REG_TSFOFST 0x40
93// WMAC Control/Status Related 92#define MAC_REG_TFTCTL 0x48
94#define MAC_REG_ENCFG 0x4C // 93
95#define MAC_REG_PAGE1SEL 0x4F // 94/* WMAC Control/Status Related */
96#define MAC_REG_CFG 0x50 // 95#define MAC_REG_ENCFG 0x4C
97#define MAC_REG_TEST 0x52 // 96#define MAC_REG_PAGE1SEL 0x4F
98#define MAC_REG_HOSTCR 0x54 // 97#define MAC_REG_CFG 0x50
99#define MAC_REG_MACCR 0x55 // 98#define MAC_REG_TEST 0x52
100#define MAC_REG_RCR 0x56 // 99#define MAC_REG_HOSTCR 0x54
101#define MAC_REG_TCR 0x57 // 100#define MAC_REG_MACCR 0x55
102#define MAC_REG_IMR 0x58 // 101#define MAC_REG_RCR 0x56
102#define MAC_REG_TCR 0x57
103#define MAC_REG_IMR 0x58
103#define MAC_REG_ISR 0x5C 104#define MAC_REG_ISR 0x5C
104// Power Saving Related 105
105#define MAC_REG_PSCFG 0x60 // 106/* Power Saving Related */
106#define MAC_REG_PSCTL 0x61 // 107#define MAC_REG_PSCFG 0x60
107#define MAC_REG_PSPWRSIG 0x62 // 108#define MAC_REG_PSCTL 0x61
109#define MAC_REG_PSPWRSIG 0x62
108#define MAC_REG_BBCR13 0x63 110#define MAC_REG_BBCR13 0x63
109#define MAC_REG_AIDATIM 0x64 111#define MAC_REG_AIDATIM 0x64
110#define MAC_REG_PWBT 0x66 112#define MAC_REG_PWBT 0x66
@@ -112,41 +114,45 @@
112#define MAC_REG_CALTMR 0x69 114#define MAC_REG_CALTMR 0x69
113#define MAC_REG_SYNSPACCNT 0x6A 115#define MAC_REG_SYNSPACCNT 0x6A
114#define MAC_REG_WAKSYNOPT 0x6B 116#define MAC_REG_WAKSYNOPT 0x6B
115// Baseband/IF Control Group 117
116#define MAC_REG_BBREGCTL 0x6C // 118/* Baseband/IF Control Group */
119#define MAC_REG_BBREGCTL 0x6C
117#define MAC_REG_CHANNEL 0x6D 120#define MAC_REG_CHANNEL 0x6D
118#define MAC_REG_BBREGADR 0x6E 121#define MAC_REG_BBREGADR 0x6E
119#define MAC_REG_BBREGDATA 0x6F 122#define MAC_REG_BBREGDATA 0x6F
120#define MAC_REG_IFREGCTL 0x70 // 123#define MAC_REG_IFREGCTL 0x70
121#define MAC_REG_IFDATA 0x71 // 124#define MAC_REG_IFDATA 0x71
122#define MAC_REG_ITRTMSET 0x74 // 125#define MAC_REG_ITRTMSET 0x74
123#define MAC_REG_PAPEDELAY 0x77 126#define MAC_REG_PAPEDELAY 0x77
124#define MAC_REG_SOFTPWRCTL 0x78 // 127#define MAC_REG_SOFTPWRCTL 0x78
125#define MAC_REG_GPIOCTL0 0x7A // 128#define MAC_REG_GPIOCTL0 0x7A
126#define MAC_REG_GPIOCTL1 0x7B // 129#define MAC_REG_GPIOCTL1 0x7B
127 130
128// MAC DMA Related Group 131/* MAC DMA Related Group */
129#define MAC_REG_TXDMACTL0 0x7C // 132#define MAC_REG_TXDMACTL0 0x7C
130#define MAC_REG_TXDMAPTR0 0x80 // 133#define MAC_REG_TXDMAPTR0 0x80
131#define MAC_REG_AC0DMACTL 0x84 // 134#define MAC_REG_AC0DMACTL 0x84
132#define MAC_REG_AC0DMAPTR 0x88 // 135#define MAC_REG_AC0DMAPTR 0x88
133#define MAC_REG_BCNDMACTL 0x8C // 136#define MAC_REG_BCNDMACTL 0x8C
134#define MAC_REG_BCNDMAPTR 0x90 // 137#define MAC_REG_BCNDMAPTR 0x90
135#define MAC_REG_RXDMACTL0 0x94 // 138#define MAC_REG_RXDMACTL0 0x94
136#define MAC_REG_RXDMAPTR0 0x98 // 139#define MAC_REG_RXDMAPTR0 0x98
137#define MAC_REG_RXDMACTL1 0x9C // 140#define MAC_REG_RXDMACTL1 0x9C
138#define MAC_REG_RXDMAPTR1 0xA0 // 141#define MAC_REG_RXDMAPTR1 0xA0
139#define MAC_REG_SYNCDMACTL 0xA4 // 142#define MAC_REG_SYNCDMACTL 0xA4
140#define MAC_REG_SYNCDMAPTR 0xA8 143#define MAC_REG_SYNCDMAPTR 0xA8
141#define MAC_REG_ATIMDMACTL 0xAC 144#define MAC_REG_ATIMDMACTL 0xAC
142#define MAC_REG_ATIMDMAPTR 0xB0 145#define MAC_REG_ATIMDMAPTR 0xB0
143// MiscFF PIO related 146
147/* MiscFF PIO related */
144#define MAC_REG_MISCFFNDEX 0xB4 148#define MAC_REG_MISCFFNDEX 0xB4
145#define MAC_REG_MISCFFCTL 0xB6 149#define MAC_REG_MISCFFCTL 0xB6
146#define MAC_REG_MISCFFDATA 0xB8 150#define MAC_REG_MISCFFDATA 0xB8
147// Extend SW Timer 151
152/* Extend SW Timer */
148#define MAC_REG_TMDATA1 0xBC 153#define MAC_REG_TMDATA1 0xBC
149// WOW Related Group 154
155/* WOW Related Group */
150#define MAC_REG_WAKEUPEN0 0xC0 156#define MAC_REG_WAKEUPEN0 0xC0
151#define MAC_REG_WAKEUPEN1 0xC1 157#define MAC_REG_WAKEUPEN1 0xC1
152#define MAC_REG_WAKEUPSR0 0xC2 158#define MAC_REG_WAKEUPSR0 0xC2
@@ -156,19 +162,21 @@
156#define MAC_REG_WAKE128_2 0xE4 162#define MAC_REG_WAKE128_2 0xE4
157#define MAC_REG_WAKE128_3 0xF4 163#define MAC_REG_WAKE128_3 0xF4
158 164
159/////////////// Page 1 /////////////////// 165/************** Page 1 ******************/
160#define MAC_REG_CRC_128_0 0x04 166#define MAC_REG_CRC_128_0 0x04
161#define MAC_REG_CRC_128_1 0x06 167#define MAC_REG_CRC_128_1 0x06
162#define MAC_REG_CRC_128_2 0x08 168#define MAC_REG_CRC_128_2 0x08
163#define MAC_REG_CRC_128_3 0x0A 169#define MAC_REG_CRC_128_3 0x0A
164// MAC Configuration Group 170
171/* MAC Configuration Group */
165#define MAC_REG_PAR0 0x0C 172#define MAC_REG_PAR0 0x0C
166#define MAC_REG_PAR4 0x10 173#define MAC_REG_PAR4 0x10
167#define MAC_REG_BSSID0 0x14 174#define MAC_REG_BSSID0 0x14
168#define MAC_REG_BSSID4 0x18 175#define MAC_REG_BSSID4 0x18
169#define MAC_REG_MAR0 0x1C 176#define MAC_REG_MAR0 0x1C
170#define MAC_REG_MAR4 0x20 177#define MAC_REG_MAR4 0x20
171// MAC RSPPKT INFO Group 178
179/* MAC RSPPKT INFO Group */
172#define MAC_REG_RSPINF_B_1 0x24 180#define MAC_REG_RSPINF_B_1 0x24
173#define MAC_REG_RSPINF_B_2 0x28 181#define MAC_REG_RSPINF_B_2 0x28
174#define MAC_REG_RSPINF_B_5 0x2C 182#define MAC_REG_RSPINF_B_5 0x2C
@@ -183,7 +191,7 @@
183#define MAC_REG_RSPINF_A_54 0x42 191#define MAC_REG_RSPINF_A_54 0x42
184#define MAC_REG_RSPINF_A_72 0x44 192#define MAC_REG_RSPINF_A_72 0x44
185 193
186// 802.11h relative 194/* 802.11h relative */
187#define MAC_REG_QUIETINIT 0x60 195#define MAC_REG_QUIETINIT 0x60
188#define MAC_REG_QUIETGAP 0x62 196#define MAC_REG_QUIETGAP 0x62
189#define MAC_REG_QUIETDUR 0x64 197#define MAC_REG_QUIETDUR 0x64
@@ -195,9 +203,7 @@
195#define MAC_REG_PWRCCK 0x73 203#define MAC_REG_PWRCCK 0x73
196#define MAC_REG_PWROFDM 0x7C 204#define MAC_REG_PWROFDM 0x7C
197 205
198// 206/* Bits in the BCFG0 register */
199// Bits in the BCFG0 register
200//
201#define BCFG0_PERROFF 0x40 207#define BCFG0_PERROFF 0x40
202#define BCFG0_MRDMDIS 0x20 208#define BCFG0_MRDMDIS 0x20
203#define BCFG0_MRDLDIS 0x10 209#define BCFG0_MRDLDIS 0x10
@@ -205,9 +211,7 @@
205#define BCFG0_VSERREN 0x02 211#define BCFG0_VSERREN 0x02
206#define BCFG0_LATMEN 0x01 212#define BCFG0_LATMEN 0x01
207 213
208// 214/* Bits in the BCFG1 register */
209// Bits in the BCFG1 register
210//
211#define BCFG1_CFUNOPT 0x80 215#define BCFG1_CFUNOPT 0x80
212#define BCFG1_CREQOPT 0x40 216#define BCFG1_CREQOPT 0x40
213#define BCFG1_DMA8 0x10 217#define BCFG1_DMA8 0x10
@@ -216,25 +220,23 @@
216#define BCFG1_MIOEN 0x02 220#define BCFG1_MIOEN 0x02
217#define BCFG1_CISDLYEN 0x01 221#define BCFG1_CISDLYEN 0x01
218 222
219// Bits in RAMBIST registers 223/* Bits in RAMBIST registers */
220#define BISTCMD_TSTPAT5 0x00 // 224#define BISTCMD_TSTPAT5 0x00
221#define BISTCMD_TSTPATA 0x80 // 225#define BISTCMD_TSTPATA 0x80
222#define BISTCMD_TSTERR 0x20 // 226#define BISTCMD_TSTERR 0x20
223#define BISTCMD_TSTPATF 0x18 // 227#define BISTCMD_TSTPATF 0x18
224#define BISTCMD_TSTPAT0 0x10 // 228#define BISTCMD_TSTPAT0 0x10
225#define BISTCMD_TSTMODE 0x04 // 229#define BISTCMD_TSTMODE 0x04
226#define BISTCMD_TSTITTX 0x03 // 230#define BISTCMD_TSTITTX 0x03
227#define BISTCMD_TSTATRX 0x02 // 231#define BISTCMD_TSTATRX 0x02
228#define BISTCMD_TSTATTX 0x01 // 232#define BISTCMD_TSTATTX 0x01
229#define BISTCMD_TSTRX 0x00 // 233#define BISTCMD_TSTRX 0x00
230#define BISTSR0_BISTGO 0x01 // 234#define BISTSR0_BISTGO 0x01
231#define BISTSR1_TSTSR 0x01 // 235#define BISTSR1_TSTSR 0x01
232#define BISTSR2_CMDPRTEN 0x02 // 236#define BISTSR2_CMDPRTEN 0x02
233#define BISTSR2_RAMTSTEN 0x01 // 237#define BISTSR2_RAMTSTEN 0x01
234 238
235// 239/* Bits in the I2MCFG EEPROM register */
236// Bits in the I2MCFG EEPROM register
237//
238#define I2MCFG_BOUNDCTL 0x80 240#define I2MCFG_BOUNDCTL 0x80
239#define I2MCFG_WAITCTL 0x20 241#define I2MCFG_WAITCTL 0x20
240#define I2MCFG_SCLOECTL 0x10 242#define I2MCFG_SCLOECTL 0x10
@@ -243,50 +245,38 @@
243#define I2MCFG_I2MLDSEQ 0x02 245#define I2MCFG_I2MLDSEQ 0x02
244#define I2MCFG_I2CMFAST 0x01 246#define I2MCFG_I2CMFAST 0x01
245 247
246// 248/* Bits in the I2MCSR EEPROM register */
247// Bits in the I2MCSR EEPROM register
248//
249#define I2MCSR_EEMW 0x80 249#define I2MCSR_EEMW 0x80
250#define I2MCSR_EEMR 0x40 250#define I2MCSR_EEMR 0x40
251#define I2MCSR_AUTOLD 0x08 251#define I2MCSR_AUTOLD 0x08
252#define I2MCSR_NACK 0x02 252#define I2MCSR_NACK 0x02
253#define I2MCSR_DONE 0x01 253#define I2MCSR_DONE 0x01
254 254
255// 255/* Bits in the PMC1 register */
256// Bits in the PMC1 register
257//
258#define SPS_RST 0x80 256#define SPS_RST 0x80
259#define PCISTIKY 0x40 257#define PCISTIKY 0x40
260#define PME_OVR 0x02 258#define PME_OVR 0x02
261 259
262// 260/* Bits in the STICKYHW register */
263// Bits in the STICKYHW register
264//
265#define STICKHW_DS1_SHADOW 0x02 261#define STICKHW_DS1_SHADOW 0x02
266#define STICKHW_DS0_SHADOW 0x01 262#define STICKHW_DS0_SHADOW 0x01
267 263
268// 264/* Bits in the TMCTL register */
269// Bits in the TMCTL register
270//
271#define TMCTL_TSUSP 0x04 265#define TMCTL_TSUSP 0x04
272#define TMCTL_TMD 0x02 266#define TMCTL_TMD 0x02
273#define TMCTL_TE 0x01 267#define TMCTL_TE 0x01
274 268
275// 269/* Bits in the TFTCTL register */
276// Bits in the TFTCTL register 270#define TFTCTL_HWUTSF 0x80
277//
278#define TFTCTL_HWUTSF 0x80 //
279#define TFTCTL_TBTTSYNC 0x40 271#define TFTCTL_TBTTSYNC 0x40
280#define TFTCTL_HWUTSFEN 0x20 272#define TFTCTL_HWUTSFEN 0x20
281#define TFTCTL_TSFCNTRRD 0x10 // 273#define TFTCTL_TSFCNTRRD 0x10
282#define TFTCTL_TBTTSYNCEN 0x08 // 274#define TFTCTL_TBTTSYNCEN 0x08
283#define TFTCTL_TSFSYNCEN 0x04 // 275#define TFTCTL_TSFSYNCEN 0x04
284#define TFTCTL_TSFCNTRST 0x02 // 276#define TFTCTL_TSFCNTRST 0x02
285#define TFTCTL_TSFCNTREN 0x01 // 277#define TFTCTL_TSFCNTREN 0x01
286 278
287// 279/* Bits in the EnhanceCFG register */
288// Bits in the EnhanceCFG register
289//
290#define EnCFG_BarkerPream 0x00020000 280#define EnCFG_BarkerPream 0x00020000
291#define EnCFG_NXTBTTCFPSTR 0x00010000 281#define EnCFG_NXTBTTCFPSTR 0x00010000
292#define EnCFG_BcnSusClr 0x00000200 282#define EnCFG_BcnSusClr 0x00000200
@@ -300,14 +290,10 @@
300#define EnCFG_BBType_b 0x00000001 290#define EnCFG_BBType_b 0x00000001
301#define EnCFG_BBType_a 0x00000000 291#define EnCFG_BBType_a 0x00000000
302 292
303// 293/* Bits in the Page1Sel register */
304// Bits in the Page1Sel register
305//
306#define PAGE1_SEL 0x01 294#define PAGE1_SEL 0x01
307 295
308// 296/* Bits in the CFG register */
309// Bits in the CFG register
310//
311#define CFG_TKIPOPT 0x80 297#define CFG_TKIPOPT 0x80
312#define CFG_RXDMAOPT 0x40 298#define CFG_RXDMAOPT 0x40
313#define CFG_TMOT_SW 0x20 299#define CFG_TMOT_SW 0x20
@@ -318,242 +304,196 @@
318#define CFG_NOTXTIMEOUT 0x02 304#define CFG_NOTXTIMEOUT 0x02
319#define CFG_NOBUFOPT 0x01 305#define CFG_NOBUFOPT 0x01
320 306
321// 307/* Bits in the TEST register */
322// Bits in the TEST register 308#define TEST_LBEXT 0x80
323// 309#define TEST_LBINT 0x40
324#define TEST_LBEXT 0x80 // 310#define TEST_LBNONE 0x00
325#define TEST_LBINT 0x40 // 311#define TEST_SOFTINT 0x20
326#define TEST_LBNONE 0x00 // 312#define TEST_CONTTX 0x10
327#define TEST_SOFTINT 0x20 // 313#define TEST_TXPE 0x08
328#define TEST_CONTTX 0x10 // 314#define TEST_NAVDIS 0x04
329#define TEST_TXPE 0x08 // 315#define TEST_NOCTS 0x02
330#define TEST_NAVDIS 0x04 // 316#define TEST_NOACK 0x01
331#define TEST_NOCTS 0x02 // 317
332#define TEST_NOACK 0x01 // 318/* Bits in the HOSTCR register */
333 319#define HOSTCR_TXONST 0x80
334// 320#define HOSTCR_RXONST 0x40
335// Bits in the HOSTCR register 321#define HOSTCR_ADHOC 0x20 /* Network Type 1 = Ad-hoc */
336// 322#define HOSTCR_AP 0x10 /* Port Type 1 = AP */
337#define HOSTCR_TXONST 0x80 // 323#define HOSTCR_TXON 0x08 /* 0000 1000 */
338#define HOSTCR_RXONST 0x40 // 324#define HOSTCR_RXON 0x04 /* 0000 0100 */
339#define HOSTCR_ADHOC 0x20 // Network Type 1 = Ad-hoc 325#define HOSTCR_MACEN 0x02 /* 0000 0010 */
340#define HOSTCR_AP 0x10 // Port Type 1 = AP 326#define HOSTCR_SOFTRST 0x01 /* 0000 0001 */
341#define HOSTCR_TXON 0x08 //0000 1000 327
342#define HOSTCR_RXON 0x04 //0000 0100 328/* Bits in the MACCR register */
343#define HOSTCR_MACEN 0x02 //0000 0010 329#define MACCR_SYNCFLUSHOK 0x04
344#define HOSTCR_SOFTRST 0x01 //0000 0001 330#define MACCR_SYNCFLUSH 0x02
345 331#define MACCR_CLRNAV 0x01
346// 332
347// Bits in the MACCR register 333/* Bits in the MAC_REG_GPIOCTL0 register */
348// 334#define LED_ACTSET 0x01
349#define MACCR_SYNCFLUSHOK 0x04 // 335#define LED_RFOFF 0x02
350#define MACCR_SYNCFLUSH 0x02 // 336#define LED_NOCONNECT 0x04
351#define MACCR_CLRNAV 0x01 // 337
352 338/* Bits in the RCR register */
353// Bits in the MAC_REG_GPIOCTL0 register
354//
355#define LED_ACTSET 0x01 //
356#define LED_RFOFF 0x02 //
357#define LED_NOCONNECT 0x04 //
358//
359// Bits in the RCR register
360//
361#define RCR_SSID 0x80 339#define RCR_SSID 0x80
362#define RCR_RXALLTYPE 0x40 // 340#define RCR_RXALLTYPE 0x40
363#define RCR_UNICAST 0x20 // 341#define RCR_UNICAST 0x20
364#define RCR_BROADCAST 0x10 // 342#define RCR_BROADCAST 0x10
365#define RCR_MULTICAST 0x08 // 343#define RCR_MULTICAST 0x08
366#define RCR_WPAERR 0x04 // 344#define RCR_WPAERR 0x04
367#define RCR_ERRCRC 0x02 // 345#define RCR_ERRCRC 0x02
368#define RCR_BSSID 0x01 // 346#define RCR_BSSID 0x01
369 347
370// 348/* Bits in the TCR register */
371// Bits in the TCR register 349#define TCR_SYNCDCFOPT 0x02
372// 350#define TCR_AUTOBCNTX 0x01 /* Beacon automatically transmit enable */
373#define TCR_SYNCDCFOPT 0x02 // 351
374#define TCR_AUTOBCNTX 0x01 // Beacon automatically transmit enable 352/* Bits in the IMR register */
375 353#define IMR_MEASURESTART 0x80000000
376// 354#define IMR_QUIETSTART 0x20000000
377// Bits in the IMR register 355#define IMR_RADARDETECT 0x10000000
378// 356#define IMR_MEASUREEND 0x08000000
379#define IMR_MEASURESTART 0x80000000 // 357#define IMR_SOFTTIMER1 0x00200000
380#define IMR_QUIETSTART 0x20000000 // 358#define IMR_RXDMA1 0x00001000 /* 0000 0000 0001 0000 0000 0000 */
381#define IMR_RADARDETECT 0x10000000 // 359#define IMR_RXNOBUF 0x00000800
382#define IMR_MEASUREEND 0x08000000 // 360#define IMR_MIBNEARFULL 0x00000400
383#define IMR_SOFTTIMER1 0x00200000 // 361#define IMR_SOFTINT 0x00000200
384#define IMR_RXDMA1 0x00001000 //0000 0000 0001 0000 0000 0000 362#define IMR_FETALERR 0x00000100
385#define IMR_RXNOBUF 0x00000800 // 363#define IMR_WATCHDOG 0x00000080
386#define IMR_MIBNEARFULL 0x00000400 // 364#define IMR_SOFTTIMER 0x00000040
387#define IMR_SOFTINT 0x00000200 // 365#define IMR_GPIO 0x00000020
388#define IMR_FETALERR 0x00000100 // 366#define IMR_TBTT 0x00000010
389#define IMR_WATCHDOG 0x00000080 // 367#define IMR_RXDMA0 0x00000008
390#define IMR_SOFTTIMER 0x00000040 // 368#define IMR_BNTX 0x00000004
391#define IMR_GPIO 0x00000020 // 369#define IMR_AC0DMA 0x00000002
392#define IMR_TBTT 0x00000010 // 370#define IMR_TXDMA0 0x00000001
393#define IMR_RXDMA0 0x00000008 // 371
394#define IMR_BNTX 0x00000004 // 372/* Bits in the ISR register */
395#define IMR_AC0DMA 0x00000002 // 373#define ISR_MEASURESTART 0x80000000
396#define IMR_TXDMA0 0x00000001 // 374#define ISR_QUIETSTART 0x20000000
397 375#define ISR_RADARDETECT 0x10000000
398// 376#define ISR_MEASUREEND 0x08000000
399// Bits in the ISR register 377#define ISR_SOFTTIMER1 0x00200000
400// 378#define ISR_RXDMA1 0x00001000 /* 0000 0000 0001 0000 0000 0000 */
401 379#define ISR_RXNOBUF 0x00000800 /* 0000 0000 0000 1000 0000 0000 */
402#define ISR_MEASURESTART 0x80000000 // 380#define ISR_MIBNEARFULL 0x00000400 /* 0000 0000 0000 0100 0000 0000 */
403#define ISR_QUIETSTART 0x20000000 // 381#define ISR_SOFTINT 0x00000200
404#define ISR_RADARDETECT 0x10000000 // 382#define ISR_FETALERR 0x00000100
405#define ISR_MEASUREEND 0x08000000 // 383#define ISR_WATCHDOG 0x00000080
406#define ISR_SOFTTIMER1 0x00200000 // 384#define ISR_SOFTTIMER 0x00000040
407#define ISR_RXDMA1 0x00001000 //0000 0000 0001 0000 0000 0000 385#define ISR_GPIO 0x00000020
408#define ISR_RXNOBUF 0x00000800 //0000 0000 0000 1000 0000 0000 386#define ISR_TBTT 0x00000010
409#define ISR_MIBNEARFULL 0x00000400 //0000 0000 0000 0100 0000 0000 387#define ISR_RXDMA0 0x00000008
410#define ISR_SOFTINT 0x00000200 // 388#define ISR_BNTX 0x00000004
411#define ISR_FETALERR 0x00000100 // 389#define ISR_AC0DMA 0x00000002
412#define ISR_WATCHDOG 0x00000080 // 390#define ISR_TXDMA0 0x00000001
413#define ISR_SOFTTIMER 0x00000040 // 391
414#define ISR_GPIO 0x00000020 // 392/* Bits in the PSCFG register */
415#define ISR_TBTT 0x00000010 // 393#define PSCFG_PHILIPMD 0x40
416#define ISR_RXDMA0 0x00000008 // 394#define PSCFG_WAKECALEN 0x20
417#define ISR_BNTX 0x00000004 // 395#define PSCFG_WAKETMREN 0x10
418#define ISR_AC0DMA 0x00000002 // 396#define PSCFG_BBPSPROG 0x08
419#define ISR_TXDMA0 0x00000001 // 397#define PSCFG_WAKESYN 0x04
420 398#define PSCFG_SLEEPSYN 0x02
421// 399#define PSCFG_AUTOSLEEP 0x01
422// Bits in the PSCFG register 400
423// 401/* Bits in the PSCTL register */
424#define PSCFG_PHILIPMD 0x40 // 402#define PSCTL_WAKEDONE 0x20
425#define PSCFG_WAKECALEN 0x20 // 403#define PSCTL_PS 0x10
426#define PSCFG_WAKETMREN 0x10 // 404#define PSCTL_GO2DOZE 0x08
427#define PSCFG_BBPSPROG 0x08 // 405#define PSCTL_LNBCN 0x04
428#define PSCFG_WAKESYN 0x04 // 406#define PSCTL_ALBCN 0x02
429#define PSCFG_SLEEPSYN 0x02 // 407#define PSCTL_PSEN 0x01
430#define PSCFG_AUTOSLEEP 0x01 // 408
431 409/* Bits in the PSPWSIG register */
432// 410#define PSSIG_WPE3 0x80
433// Bits in the PSCTL register 411#define PSSIG_WPE2 0x40
434// 412#define PSSIG_WPE1 0x20
435#define PSCTL_WAKEDONE 0x20 // 413#define PSSIG_WRADIOPE 0x10
436#define PSCTL_PS 0x10 // 414#define PSSIG_SPE3 0x08
437#define PSCTL_GO2DOZE 0x08 // 415#define PSSIG_SPE2 0x04
438#define PSCTL_LNBCN 0x04 // 416#define PSSIG_SPE1 0x02
439#define PSCTL_ALBCN 0x02 // 417#define PSSIG_SRADIOPE 0x01
440#define PSCTL_PSEN 0x01 // 418
441 419/* Bits in the BBREGCTL register */
442// 420#define BBREGCTL_DONE 0x04
443// Bits in the PSPWSIG register 421#define BBREGCTL_REGR 0x02
444// 422#define BBREGCTL_REGW 0x01
445#define PSSIG_WPE3 0x80 // 423
446#define PSSIG_WPE2 0x40 // 424/* Bits in the IFREGCTL register */
447#define PSSIG_WPE1 0x20 // 425#define IFREGCTL_DONE 0x04
448#define PSSIG_WRADIOPE 0x10 // 426#define IFREGCTL_IFRF 0x02
449#define PSSIG_SPE3 0x08 // 427#define IFREGCTL_REGW 0x01
450#define PSSIG_SPE2 0x04 // 428
451#define PSSIG_SPE1 0x02 // 429/* Bits in the SOFTPWRCTL register */
452#define PSSIG_SRADIOPE 0x01 // 430#define SOFTPWRCTL_RFLEOPT 0x0800
453 431#define SOFTPWRCTL_TXPEINV 0x0200
454// 432#define SOFTPWRCTL_SWPECTI 0x0100
455// Bits in the BBREGCTL register 433#define SOFTPWRCTL_SWPAPE 0x0020
456// 434#define SOFTPWRCTL_SWCALEN 0x0010
457#define BBREGCTL_DONE 0x04 // 435#define SOFTPWRCTL_SWRADIO_PE 0x0008
458#define BBREGCTL_REGR 0x02 // 436#define SOFTPWRCTL_SWPE2 0x0004
459#define BBREGCTL_REGW 0x01 // 437#define SOFTPWRCTL_SWPE1 0x0002
460 438#define SOFTPWRCTL_SWPE3 0x0001
461// 439
462// Bits in the IFREGCTL register 440/* Bits in the GPIOCTL1 register */
463// 441#define GPIO1_DATA1 0x20
464#define IFREGCTL_DONE 0x04 // 442#define GPIO1_MD1 0x10
465#define IFREGCTL_IFRF 0x02 // 443#define GPIO1_DATA0 0x02
466#define IFREGCTL_REGW 0x01 // 444#define GPIO1_MD0 0x01
467 445
468// 446/* Bits in the DMACTL register */
469// Bits in the SOFTPWRCTL register 447#define DMACTL_CLRRUN 0x00080000
470// 448#define DMACTL_RUN 0x00000008
471#define SOFTPWRCTL_RFLEOPT 0x0800 // 449#define DMACTL_WAKE 0x00000004
472#define SOFTPWRCTL_TXPEINV 0x0200 // 450#define DMACTL_DEAD 0x00000002
473#define SOFTPWRCTL_SWPECTI 0x0100 // 451#define DMACTL_ACTIVE 0x00000001
474#define SOFTPWRCTL_SWPAPE 0x0020 // 452
475#define SOFTPWRCTL_SWCALEN 0x0010 // 453/* Bits in the RXDMACTL0 register */
476#define SOFTPWRCTL_SWRADIO_PE 0x0008 // 454#define RX_PERPKT 0x00000100
477#define SOFTPWRCTL_SWPE2 0x0004 // 455#define RX_PERPKTCLR 0x01000000
478#define SOFTPWRCTL_SWPE1 0x0002 // 456
479#define SOFTPWRCTL_SWPE3 0x0001 // 457/* Bits in the BCNDMACTL register */
480 458#define BEACON_READY 0x01
481// 459
482// Bits in the GPIOCTL1 register 460/* Bits in the MISCFFCTL register */
483// 461#define MISCFFCTL_WRITE 0x0001
484#define GPIO1_DATA1 0x20 // 462
485#define GPIO1_MD1 0x10 // 463/* Bits in WAKEUPEN0 */
486#define GPIO1_DATA0 0x02 //
487#define GPIO1_MD0 0x01 //
488
489//
490// Bits in the DMACTL register
491//
492#define DMACTL_CLRRUN 0x00080000 //
493#define DMACTL_RUN 0x00000008 //
494#define DMACTL_WAKE 0x00000004 //
495#define DMACTL_DEAD 0x00000002 //
496#define DMACTL_ACTIVE 0x00000001 //
497//
498// Bits in the RXDMACTL0 register
499//
500#define RX_PERPKT 0x00000100 //
501#define RX_PERPKTCLR 0x01000000 //
502//
503// Bits in the BCNDMACTL register
504//
505#define BEACON_READY 0x01 //
506//
507// Bits in the MISCFFCTL register
508//
509#define MISCFFCTL_WRITE 0x0001 //
510
511//
512// Bits in WAKEUPEN0
513//
514#define WAKEUPEN0_DIRPKT 0x10 464#define WAKEUPEN0_DIRPKT 0x10
515#define WAKEUPEN0_LINKOFF 0x08 465#define WAKEUPEN0_LINKOFF 0x08
516#define WAKEUPEN0_ATIMEN 0x04 466#define WAKEUPEN0_ATIMEN 0x04
517#define WAKEUPEN0_TIMEN 0x02 467#define WAKEUPEN0_TIMEN 0x02
518#define WAKEUPEN0_MAGICEN 0x01 468#define WAKEUPEN0_MAGICEN 0x01
519 469
520// 470/* Bits in WAKEUPEN1 */
521// Bits in WAKEUPEN1
522//
523#define WAKEUPEN1_128_3 0x08 471#define WAKEUPEN1_128_3 0x08
524#define WAKEUPEN1_128_2 0x04 472#define WAKEUPEN1_128_2 0x04
525#define WAKEUPEN1_128_1 0x02 473#define WAKEUPEN1_128_1 0x02
526#define WAKEUPEN1_128_0 0x01 474#define WAKEUPEN1_128_0 0x01
527 475
528// 476/* Bits in WAKEUPSR0 */
529// Bits in WAKEUPSR0
530//
531#define WAKEUPSR0_DIRPKT 0x10 477#define WAKEUPSR0_DIRPKT 0x10
532#define WAKEUPSR0_LINKOFF 0x08 478#define WAKEUPSR0_LINKOFF 0x08
533#define WAKEUPSR0_ATIMEN 0x04 479#define WAKEUPSR0_ATIMEN 0x04
534#define WAKEUPSR0_TIMEN 0x02 480#define WAKEUPSR0_TIMEN 0x02
535#define WAKEUPSR0_MAGICEN 0x01 481#define WAKEUPSR0_MAGICEN 0x01
536 482
537// 483/* Bits in WAKEUPSR1 */
538// Bits in WAKEUPSR1
539//
540#define WAKEUPSR1_128_3 0x08 484#define WAKEUPSR1_128_3 0x08
541#define WAKEUPSR1_128_2 0x04 485#define WAKEUPSR1_128_2 0x04
542#define WAKEUPSR1_128_1 0x02 486#define WAKEUPSR1_128_1 0x02
543#define WAKEUPSR1_128_0 0x01 487#define WAKEUPSR1_128_0 0x01
544 488
545// 489/* Bits in the MAC_REG_GPIOCTL register */
546// Bits in the MAC_REG_GPIOCTL register 490#define GPIO0_MD 0x01
547// 491#define GPIO0_DATA 0x02
548#define GPIO0_MD 0x01 // 492#define GPIO0_INTMD 0x04
549#define GPIO0_DATA 0x02 // 493#define GPIO1_MD 0x10
550#define GPIO0_INTMD 0x04 // 494#define GPIO1_DATA 0x20
551#define GPIO1_MD 0x10 // 495
552#define GPIO1_DATA 0x20 // 496/* Bits in the MSRCTL register */
553
554//
555// Bits in the MSRCTL register
556//
557#define MSRCTL_FINISH 0x80 497#define MSRCTL_FINISH 0x80
558#define MSRCTL_READY 0x40 498#define MSRCTL_READY 0x40
559#define MSRCTL_RADARDETECT 0x20 499#define MSRCTL_RADARDETECT 0x20
@@ -562,28 +502,27 @@
562#define MSRCTL_QUIETRPT 0x04 502#define MSRCTL_QUIETRPT 0x04
563#define MSRCTL_QUIETINT 0x02 503#define MSRCTL_QUIETINT 0x02
564#define MSRCTL_QUIETEN 0x01 504#define MSRCTL_QUIETEN 0x01
565// 505
566// Bits in the MSRCTL1 register 506/* Bits in the MSRCTL1 register */
567//
568#define MSRCTL1_TXPWR 0x08 507#define MSRCTL1_TXPWR 0x08
569#define MSRCTL1_CSAPAREN 0x04 508#define MSRCTL1_CSAPAREN 0x04
570#define MSRCTL1_TXPAUSE 0x01 509#define MSRCTL1_TXPAUSE 0x01
571 510
572// Loopback mode 511/* Loopback mode */
573#define MAC_LB_EXT 0x02 // 512#define MAC_LB_EXT 0x02
574#define MAC_LB_INTERNAL 0x01 // 513#define MAC_LB_INTERNAL 0x01
575#define MAC_LB_NONE 0x00 // 514#define MAC_LB_NONE 0x00
576 515
577#define Default_BI 0x200 516#define Default_BI 0x200
578 517
579// MiscFIFO Offset 518/* MiscFIFO Offset */
580#define MISCFIFO_KEYETRY0 32 519#define MISCFIFO_KEYETRY0 32
581#define MISCFIFO_KEYENTRYSIZE 22 520#define MISCFIFO_KEYENTRYSIZE 22
582#define MISCFIFO_SYNINFO_IDX 10 521#define MISCFIFO_SYNINFO_IDX 10
583#define MISCFIFO_SYNDATA_IDX 11 522#define MISCFIFO_SYNDATA_IDX 11
584#define MISCFIFO_SYNDATASIZE 21 523#define MISCFIFO_SYNDATASIZE 21
585 524
586// enabled mask value of irq 525/* enabled mask value of irq */
587#define IMR_MASK_VALUE (IMR_SOFTTIMER1 | \ 526#define IMR_MASK_VALUE (IMR_SOFTTIMER1 | \
588 IMR_RXDMA1 | \ 527 IMR_RXDMA1 | \
589 IMR_RXNOBUF | \ 528 IMR_RXNOBUF | \
@@ -599,15 +538,13 @@
599 IMR_AC0DMA | \ 538 IMR_AC0DMA | \
600 IMR_TXDMA0) 539 IMR_TXDMA0)
601 540
602// max time out delay time 541/* max time out delay time */
603#define W_MAX_TIMEOUT 0xFFF0U // 542#define W_MAX_TIMEOUT 0xFFF0U
604 543
605// wait time within loop 544/* wait time within loop */
606#define CB_DELAY_LOOP_WAIT 10 // 10ms 545#define CB_DELAY_LOOP_WAIT 10 /* 10ms */
607 546
608// 547/* revision id */
609// revision id
610//
611#define REV_ID_VT3253_A0 0x00 548#define REV_ID_VT3253_A0 0x00
612#define REV_ID_VT3253_A1 0x01 549#define REV_ID_VT3253_A1 0x01
613#define REV_ID_VT3253_B0 0x08 550#define REV_ID_VT3253_B0 0x08
@@ -691,12 +628,12 @@ do { \
691 VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR, \ 628 VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR, \
692 (unsigned long *)pdwCurrDescAddr) 629 (unsigned long *)pdwCurrDescAddr)
693 630
694// set the chip with current BCN tx descriptor address 631/* set the chip with current BCN tx descriptor address */
695#define MACvSetCurrBCNTxDescAddr(dwIoBase, dwCurrDescAddr) \ 632#define MACvSetCurrBCNTxDescAddr(dwIoBase, dwCurrDescAddr) \
696 VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, \ 633 VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, \
697 dwCurrDescAddr) 634 dwCurrDescAddr)
698 635
699// set the chip with current BCN length 636/* set the chip with current BCN length */
700#define MACvSetCurrBCNLength(dwIoBase, wCurrBCNLength) \ 637#define MACvSetCurrBCNLength(dwIoBase, wCurrBCNLength) \
701 VNSvOutPortW(dwIoBase + MAC_REG_BCNDMACTL+2, \ 638 VNSvOutPortW(dwIoBase + MAC_REG_BCNDMACTL+2, \
702 wCurrBCNLength) 639 wCurrBCNLength)
@@ -888,7 +825,7 @@ do { \
888 VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1) 825 VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1)
889 826
890#define MACvReadMIBCounter(dwIoBase, pdwCounter) \ 827#define MACvReadMIBCounter(dwIoBase, pdwCounter) \
891 VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR , pdwCounter) 828 VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR, pdwCounter)
892 829
893#define MACvPwrEvntDisable(dwIoBase) \ 830#define MACvPwrEvntDisable(dwIoBase) \
894 VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPEN0, 0x0000) 831 VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPEN0, 0x0000)
@@ -896,7 +833,7 @@ do { \
896#define MACvEnableProtectMD(dwIoBase) \ 833#define MACvEnableProtectMD(dwIoBase) \
897do { \ 834do { \
898 unsigned long dwOrgValue; \ 835 unsigned long dwOrgValue; \
899 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ 836 VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue); \
900 dwOrgValue = dwOrgValue | EnCFG_ProtectMd; \ 837 dwOrgValue = dwOrgValue | EnCFG_ProtectMd; \
901 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ 838 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \
902} while (0) 839} while (0)
@@ -904,7 +841,7 @@ do { \
904#define MACvDisableProtectMD(dwIoBase) \ 841#define MACvDisableProtectMD(dwIoBase) \
905do { \ 842do { \
906 unsigned long dwOrgValue; \ 843 unsigned long dwOrgValue; \
907 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ 844 VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue); \
908 dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd; \ 845 dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd; \
909 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ 846 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \
910} while (0) 847} while (0)
@@ -912,7 +849,7 @@ do { \
912#define MACvEnableBarkerPreambleMd(dwIoBase) \ 849#define MACvEnableBarkerPreambleMd(dwIoBase) \
913do { \ 850do { \
914 unsigned long dwOrgValue; \ 851 unsigned long dwOrgValue; \
915 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ 852 VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue); \
916 dwOrgValue = dwOrgValue | EnCFG_BarkerPream; \ 853 dwOrgValue = dwOrgValue | EnCFG_BarkerPream; \
917 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ 854 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \
918} while (0) 855} while (0)
@@ -920,7 +857,7 @@ do { \
920#define MACvDisableBarkerPreambleMd(dwIoBase) \ 857#define MACvDisableBarkerPreambleMd(dwIoBase) \
921do { \ 858do { \
922 unsigned long dwOrgValue; \ 859 unsigned long dwOrgValue; \
923 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ 860 VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue); \
924 dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream; \ 861 dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream; \
925 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ 862 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \
926} while (0) 863} while (0)
@@ -928,7 +865,7 @@ do { \
928#define MACvSetBBType(dwIoBase, byTyp) \ 865#define MACvSetBBType(dwIoBase, byTyp) \
929do { \ 866do { \
930 unsigned long dwOrgValue; \ 867 unsigned long dwOrgValue; \
931 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ 868 VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue); \
932 dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK; \ 869 dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK; \
933 dwOrgValue = dwOrgValue | (unsigned long)byTyp; \ 870 dwOrgValue = dwOrgValue | (unsigned long)byTyp; \
934 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ 871 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \
@@ -953,15 +890,18 @@ do { \
953#define MACvSetRFLE_LatchBase(dwIoBase) \ 890#define MACvSetRFLE_LatchBase(dwIoBase) \
954 MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT) 891 MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT)
955 892
956bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits); 893bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs,
957bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits); 894 unsigned char byTestBits);
895bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs,
896 unsigned char byTestBits);
958 897
959bool MACbIsIntDisable(void __iomem *dwIoBase); 898bool MACbIsIntDisable(void __iomem *dwIoBase);
960 899
961void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit); 900void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit);
962 901
963void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit); 902void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit);
964void MACvGetLongRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit); 903void MACvGetLongRetryLimit(void __iomem *dwIoBase,
904 unsigned char *pbyRetryLimit);
965 905
966void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode); 906void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode);
967 907
@@ -975,22 +915,32 @@ bool MACbSafeTxOff(void __iomem *dwIoBase);
975bool MACbSafeStop(void __iomem *dwIoBase); 915bool MACbSafeStop(void __iomem *dwIoBase);
976bool MACbShutdown(void __iomem *dwIoBase); 916bool MACbShutdown(void __iomem *dwIoBase);
977void MACvInitialize(void __iomem *dwIoBase); 917void MACvInitialize(void __iomem *dwIoBase);
978void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 918void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase,
979void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 919 unsigned long dwCurrDescAddr);
980void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 920void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase,
981void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 921 unsigned long dwCurrDescAddr);
982void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 922void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase,
983void MACvSetCurrSyncDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 923 unsigned long dwCurrDescAddr);
984void MACvSetCurrATIMDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr); 924void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase,
925 unsigned long dwCurrDescAddr);
926void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase,
927 unsigned long dwCurrDescAddr);
928void MACvSetCurrSyncDescAddrEx(void __iomem *dwIoBase,
929 unsigned long dwCurrDescAddr);
930void MACvSetCurrATIMDescAddrEx(void __iomem *dwIoBase,
931 unsigned long dwCurrDescAddr);
985void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay); 932void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay);
986void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime); 933void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime);
987 934
988void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned long dwData); 935void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset,
936 unsigned long dwData);
989 937
990bool MACbPSWakeup(void __iomem *dwIoBase); 938bool MACbPSWakeup(void __iomem *dwIoBase);
991 939
992void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, 940void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl,
993 unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID); 941 unsigned int uEntryIdx, unsigned int uKeyIdx,
942 unsigned char *pbyAddr, u32 *pdwKey,
943 unsigned char byLocalID);
994void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx); 944void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx);
995 945
996#endif // __MAC_H__ 946#endif /* __MAC_H__ */
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
index e826f07e91c0..be3c4e949b6a 100644
--- a/drivers/staging/vt6655/power.c
+++ b/drivers/staging/vt6655/power.c
@@ -71,33 +71,33 @@ PSvEnablePowerSaving(
71 struct vnt_private *pDevice = hDeviceContext; 71 struct vnt_private *pDevice = hDeviceContext;
72 u16 wAID = pDevice->current_aid | BIT(14) | BIT(15); 72 u16 wAID = pDevice->current_aid | BIT(14) | BIT(15);
73 73
74 // set period of power up before TBTT 74 /* set period of power up before TBTT */
75 VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT); 75 VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT);
76 if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) { 76 if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) {
77 // set AID 77 /* set AID */
78 VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID); 78 VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID);
79 } else { 79 } else {
80 // set ATIM Window 80 /* set ATIM Window */
81#if 0 /* TODO atim window */ 81#if 0 /* TODO atim window */
82 MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); 82 MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
83#endif 83#endif
84 } 84 }
85 // Set AutoSleep 85 /* Set AutoSleep */
86 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); 86 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
87 // Set HWUTSF 87 /* Set HWUTSF */
88 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); 88 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
89 89
90 if (wListenInterval >= 2) { 90 if (wListenInterval >= 2) {
91 // clear always listen beacon 91 /* clear always listen beacon */
92 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 92 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
93 // first time set listen next beacon 93 /* first time set listen next beacon */
94 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); 94 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
95 } else { 95 } else {
96 // always listen beacon 96 /* always listen beacon */
97 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 97 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
98 } 98 }
99 99
100 // enable power saving hw function 100 /* enable power saving hw function */
101 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); 101 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
102 pDevice->bEnablePSMode = true; 102 pDevice->bEnablePSMode = true;
103 103
@@ -122,13 +122,13 @@ PSvDisablePowerSaving(
122{ 122{
123 struct vnt_private *pDevice = hDeviceContext; 123 struct vnt_private *pDevice = hDeviceContext;
124 124
125 // disable power saving hw function 125 /* disable power saving hw function */
126 MACbPSWakeup(pDevice->PortOffset); 126 MACbPSWakeup(pDevice->PortOffset);
127 //clear AutoSleep 127 /* clear AutoSleep */
128 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); 128 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
129 //clear HWUTSF 129 /* clear HWUTSF */
130 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); 130 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
131 // set always listen beacon 131 /* set always listen beacon */
132 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 132 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
133 133
134 pDevice->bEnablePSMode = false; 134 pDevice->bEnablePSMode = false;
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index 32ef99341e20..941b2adca95a 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -651,7 +651,8 @@ bool RFbInit(
651 * Return Value: true if succeeded; false if failed. 651 * Return Value: true if succeeded; false if failed.
652 * 652 *
653 */ 653 */
654bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, unsigned char byChannel) 654bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType,
655 u16 byChannel)
655{ 656{
656 bool bResult = true; 657 bool bResult = true;
657 658
@@ -687,7 +688,8 @@ bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, unsigned
687 * Return Value: None. 688 * Return Value: None.
688 * 689 *
689 */ 690 */
690bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType, unsigned int uChannel) 691bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType,
692 u16 uChannel)
691{ 693{
692 void __iomem *dwIoBase = priv->PortOffset; 694 void __iomem *dwIoBase = priv->PortOffset;
693 int ii; 695 int ii;
@@ -767,13 +769,12 @@ bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType, unsig
767bool RFbSetPower( 769bool RFbSetPower(
768 struct vnt_private *priv, 770 struct vnt_private *priv,
769 unsigned int uRATE, 771 unsigned int uRATE,
770 unsigned int uCH 772 u16 uCH
771) 773)
772{ 774{
773 bool bResult = true; 775 bool bResult = true;
774 unsigned char byPwr = 0; 776 unsigned char byPwr = 0;
775 unsigned char byDec = 0; 777 unsigned char byDec = 0;
776 unsigned char byPwrdBm = 0;
777 778
778 if (priv->dwDiagRefCount != 0) 779 if (priv->dwDiagRefCount != 0)
779 return true; 780 return true;
@@ -786,8 +787,10 @@ bool RFbSetPower(
786 case RATE_2M: 787 case RATE_2M:
787 case RATE_5M: 788 case RATE_5M:
788 case RATE_11M: 789 case RATE_11M:
790 if (uCH > CB_MAX_CHANNEL_24G)
791 return false;
792
789 byPwr = priv->abyCCKPwrTbl[uCH]; 793 byPwr = priv->abyCCKPwrTbl[uCH];
790 byPwrdBm = priv->abyCCKDefaultPwr[uCH];
791 break; 794 break;
792 case RATE_6M: 795 case RATE_6M:
793 case RATE_9M: 796 case RATE_9M:
@@ -801,15 +804,6 @@ bool RFbSetPower(
801 if (byDec >= priv->byMaxPwrLevel) 804 if (byDec >= priv->byMaxPwrLevel)
802 byDec = priv->byMaxPwrLevel-1; 805 byDec = priv->byMaxPwrLevel-1;
803 806
804 if (priv->byRFType == RF_UW2452) {
805 byPwrdBm = byDec - byPwr;
806 byPwrdBm /= 3;
807 } else {
808 byPwrdBm = byDec - byPwr;
809 byPwrdBm >>= 1;
810 }
811
812 byPwrdBm += priv->abyOFDMDefaultPwr[uCH];
813 byPwr = byDec; 807 byPwr = byDec;
814 break; 808 break;
815 case RATE_24M: 809 case RATE_24M:
@@ -817,7 +811,6 @@ bool RFbSetPower(
817 case RATE_48M: 811 case RATE_48M:
818 case RATE_54M: 812 case RATE_54M:
819 byPwr = priv->abyOFDMPwrTbl[uCH]; 813 byPwr = priv->abyOFDMPwrTbl[uCH];
820 byPwrdBm = priv->abyOFDMDefaultPwr[uCH];
821 break; 814 break;
822 } 815 }
823 816
@@ -937,8 +930,8 @@ RFvRSSITodBm(
937/* Post processing for the 11b/g and 11a. 930/* Post processing for the 11b/g and 11a.
938 * for save time on changing Reg2,3,5,7,10,12,15 */ 931 * for save time on changing Reg2,3,5,7,10,12,15 */
939bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv, 932bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv,
940 unsigned char byOldChannel, 933 u16 byOldChannel,
941 unsigned char byNewChannel) 934 u16 byNewChannel)
942{ 935{
943 bool bResult; 936 bool bResult;
944 937
diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h
index 8a6e2cfedaa5..2ea21e2b00f2 100644
--- a/drivers/staging/vt6655/rf.h
+++ b/drivers/staging/vt6655/rf.h
@@ -74,12 +74,12 @@
74/*--------------------- Export Functions --------------------------*/ 74/*--------------------- Export Functions --------------------------*/
75 75
76bool IFRFbWriteEmbedded(struct vnt_private *, unsigned long dwData); 76bool IFRFbWriteEmbedded(struct vnt_private *, unsigned long dwData);
77bool RFbSelectChannel(struct vnt_private *, unsigned char byRFType, unsigned char byChannel); 77bool RFbSelectChannel(struct vnt_private *, unsigned char byRFType, u16);
78bool RFbInit( 78bool RFbInit(
79 struct vnt_private * 79 struct vnt_private *
80); 80);
81bool RFvWriteWakeProgSyn(struct vnt_private *, unsigned char byRFType, unsigned int uChannel); 81bool RFvWriteWakeProgSyn(struct vnt_private *, unsigned char byRFType, u16);
82bool RFbSetPower(struct vnt_private *, unsigned int uRATE, unsigned int uCH); 82bool RFbSetPower(struct vnt_private *, unsigned int uRATE, u16);
83bool RFbRawSetPower( 83bool RFbRawSetPower(
84 struct vnt_private *, 84 struct vnt_private *,
85 unsigned char byPwr, 85 unsigned char byPwr,
@@ -94,7 +94,7 @@ RFvRSSITodBm(
94); 94);
95 95
96//{{ RobertYu: 20050104 96//{{ RobertYu: 20050104
97bool RFbAL7230SelectChannelPostProcess(struct vnt_private *, unsigned char byOldChannel, unsigned char byNewChannel); 97bool RFbAL7230SelectChannelPostProcess(struct vnt_private *, u16, u16);
98//}} RobertYu 98//}} RobertYu
99 99
100#endif // __RF_H__ 100#endif // __RF_H__
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index b5b0155961f2..07ce3fd88e70 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -205,7 +205,7 @@ s_uGetRTSCTSRsvTime(
205 unsigned short wCurrentRate 205 unsigned short wCurrentRate
206) 206)
207{ 207{
208 unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; 208 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
209 209
210 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0; 210 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
211 211
@@ -1207,7 +1207,6 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1207 ptdCurr->pTDInfo->dwReqCount = cbReqCount; 1207 ptdCurr->pTDInfo->dwReqCount = cbReqCount;
1208 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; 1208 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1209 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; 1209 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1210 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1211 1210
1212 return cbHeaderLength; 1211 return cbHeaderLength;
1213} 1212}
diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h
index c53703a772f5..cc63dc8d47f7 100644
--- a/drivers/staging/vt6655/upc.h
+++ b/drivers/staging/vt6655/upc.h
@@ -33,9 +33,9 @@
33 33
34/*--------------------- Export Definitions -------------------------*/ 34/*--------------------- Export Definitions -------------------------*/
35 35
36// 36
37// For memory mapped IO 37/* For memory mapped IO */
38// 38
39 39
40#define VNSvInPortB(dwIOAddress, pbyData) \ 40#define VNSvInPortB(dwIOAddress, pbyData) \
41do { \ 41do { \
@@ -86,4 +86,4 @@ do { \
86 86
87/*--------------------- Export Functions --------------------------*/ 87/*--------------------- Export Functions --------------------------*/
88 88
89#endif // __UPC_H__ 89#endif /* __UPC_H__ */
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index 9340f1508cff..67ff13f4f731 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -78,7 +78,7 @@ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
78 /* Set Channel[7] = 0 to tell H/W channel is changing now. */ 78 /* Set Channel[7] = 0 to tell H/W channel is changing now. */
79 vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0); 79 vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0);
80 80
81 vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE, 81 vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL,
82 connection_channel, 0, 0, NULL); 82 connection_channel, 0, 0, NULL);
83 83
84 vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, 84 vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 5a7ca527106e..f71d59fa3b21 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -160,7 +160,7 @@
160#define MESSAGE_TYPE_CLRKEYENTRY 0x9 160#define MESSAGE_TYPE_CLRKEYENTRY 0x9
161#define MESSAGE_TYPE_WRITE_MISCFF 0xa 161#define MESSAGE_TYPE_WRITE_MISCFF 0xa
162#define MESSAGE_TYPE_SET_ANTMD 0xb 162#define MESSAGE_TYPE_SET_ANTMD 0xb
163#define MESSAGE_TYPE_SELECT_CHANNLE 0xc 163#define MESSAGE_TYPE_SELECT_CHANNEL 0xc
164#define MESSAGE_TYPE_SET_TSFTBTT 0xd 164#define MESSAGE_TYPE_SET_TSFTBTT 0xd
165#define MESSAGE_TYPE_SET_SSTIFS 0xe 165#define MESSAGE_TYPE_SET_SSTIFS 0xe
166#define MESSAGE_TYPE_CHANGE_BBTYPE 0xf 166#define MESSAGE_TYPE_CHANGE_BBTYPE 0xf
@@ -307,8 +307,8 @@ struct vnt_private {
307 307
308 struct vnt_cmd_card_init init_command; 308 struct vnt_cmd_card_init init_command;
309 struct vnt_rsp_card_init init_response; 309 struct vnt_rsp_card_init init_response;
310 u8 current_net_addr[ETH_ALEN]; 310 u8 current_net_addr[ETH_ALEN] __aligned(2);
311 u8 permanent_net_addr[ETH_ALEN]; 311 u8 permanent_net_addr[ETH_ALEN] __aligned(2);
312 312
313 u8 exist_sw_net_addr; 313 u8 exist_sw_net_addr;
314 314
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
index fab195f8c3f5..95e0e83a487e 100644
--- a/drivers/staging/vt6656/dpc.h
+++ b/drivers/staging/vt6656/dpc.h
@@ -32,6 +32,6 @@
32#include "device.h" 32#include "device.h"
33 33
34int vnt_rx_data(struct vnt_private *, struct vnt_rcb *, 34int vnt_rx_data(struct vnt_private *, struct vnt_rcb *,
35 unsigned long bytes_recieved); 35 unsigned long bytes_received);
36 36
37#endif /* __RXTX_H__ */ 37#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index b95d5b1efcc7..71adc1f61838 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -34,6 +34,7 @@
34 */ 34 */
35#undef __NO_VERSION__ 35#undef __NO_VERSION__
36 36
37#include <linux/etherdevice.h>
37#include <linux/file.h> 38#include <linux/file.h>
38#include "device.h" 39#include "device.h"
39#include "card.h" 40#include "card.h"
@@ -319,7 +320,7 @@ static int vnt_init_registers(struct vnt_private *priv)
319 320
320 /* get permanent network address */ 321 /* get permanent network address */
321 memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6); 322 memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6);
322 memcpy(priv->current_net_addr, priv->permanent_net_addr, ETH_ALEN); 323 ether_addr_copy(priv->current_net_addr, priv->permanent_net_addr);
323 324
324 /* if exist SW network address, use it */ 325 /* if exist SW network address, use it */
325 dev_dbg(&priv->usb->dev, "Network address = %pM\n", 326 dev_dbg(&priv->usb->dev, "Network address = %pM\n",
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index ea5140ab2b41..33baf26de4b5 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -36,6 +36,7 @@
36 * 36 *
37 */ 37 */
38 38
39#include <linux/etherdevice.h>
39#include "device.h" 40#include "device.h"
40#include "rxtx.h" 41#include "rxtx.h"
41#include "card.h" 42#include "card.h"
@@ -55,7 +56,7 @@ static const u16 vnt_fb_opt0[2][5] = {
55 56
56static const u16 vnt_fb_opt1[2][5] = { 57static const u16 vnt_fb_opt1[2][5] = {
57 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */ 58 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
58 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */ 59 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
59}; 60};
60 61
61#define RTSDUR_BB 0 62#define RTSDUR_BB 0
@@ -392,8 +393,8 @@ static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context,
392 rts->frame_control = 393 rts->frame_control =
393 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); 394 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
394 395
395 memcpy(rts->ra, hdr->addr1, ETH_ALEN); 396 ether_addr_copy(rts->ra, hdr->addr1);
396 memcpy(rts->ta, hdr->addr2, ETH_ALEN); 397 ether_addr_copy(rts->ta, hdr->addr2);
397 398
398 return 0; 399 return 0;
399} 400}
@@ -517,65 +518,66 @@ static u16 vnt_rxtx_rts_a_fb_head(struct vnt_usb_send_context *tx_context,
517 return vnt_rxtx_datahead_a_fb(tx_context, &buf->data_head); 518 return vnt_rxtx_datahead_a_fb(tx_context, &buf->data_head);
518} 519}
519 520
520static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, 521static u16 vnt_fill_cts_fb_head(struct vnt_usb_send_context *tx_context,
521 union vnt_tx_data_head *head) 522 union vnt_tx_data_head *head)
522{ 523{
523 struct vnt_private *priv = tx_context->priv; 524 struct vnt_private *priv = tx_context->priv;
525 struct vnt_cts_fb *buf = &head->cts_g_fb;
524 u32 cts_frame_len = 14; 526 u32 cts_frame_len = 14;
525 u16 current_rate = tx_context->tx_rate; 527 u16 current_rate = tx_context->tx_rate;
526 528
527 if (!head) 529 /* Get SignalField,ServiceField,Length */
528 return 0; 530 vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate,
531 PK_TYPE_11B, &buf->b);
529 532
530 if (tx_context->fb_option) { 533 buf->duration_ba =
531 /* Auto Fall back */ 534 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
532 struct vnt_cts_fb *buf = &head->cts_g_fb; 535 tx_context->pkt_type,
533 /* Get SignalField,ServiceField,Length */ 536 current_rate);
534 vnt_get_phy_field(priv, cts_frame_len, 537 /* Get CTSDuration_ba_f0 */
535 priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); 538 buf->cts_duration_ba_f0 =
536 buf->duration_ba = 539 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F0,
537 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA, 540 tx_context->pkt_type,
538 tx_context->pkt_type, 541 priv->tx_rate_fb0);
539 current_rate); 542 /* Get CTSDuration_ba_f1 */
540 /* Get CTSDuration_ba_f0 */ 543 buf->cts_duration_ba_f1 =
541 buf->cts_duration_ba_f0 = 544 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F1,
542 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F0, 545 tx_context->pkt_type,
543 tx_context->pkt_type, 546 priv->tx_rate_fb1);
544 priv->tx_rate_fb0); 547 /* Get CTS Frame body */
545 /* Get CTSDuration_ba_f1 */ 548 buf->data.duration = buf->duration_ba;
546 buf->cts_duration_ba_f1 = 549 buf->data.frame_control =
547 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F1, 550 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
548 tx_context->pkt_type,
549 priv->tx_rate_fb1);
550 /* Get CTS Frame body */
551 buf->data.duration = buf->duration_ba;
552 buf->data.frame_control =
553 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
554 551
555 memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN); 552 ether_addr_copy(buf->data.ra, priv->current_net_addr);
556 553
557 return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head); 554 return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head);
558 } else { 555}
559 struct vnt_cts *buf = &head->cts_g; 556
560 /* Get SignalField,ServiceField,Length */ 557static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context,
561 vnt_get_phy_field(priv, cts_frame_len, 558 union vnt_tx_data_head *head)
562 priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); 559{
563 /* Get CTSDuration_ba */ 560 struct vnt_private *priv = tx_context->priv;
564 buf->duration_ba = 561 struct vnt_cts *buf = &head->cts_g;
565 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA, 562 u32 cts_frame_len = 14;
566 tx_context->pkt_type, 563 u16 current_rate = tx_context->tx_rate;
567 current_rate);
568 /*Get CTS Frame body*/
569 buf->data.duration = buf->duration_ba;
570 buf->data.frame_control =
571 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
572 564
573 memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN); 565 /* Get SignalField,ServiceField,Length */
566 vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate,
567 PK_TYPE_11B, &buf->b);
568 /* Get CTSDuration_ba */
569 buf->duration_ba =
570 vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
571 tx_context->pkt_type,
572 current_rate);
573 /*Get CTS Frame body*/
574 buf->data.duration = buf->duration_ba;
575 buf->data.frame_control =
576 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
574 577
575 return vnt_rxtx_datahead_g(tx_context, &buf->data_head); 578 ether_addr_copy(buf->data.ra, priv->current_net_addr);
576 }
577 579
578 return 0; 580 return vnt_rxtx_datahead_g(tx_context, &buf->data_head);
579} 581}
580 582
581static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context, 583static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context,
@@ -632,6 +634,9 @@ static u16 vnt_rxtx_cts(struct vnt_usb_send_context *tx_context,
632 head = &tx_head->tx_cts.tx.mic.head; 634 head = &tx_head->tx_cts.tx.mic.head;
633 635
634 /* Fill CTS */ 636 /* Fill CTS */
637 if (tx_context->fb_option)
638 return vnt_fill_cts_fb_head(tx_context, head);
639
635 return vnt_fill_cts_head(tx_context, head); 640 return vnt_fill_cts_head(tx_context, head);
636} 641}
637 642
@@ -739,7 +744,7 @@ static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context,
739 744
740 mic_hdr->id = 0x59; 745 mic_hdr->id = 0x59;
741 mic_hdr->payload_len = cpu_to_be16(payload_len); 746 mic_hdr->payload_len = cpu_to_be16(payload_len);
742 memcpy(mic_hdr->mic_addr2, hdr->addr2, ETH_ALEN); 747 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
743 748
744 ieee80211_get_key_tx_seq(tx_key, &seq); 749 ieee80211_get_key_tx_seq(tx_key, &seq);
745 750
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 20d146b61ba7..8f2091070491 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -879,7 +879,7 @@ typedef struct hfa384x_usb_error {
879/* Unions for packaging all the known packet types together */ 879/* Unions for packaging all the known packet types together */
880 880
881typedef union hfa384x_usbout { 881typedef union hfa384x_usbout {
882 u16 type; 882 __le16 type;
883 hfa384x_usb_txfrm_t txfrm; 883 hfa384x_usb_txfrm_t txfrm;
884 hfa384x_usb_cmdreq_t cmdreq; 884 hfa384x_usb_cmdreq_t cmdreq;
885 hfa384x_usb_wridreq_t wridreq; 885 hfa384x_usb_wridreq_t wridreq;
@@ -889,7 +889,7 @@ typedef union hfa384x_usbout {
889} __packed hfa384x_usbout_t; 889} __packed hfa384x_usbout_t;
890 890
891typedef union hfa384x_usbin { 891typedef union hfa384x_usbin {
892 u16 type; 892 __le16 type;
893 hfa384x_usb_rxfrm_t rxfrm; 893 hfa384x_usb_rxfrm_t rxfrm;
894 hfa384x_usb_txfrm_t txfrm; 894 hfa384x_usb_txfrm_t txfrm;
895 hfa384x_usb_infofrm_t infofrm; 895 hfa384x_usb_infofrm_t infofrm;
@@ -1268,7 +1268,7 @@ typedef struct hfa384x {
1268 hfa384x_downloadbuffer_t bufinfo; 1268 hfa384x_downloadbuffer_t bufinfo;
1269 u16 dltimeout; 1269 u16 dltimeout;
1270 1270
1271 int scanflag; /* to signal scan comlete */ 1271 int scanflag; /* to signal scan complete */
1272 int join_ap; /* are we joined to a specific ap */ 1272 int join_ap; /* are we joined to a specific ap */
1273 int join_retries; /* number of join retries till we fail */ 1273 int join_retries; /* number of join retries till we fail */
1274 hfa384x_JoinRequest_data_t joinreq; /* join request saved data */ 1274 hfa384x_JoinRequest_data_t joinreq; /* join request saved data */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 55d2f563e308..28cd1c4c02c8 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -382,7 +382,7 @@ done:
382* 382*
383* Arguments: 383* Arguments:
384* hw device struct 384* hw device struct
385* tx_urb URB of data for tranmission 385* tx_urb URB of data for transmission
386* memflags memory allocation flags 386* memflags memory allocation flags
387* 387*
388* Returns: 388* Returns:
@@ -2391,7 +2391,7 @@ int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
2391* 0 success 2391* 0 success
2392* >0 f/w reported error - f/w status code 2392* >0 f/w reported error - f/w status code
2393* <0 driver reported error 2393* <0 driver reported error
2394* -ETIMEDOUT timout waiting for the cmd regs to become 2394* -ETIMEDOUT timeout waiting for the cmd regs to become
2395* available, or waiting for the control reg 2395* available, or waiting for the control reg
2396* to indicate the Aux port is enabled. 2396* to indicate the Aux port is enabled.
2397* -ENODATA the buffer does NOT contain a valid PDA. 2397* -ENODATA the buffer does NOT contain a valid PDA.
@@ -3346,7 +3346,7 @@ retry:
3346 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) 3346 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
3347 run_queue = 1; 3347 run_queue = 1;
3348 } else { 3348 } else {
3349 const u16 intype = (usbin->type & ~cpu_to_le16(0x8000)); 3349 const __le16 intype = (usbin->type & ~cpu_to_le16(0x8000));
3350 3350
3351 /* 3351 /*
3352 * Check that our message is what we're expecting ... 3352 * Check that our message is what we're expecting ...
@@ -4123,12 +4123,11 @@ static int hfa384x_isgood_pdrcode(u16 pdrcode)
4123 pr_debug("Encountered unknown PDR#=0x%04x, assuming it's ok.\n", 4123 pr_debug("Encountered unknown PDR#=0x%04x, assuming it's ok.\n",
4124 pdrcode); 4124 pdrcode);
4125 return 1; 4125 return 1;
4126 } else {
4127 /* bad code */
4128 pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n",
4129 pdrcode);
4130 return 0;
4131 } 4126 }
4127 break;
4132 } 4128 }
4133 return 0; /* avoid compiler warnings */ 4129 /* bad code */
4130 pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n",
4131 pdrcode);
4132 return 0;
4134} 4133}
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 7eaaf9a63503..bd69e8cf200f 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -511,7 +511,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
511* protocol. 511* protocol.
512* 512*
513* Arguments: 513* Arguments:
514* proto protocl number (in host order) to search for. 514* proto protocol number (in host order) to search for.
515* 515*
516* Returns: 516* Returns:
517* 1 - if the table is empty or a match is found. 517* 1 - if the table is empty or a match is found.
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 7221379c9742..4b84b568f6ca 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -80,7 +80,7 @@ static void p80211req_mibset_mibget(wlandevice_t *wlandev,
80/*---------------------------------------------------------------- 80/*----------------------------------------------------------------
81* p80211req_dorequest 81* p80211req_dorequest
82* 82*
83* Handles an MLME reqest/confirm message. 83* Handles an MLME request/confirm message.
84* 84*
85* Arguments: 85* Arguments:
86* wlandev WLAN device struct 86* wlandev WLAN device struct
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index b62fdcba94e6..16f123959104 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -45,7 +45,7 @@
45* -------------------------------------------------------------------- 45* --------------------------------------------------------------------
46* 46*
47* This file contains the constants and data structures for interaction 47* This file contains the constants and data structures for interaction
48* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC). 48* with the hfa384x Wireless LAN (WLAN) Media Access Controller (MAC).
49* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset. 49* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset.
50* 50*
51* [Implementation and usage notes] 51* [Implementation and usage notes]
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index df577dfe7ffb..10ad24a89ddd 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -199,7 +199,7 @@ static int prism2sta_close(wlandevice_t *wlandev)
199/*---------------------------------------------------------------- 199/*----------------------------------------------------------------
200* prism2sta_reset 200* prism2sta_reset
201* 201*
202* Not currently implented. 202* Currently not implemented.
203* 203*
204* Arguments: 204* Arguments:
205* wlandev wlan device structure 205* wlandev wlan device structure
@@ -662,7 +662,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
662 "ident: ap f/w: id=0x%02x %d.%d.%d\n", 662 "ident: ap f/w: id=0x%02x %d.%d.%d\n",
663 hw->ident_sta_fw.id, hw->ident_sta_fw.major, 663 hw->ident_sta_fw.id, hw->ident_sta_fw.major,
664 hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); 664 hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
665 netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmeare loaded!\n"); 665 netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmware loaded!\n");
666 goto failed; 666 goto failed;
667 } 667 }
668 668
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 709d49e7f3c9..935c714f592a 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -930,7 +930,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
930 + var->hsync_len; 930 + var->hsync_len;
931 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin 931 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
932 + var->vsync_len; 932 + var->vsync_len;
933#if defined(__powerpc__) 933#if defined(__BIG_ENDIAN)
934 u8 cr_data; 934 u8 cr_data;
935#endif 935#endif
936 unsigned int drate = 0, hrate = 0; 936 unsigned int drate = 0, hrate = 0;
@@ -952,7 +952,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
952 } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n", 952 } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
953 var->pixclock, htotal, vtotal); 953 var->pixclock, htotal, vtotal);
954 954
955 if (var->pixclock && htotal && vtotal) { 955 if (var->pixclock) {
956 drate = 1000000000 / var->pixclock; 956 drate = 1000000000 / var->pixclock;
957 hrate = (drate * 1000) / htotal; 957 hrate = (drate * 1000) / htotal;
958 xgifb_info->refresh_rate = (unsigned int) (hrate * 2 958 xgifb_info->refresh_rate = (unsigned int) (hrate * 2
@@ -1044,7 +1044,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1044 xgifb_info->DstColor = 0x0000; 1044 xgifb_info->DstColor = 0x0000;
1045 xgifb_info->XGI310_AccelDepth = 0x00000000; 1045 xgifb_info->XGI310_AccelDepth = 0x00000000;
1046 xgifb_info->video_cmap_len = 256; 1046 xgifb_info->video_cmap_len = 256;
1047#if defined(__powerpc__) 1047#if defined(__BIG_ENDIAN)
1048 cr_data = xgifb_reg_get(XGICR, 0x4D); 1048 cr_data = xgifb_reg_get(XGICR, 0x4D);
1049 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0)); 1049 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1050#endif 1050#endif
@@ -1052,7 +1052,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1052 case 16: 1052 case 16:
1053 xgifb_info->DstColor = 0x8000; 1053 xgifb_info->DstColor = 0x8000;
1054 xgifb_info->XGI310_AccelDepth = 0x00010000; 1054 xgifb_info->XGI310_AccelDepth = 0x00010000;
1055#if defined(__powerpc__) 1055#if defined(__BIG_ENDIAN)
1056 cr_data = xgifb_reg_get(XGICR, 0x4D); 1056 cr_data = xgifb_reg_get(XGICR, 0x4D);
1057 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B)); 1057 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1058#endif 1058#endif
@@ -1062,7 +1062,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1062 xgifb_info->DstColor = 0xC000; 1062 xgifb_info->DstColor = 0xC000;
1063 xgifb_info->XGI310_AccelDepth = 0x00020000; 1063 xgifb_info->XGI310_AccelDepth = 0x00020000;
1064 xgifb_info->video_cmap_len = 16; 1064 xgifb_info->video_cmap_len = 16;
1065#if defined(__powerpc__) 1065#if defined(__BIG_ENDIAN)
1066 cr_data = xgifb_reg_get(XGICR, 0x4D); 1066 cr_data = xgifb_reg_get(XGICR, 0x4D);
1067 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15)); 1067 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1068#endif 1068#endif
diff --git a/include/dt-bindings/iio/qcom,spmi-vadc.h b/include/dt-bindings/iio/qcom,spmi-vadc.h
new file mode 100644
index 000000000000..42121fa238fa
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-vadc.h
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_H
15#define _DT_BINDINGS_QCOM_SPMI_VADC_H
16
17/* Voltage ADC channels */
18#define VADC_USBIN 0x00
19#define VADC_DCIN 0x01
20#define VADC_VCHG_SNS 0x02
21#define VADC_SPARE1_03 0x03
22#define VADC_USB_ID_MV 0x04
23#define VADC_VCOIN 0x05
24#define VADC_VBAT_SNS 0x06
25#define VADC_VSYS 0x07
26#define VADC_DIE_TEMP 0x08
27#define VADC_REF_625MV 0x09
28#define VADC_REF_1250MV 0x0a
29#define VADC_CHG_TEMP 0x0b
30#define VADC_SPARE1 0x0c
31#define VADC_SPARE2 0x0d
32#define VADC_GND_REF 0x0e
33#define VADC_VDD_VADC 0x0f
34
35#define VADC_P_MUX1_1_1 0x10
36#define VADC_P_MUX2_1_1 0x11
37#define VADC_P_MUX3_1_1 0x12
38#define VADC_P_MUX4_1_1 0x13
39#define VADC_P_MUX5_1_1 0x14
40#define VADC_P_MUX6_1_1 0x15
41#define VADC_P_MUX7_1_1 0x16
42#define VADC_P_MUX8_1_1 0x17
43#define VADC_P_MUX9_1_1 0x18
44#define VADC_P_MUX10_1_1 0x19
45#define VADC_P_MUX11_1_1 0x1a
46#define VADC_P_MUX12_1_1 0x1b
47#define VADC_P_MUX13_1_1 0x1c
48#define VADC_P_MUX14_1_1 0x1d
49#define VADC_P_MUX15_1_1 0x1e
50#define VADC_P_MUX16_1_1 0x1f
51
52#define VADC_P_MUX1_1_3 0x20
53#define VADC_P_MUX2_1_3 0x21
54#define VADC_P_MUX3_1_3 0x22
55#define VADC_P_MUX4_1_3 0x23
56#define VADC_P_MUX5_1_3 0x24
57#define VADC_P_MUX6_1_3 0x25
58#define VADC_P_MUX7_1_3 0x26
59#define VADC_P_MUX8_1_3 0x27
60#define VADC_P_MUX9_1_3 0x28
61#define VADC_P_MUX10_1_3 0x29
62#define VADC_P_MUX11_1_3 0x2a
63#define VADC_P_MUX12_1_3 0x2b
64#define VADC_P_MUX13_1_3 0x2c
65#define VADC_P_MUX14_1_3 0x2d
66#define VADC_P_MUX15_1_3 0x2e
67#define VADC_P_MUX16_1_3 0x2f
68
69#define VADC_LR_MUX1_BAT_THERM 0x30
70#define VADC_LR_MUX2_BAT_ID 0x31
71#define VADC_LR_MUX3_XO_THERM 0x32
72#define VADC_LR_MUX4_AMUX_THM1 0x33
73#define VADC_LR_MUX5_AMUX_THM2 0x34
74#define VADC_LR_MUX6_AMUX_THM3 0x35
75#define VADC_LR_MUX7_HW_ID 0x36
76#define VADC_LR_MUX8_AMUX_THM4 0x37
77#define VADC_LR_MUX9_AMUX_THM5 0x38
78#define VADC_LR_MUX10_USB_ID 0x39
79#define VADC_AMUX_PU1 0x3a
80#define VADC_AMUX_PU2 0x3b
81#define VADC_LR_MUX3_BUF_XO_THERM 0x3c
82
83#define VADC_LR_MUX1_PU1_BAT_THERM 0x70
84#define VADC_LR_MUX2_PU1_BAT_ID 0x71
85#define VADC_LR_MUX3_PU1_XO_THERM 0x72
86#define VADC_LR_MUX4_PU1_AMUX_THM1 0x73
87#define VADC_LR_MUX5_PU1_AMUX_THM2 0x74
88#define VADC_LR_MUX6_PU1_AMUX_THM3 0x75
89#define VADC_LR_MUX7_PU1_AMUX_HW_ID 0x76
90#define VADC_LR_MUX8_PU1_AMUX_THM4 0x77
91#define VADC_LR_MUX9_PU1_AMUX_THM5 0x78
92#define VADC_LR_MUX10_PU1_AMUX_USB_ID 0x79
93#define VADC_LR_MUX3_BUF_PU1_XO_THERM 0x7c
94
95#define VADC_LR_MUX1_PU2_BAT_THERM 0xb0
96#define VADC_LR_MUX2_PU2_BAT_ID 0xb1
97#define VADC_LR_MUX3_PU2_XO_THERM 0xb2
98#define VADC_LR_MUX4_PU2_AMUX_THM1 0xb3
99#define VADC_LR_MUX5_PU2_AMUX_THM2 0xb4
100#define VADC_LR_MUX6_PU2_AMUX_THM3 0xb5
101#define VADC_LR_MUX7_PU2_AMUX_HW_ID 0xb6
102#define VADC_LR_MUX8_PU2_AMUX_THM4 0xb7
103#define VADC_LR_MUX9_PU2_AMUX_THM5 0xb8
104#define VADC_LR_MUX10_PU2_AMUX_USB_ID 0xb9
105#define VADC_LR_MUX3_BUF_PU2_XO_THERM 0xbc
106
107#define VADC_LR_MUX1_PU1_PU2_BAT_THERM 0xf0
108#define VADC_LR_MUX2_PU1_PU2_BAT_ID 0xf1
109#define VADC_LR_MUX3_PU1_PU2_XO_THERM 0xf2
110#define VADC_LR_MUX4_PU1_PU2_AMUX_THM1 0xf3
111#define VADC_LR_MUX5_PU1_PU2_AMUX_THM2 0xf4
112#define VADC_LR_MUX6_PU1_PU2_AMUX_THM3 0xf5
113#define VADC_LR_MUX7_PU1_PU2_AMUX_HW_ID 0xf6
114#define VADC_LR_MUX8_PU1_PU2_AMUX_THM4 0xf7
115#define VADC_LR_MUX9_PU1_PU2_AMUX_THM5 0xf8
116#define VADC_LR_MUX10_PU1_PU2_AMUX_USB_ID 0xf9
117#define VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM 0xfc
118
119#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_H */
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h
index 519392763393..b65850a41127 100644
--- a/include/linux/iio/buffer.h
+++ b/include/linux/iio/buffer.h
@@ -25,9 +25,7 @@ struct iio_buffer;
25 * available. 25 * available.
26 * @request_update: if a parameter change has been marked, update underlying 26 * @request_update: if a parameter change has been marked, update underlying
27 * storage. 27 * storage.
28 * @get_bytes_per_datum:get current bytes per datum
29 * @set_bytes_per_datum:set number of bytes per datum 28 * @set_bytes_per_datum:set number of bytes per datum
30 * @get_length: get number of datums in buffer
31 * @set_length: set number of datums in buffer 29 * @set_length: set number of datums in buffer
32 * @release: called when the last reference to the buffer is dropped, 30 * @release: called when the last reference to the buffer is dropped,
33 * should free all resources allocated by the buffer. 31 * should free all resources allocated by the buffer.
@@ -49,9 +47,7 @@ struct iio_buffer_access_funcs {
49 47
50 int (*request_update)(struct iio_buffer *buffer); 48 int (*request_update)(struct iio_buffer *buffer);
51 49
52 int (*get_bytes_per_datum)(struct iio_buffer *buffer);
53 int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); 50 int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
54 int (*get_length)(struct iio_buffer *buffer);
55 int (*set_length)(struct iio_buffer *buffer, int length); 51 int (*set_length)(struct iio_buffer *buffer, int length);
56 52
57 void (*release)(struct iio_buffer *buffer); 53 void (*release)(struct iio_buffer *buffer);
@@ -85,10 +81,11 @@ struct iio_buffer {
85 bool scan_timestamp; 81 bool scan_timestamp;
86 const struct iio_buffer_access_funcs *access; 82 const struct iio_buffer_access_funcs *access;
87 struct list_head scan_el_dev_attr_list; 83 struct list_head scan_el_dev_attr_list;
84 struct attribute_group buffer_group;
88 struct attribute_group scan_el_group; 85 struct attribute_group scan_el_group;
89 wait_queue_head_t pollq; 86 wait_queue_head_t pollq;
90 bool stufftoread; 87 bool stufftoread;
91 const struct attribute_group *attrs; 88 const struct attribute **attrs;
92 struct list_head demux_list; 89 struct list_head demux_list;
93 void *demux_bounce; 90 void *demux_bounce;
94 struct list_head buffer_list; 91 struct list_head buffer_list;
@@ -117,15 +114,6 @@ int iio_scan_mask_query(struct iio_dev *indio_dev,
117 struct iio_buffer *buffer, int bit); 114 struct iio_buffer *buffer, int bit);
118 115
119/** 116/**
120 * iio_scan_mask_set() - set particular bit in the scan mask
121 * @indio_dev IIO device structure
122 * @buffer: the buffer whose scan mask we are interested in
123 * @bit: the bit to be set.
124 **/
125int iio_scan_mask_set(struct iio_dev *indio_dev,
126 struct iio_buffer *buffer, int bit);
127
128/**
129 * iio_push_to_buffers() - push to a registered buffer. 117 * iio_push_to_buffers() - push to a registered buffer.
130 * @indio_dev: iio_dev structure for device. 118 * @indio_dev: iio_dev structure for device.
131 * @data: Full scan. 119 * @data: Full scan.
@@ -159,56 +147,6 @@ static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
159 147
160int iio_update_demux(struct iio_dev *indio_dev); 148int iio_update_demux(struct iio_dev *indio_dev);
161 149
162/**
163 * iio_buffer_register() - register the buffer with IIO core
164 * @indio_dev: device with the buffer to be registered
165 * @channels: the channel descriptions used to construct buffer
166 * @num_channels: the number of channels
167 **/
168int iio_buffer_register(struct iio_dev *indio_dev,
169 const struct iio_chan_spec *channels,
170 int num_channels);
171
172/**
173 * iio_buffer_unregister() - unregister the buffer from IIO core
174 * @indio_dev: the device with the buffer to be unregistered
175 **/
176void iio_buffer_unregister(struct iio_dev *indio_dev);
177
178/**
179 * iio_buffer_read_length() - attr func to get number of datums in the buffer
180 **/
181ssize_t iio_buffer_read_length(struct device *dev,
182 struct device_attribute *attr,
183 char *buf);
184/**
185 * iio_buffer_write_length() - attr func to set number of datums in the buffer
186 **/
187ssize_t iio_buffer_write_length(struct device *dev,
188 struct device_attribute *attr,
189 const char *buf,
190 size_t len);
191/**
192 * iio_buffer_store_enable() - attr to turn the buffer on
193 **/
194ssize_t iio_buffer_store_enable(struct device *dev,
195 struct device_attribute *attr,
196 const char *buf,
197 size_t len);
198/**
199 * iio_buffer_show_enable() - attr to see if the buffer is on
200 **/
201ssize_t iio_buffer_show_enable(struct device *dev,
202 struct device_attribute *attr,
203 char *buf);
204#define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR, \
205 iio_buffer_read_length, \
206 iio_buffer_write_length)
207
208#define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
209 iio_buffer_show_enable, \
210 iio_buffer_store_enable)
211
212bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, 150bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
213 const unsigned long *mask); 151 const unsigned long *mask);
214 152
@@ -232,16 +170,6 @@ static inline void iio_device_attach_buffer(struct iio_dev *indio_dev,
232 170
233#else /* CONFIG_IIO_BUFFER */ 171#else /* CONFIG_IIO_BUFFER */
234 172
235static inline int iio_buffer_register(struct iio_dev *indio_dev,
236 const struct iio_chan_spec *channels,
237 int num_channels)
238{
239 return 0;
240}
241
242static inline void iio_buffer_unregister(struct iio_dev *indio_dev)
243{}
244
245static inline void iio_buffer_get(struct iio_buffer *buffer) {} 173static inline void iio_buffer_get(struct iio_buffer *buffer) {}
246static inline void iio_buffer_put(struct iio_buffer *buffer) {} 174static inline void iio_buffer_put(struct iio_buffer *buffer) {}
247 175
diff --git a/include/linux/iio/common/ssp_sensors.h b/include/linux/iio/common/ssp_sensors.h
new file mode 100644
index 000000000000..f4d1b0edb432
--- /dev/null
+++ b/include/linux/iio/common/ssp_sensors.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15#ifndef _SSP_SENSORS_H_
16#define _SSP_SENSORS_H_
17
18#include <linux/iio/iio.h>
19
20#define SSP_TIME_SIZE 4
21#define SSP_ACCELEROMETER_SIZE 6
22#define SSP_GYROSCOPE_SIZE 6
23#define SSP_BIO_HRM_RAW_SIZE 8
24#define SSP_BIO_HRM_RAW_FAC_SIZE 36
25#define SSP_BIO_HRM_LIB_SIZE 8
26
27/**
28 * enum ssp_sensor_type - SSP sensor type
29 */
30enum ssp_sensor_type {
31 SSP_ACCELEROMETER_SENSOR = 0,
32 SSP_GYROSCOPE_SENSOR,
33 SSP_GEOMAGNETIC_UNCALIB_SENSOR,
34 SSP_GEOMAGNETIC_RAW,
35 SSP_GEOMAGNETIC_SENSOR,
36 SSP_PRESSURE_SENSOR,
37 SSP_GESTURE_SENSOR,
38 SSP_PROXIMITY_SENSOR,
39 SSP_TEMPERATURE_HUMIDITY_SENSOR,
40 SSP_LIGHT_SENSOR,
41 SSP_PROXIMITY_RAW,
42 SSP_ORIENTATION_SENSOR,
43 SSP_STEP_DETECTOR,
44 SSP_SIG_MOTION_SENSOR,
45 SSP_GYRO_UNCALIB_SENSOR,
46 SSP_GAME_ROTATION_VECTOR,
47 SSP_ROTATION_VECTOR,
48 SSP_STEP_COUNTER,
49 SSP_BIO_HRM_RAW,
50 SSP_BIO_HRM_RAW_FAC,
51 SSP_BIO_HRM_LIB,
52 SSP_SENSOR_MAX,
53};
54
55struct ssp_data;
56
57/**
58 * struct ssp_sensor_data - Sensor object
59 * @process_data: Callback to feed sensor data.
60 * @type: Used sensor type.
61 * @buffer: Received data buffer.
62 */
63struct ssp_sensor_data {
64 int (*process_data)(struct iio_dev *indio_dev, void *buf,
65 int64_t timestamp);
66 enum ssp_sensor_type type;
67 u8 *buffer;
68};
69
70void ssp_register_consumer(struct iio_dev *indio_dev,
71 enum ssp_sensor_type type);
72
73int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
74 u32 delay);
75
76int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type);
77
78u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type);
79
80int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
81 u32 delay);
82#endif /* _SSP_SENSORS_H_ */
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 651f9a0e2765..26fb8f6342bb 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -151,6 +151,16 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
151int iio_read_channel_processed(struct iio_channel *chan, int *val); 151int iio_read_channel_processed(struct iio_channel *chan, int *val);
152 152
153/** 153/**
154 * iio_write_channel_raw() - write to a given channel
155 * @chan: The channel being queried.
156 * @val: Value being written.
157 *
158 * Note raw writes to iio channels are in dac counts and hence
159 * scale will need to be applied if standard units required.
160 */
161int iio_write_channel_raw(struct iio_channel *chan, int val);
162
163/**
154 * iio_get_channel_type() - get the type of a channel 164 * iio_get_channel_type() - get the type of a channel
155 * @channel: The channel being queried. 165 * @channel: The channel being queried.
156 * @type: The type of the channel. 166 * @type: The type of the channel.
@@ -191,7 +201,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val,
191 * The scale factor allows to increase the precession of the returned value. For 201 * The scale factor allows to increase the precession of the returned value. For
192 * a scale factor of 1 the function will return the result in the normal IIO 202 * a scale factor of 1 the function will return the result in the normal IIO
193 * unit for the channel type. E.g. millivolt for voltage channels, if you want 203 * unit for the channel type. E.g. millivolt for voltage channels, if you want
194 * nanovolts instead pass 1000 as the scale factor. 204 * nanovolts instead pass 1000000 as the scale factor.
195 */ 205 */
196int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, 206int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
197 int *processed, unsigned int scale); 207 int *processed, unsigned int scale);
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 3642ce7ef512..80d855061064 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -38,6 +38,11 @@ enum iio_chan_info_enum {
38 IIO_CHAN_INFO_HARDWAREGAIN, 38 IIO_CHAN_INFO_HARDWAREGAIN,
39 IIO_CHAN_INFO_HYSTERESIS, 39 IIO_CHAN_INFO_HYSTERESIS,
40 IIO_CHAN_INFO_INT_TIME, 40 IIO_CHAN_INFO_INT_TIME,
41 IIO_CHAN_INFO_ENABLE,
42 IIO_CHAN_INFO_CALIBHEIGHT,
43 IIO_CHAN_INFO_CALIBWEIGHT,
44 IIO_CHAN_INFO_DEBOUNCE_COUNT,
45 IIO_CHAN_INFO_DEBOUNCE_TIME,
41}; 46};
42 47
43enum iio_shared_by { 48enum iio_shared_by {
@@ -284,10 +289,11 @@ static inline s64 iio_get_time_ns(void)
284/* Device operating modes */ 289/* Device operating modes */
285#define INDIO_DIRECT_MODE 0x01 290#define INDIO_DIRECT_MODE 0x01
286#define INDIO_BUFFER_TRIGGERED 0x02 291#define INDIO_BUFFER_TRIGGERED 0x02
292#define INDIO_BUFFER_SOFTWARE 0x04
287#define INDIO_BUFFER_HARDWARE 0x08 293#define INDIO_BUFFER_HARDWARE 0x08
288 294
289#define INDIO_ALL_BUFFER_MODES \ 295#define INDIO_ALL_BUFFER_MODES \
290 (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE) 296 (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | INDIO_BUFFER_SOFTWARE)
291 297
292#define INDIO_MAX_RAW_ELEMENTS 4 298#define INDIO_MAX_RAW_ELEMENTS 4
293 299
@@ -591,7 +597,8 @@ void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
591static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) 597static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
592{ 598{
593 return indio_dev->currentmode 599 return indio_dev->currentmode
594 & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE); 600 & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE |
601 INDIO_BUFFER_SOFTWARE);
595} 602}
596 603
597/** 604/**
diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h
index 25eeac762e84..1683bc710d14 100644
--- a/include/linux/iio/kfifo_buf.h
+++ b/include/linux/iio/kfifo_buf.h
@@ -5,7 +5,10 @@
5#include <linux/iio/iio.h> 5#include <linux/iio/iio.h>
6#include <linux/iio/buffer.h> 6#include <linux/iio/buffer.h>
7 7
8struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); 8struct iio_buffer *iio_kfifo_allocate(void);
9void iio_kfifo_free(struct iio_buffer *r); 9void iio_kfifo_free(struct iio_buffer *r);
10 10
11struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev);
12void devm_iio_kfifo_free(struct device *dev, struct iio_buffer *r);
13
11#endif 14#endif
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 4a2af8adf874..580ed5bdb3fa 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -30,6 +30,11 @@ enum iio_chan_type {
30 IIO_CCT, 30 IIO_CCT,
31 IIO_PRESSURE, 31 IIO_PRESSURE,
32 IIO_HUMIDITYRELATIVE, 32 IIO_HUMIDITYRELATIVE,
33 IIO_ACTIVITY,
34 IIO_STEPS,
35 IIO_ENERGY,
36 IIO_DISTANCE,
37 IIO_VELOCITY,
33}; 38};
34 39
35enum iio_modifier { 40enum iio_modifier {
@@ -59,7 +64,12 @@ enum iio_modifier {
59 IIO_MOD_NORTH_MAGN, 64 IIO_MOD_NORTH_MAGN,
60 IIO_MOD_NORTH_TRUE, 65 IIO_MOD_NORTH_TRUE,
61 IIO_MOD_NORTH_MAGN_TILT_COMP, 66 IIO_MOD_NORTH_MAGN_TILT_COMP,
62 IIO_MOD_NORTH_TRUE_TILT_COMP 67 IIO_MOD_NORTH_TRUE_TILT_COMP,
68 IIO_MOD_RUNNING,
69 IIO_MOD_JOGGING,
70 IIO_MOD_WALKING,
71 IIO_MOD_STILL,
72 IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,
63}; 73};
64 74
65enum iio_event_type { 75enum iio_event_type {
@@ -68,6 +78,7 @@ enum iio_event_type {
68 IIO_EV_TYPE_ROC, 78 IIO_EV_TYPE_ROC,
69 IIO_EV_TYPE_THRESH_ADAPTIVE, 79 IIO_EV_TYPE_THRESH_ADAPTIVE,
70 IIO_EV_TYPE_MAG_ADAPTIVE, 80 IIO_EV_TYPE_MAG_ADAPTIVE,
81 IIO_EV_TYPE_CHANGE,
71}; 82};
72 83
73enum iio_event_info { 84enum iio_event_info {
@@ -81,6 +92,7 @@ enum iio_event_direction {
81 IIO_EV_DIR_EITHER, 92 IIO_EV_DIR_EITHER,
82 IIO_EV_DIR_RISING, 93 IIO_EV_DIR_RISING,
83 IIO_EV_DIR_FALLING, 94 IIO_EV_DIR_FALLING,
95 IIO_EV_DIR_NONE,
84}; 96};
85 97
86#define IIO_VAL_INT 1 98#define IIO_VAL_INT 1