dect
/
linux-2.6
Archived
13
0
Fork 0

Staging driver tree merge for 3.8-rc1

Here's the big staging tree merge for 3.8-rc1
 
 There's a lot of patches in here, the majority being the comedi rework/cleanup
 that has been ongoing and is causing a huge reduction in overall code size,
 which is amazing to watch.  We also removed some older drivers (telephony and
 rts_pstor), and added a new one (fwserial which also came in through the tty
 tree due to tty api changes, take that one if you get merge conflicts.)
 
 The iio and ipack drivers are moving out of the staging area into their
 own part of the kernel as they have been cleaned up sufficiently and are
 working well.
 
 Overall, again a reduction of code:
  768 files changed, 31887 insertions(+), 82166 deletions(-)
 
 All of this has been in the linux-next tree for a while.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iEYEABECAAYFAlDHiRkACgkQMUfUDdst+ykyCgCglEbrWzevtCOl+C2KAmIR+Jnt
 qUsAoLOXYeQq1aadxzqh3tK+ytlMrWd1
 =Ync9
 -----END PGP SIGNATURE-----

Merge tag 'staging-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver tree merge from Greg Kroah-Hartman:
 "Here's the big staging tree merge for 3.8-rc1

  There's a lot of patches in here, the majority being the comedi
  rework/cleanup that has been ongoing and is causing a huge reduction
  in overall code size, which is amazing to watch.  We also removed some
  older drivers (telephony and rts_pstor), and added a new one (fwserial
  which also came in through the tty tree due to tty api changes, take
  that one if you get merge conflicts.)

  The iio and ipack drivers are moving out of the staging area into
  their own part of the kernel as they have been cleaned up sufficiently
  and are working well.

  Overall, again a reduction of code:
   768 files changed, 31887 insertions(+), 82166 deletions(-)

  All of this has been in the linux-next tree for a while.

  Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"

* tag 'staging-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1298 commits)
  iio: imu: adis16480: remove duplicated include from adis16480.c
  iio: gyro: adis16136: remove duplicated include from adis16136.c
  iio:imu: adis16480: show_firmware() buffer too small
  iio:gyro: adis16136: divide by zero in write_frequency()
  iio: adc: Add Texas Instruments ADC081C021/027 support
  iio:ad7793: Add support for the ad7796 and ad7797
  iio:ad7793: Add support for the ad7798 and ad7799
  staging:iio: Move ad7793 driver out of staging
  staging:iio:ad7793: Implement stricter id checking
  staging:iio:ad7793: Move register definitions from header to source
  staging:iio:ad7793: Rework regulator handling
  staging:iio:ad7793: Rework platform data
  staging:iio:ad7793: Use kstrtol instead of strict_strtol
  staging:iio:ad7793: Use usleep_range instead of msleep
  staging:iio:ad7793: Fix temperature scale
  staging:iio:ad7793: Fix VDD monitor scale
  staging: gdm72xx: unlock on error in init_usb()
  staging: panel: pass correct lengths to keypad_send_key()
  staging: comedi: addi_apci_2032: fix interrupt support
  staging: comedi: addi_apci_2032: move i_APCI2032_ConfigDigitalOutput()
  ...
This commit is contained in:
Linus Torvalds 2012-12-11 13:59:44 -08:00
commit 8966961b31
768 changed files with 31772 additions and 82051 deletions

View File

@ -189,6 +189,14 @@ Description:
A computed peak value based on the sum squared magnitude of
the underlying value in the specified directions.
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_raw
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_raw
KernelVersion: 3.8
Contact: linux-iio@vger.kernel.org
Description:
Raw pressure measurement from channel Y. Units after
application of scale and offset are kilopascal.
What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
@ -197,6 +205,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@ -226,6 +236,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@ -245,6 +257,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibbias
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibbias
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@ -262,6 +276,8 @@ What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale
What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale
what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale
what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibscale
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibscale
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@ -275,6 +291,8 @@ What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
What: /sys/.../iio:deviceX/out_voltageX_scale_available
What: /sys/.../iio:deviceX/out_altvoltageX_scale_available
What: /sys/.../iio:deviceX/in_capacitance_scale_available
What: /sys/.../iio:deviceX/in_pressure_scale_available
What: /sys/.../iio:deviceX/in_pressureY_scale_available
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@ -694,6 +712,8 @@ What: /sys/.../buffer/scan_elements/in_voltageY_en
What: /sys/.../buffer/scan_elements/in_voltageY-voltageZ_en
What: /sys/.../buffer/scan_elements/in_incli_x_en
What: /sys/.../buffer/scan_elements/in_incli_y_en
What: /sys/.../buffer/scan_elements/in_pressureY_en
What: /sys/.../buffer/scan_elements/in_pressure_en
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
@ -707,6 +727,8 @@ What: /sys/.../buffer/scan_elements/in_voltageY_type
What: /sys/.../buffer/scan_elements/in_voltage_type
What: /sys/.../buffer/scan_elements/in_voltageY_supply_type
What: /sys/.../buffer/scan_elements/in_timestamp_type
What: /sys/.../buffer/scan_elements/in_pressureY_type
What: /sys/.../buffer/scan_elements/in_pressure_type
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
@ -751,6 +773,8 @@ What: /sys/.../buffer/scan_elements/in_magn_z_index
What: /sys/.../buffer/scan_elements/in_incli_x_index
What: /sys/.../buffer/scan_elements/in_incli_y_index
What: /sys/.../buffer/scan_elements/in_timestamp_index
What: /sys/.../buffer/scan_elements/in_pressureY_index
What: /sys/.../buffer/scan_elements/in_pressure_index
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:

View File

@ -1,4 +0,0 @@
00-INDEX
- this file.
ixj.txt
- document describing the Quicknet drivers.

View File

@ -1,394 +0,0 @@
Linux Quicknet-Drivers-Howto
Quicknet Technologies, Inc. (www.quicknet.net)
Version 0.3.4 December 18, 1999
1.0 Introduction
This document describes the first GPL release version of the Linux
driver for the Quicknet Internet PhoneJACK and Internet LineJACK
cards. More information about these cards is available at
www.quicknet.net. The driver version discussed in this document is
0.3.4.
These cards offer nice telco style interfaces to use your standard
telephone/key system/PBX as the user interface for VoIP applications.
The Internet LineJACK also offers PSTN connectivity for a single line
Internet to PSTN gateway. Of course, you can add more than one card
to a system to obtain multi-line functionality. At this time, the
driver supports the POTS port on both the Internet PhoneJACK and the
Internet LineJACK, but the PSTN port on the latter card is not yet
supported.
This document, and the drivers for the cards, are intended for a
limited audience that includes technically capable programmers who
would like to experiment with Quicknet cards. The drivers are
considered in ALPHA status and are not yet considered stable enough
for general, widespread use in an unlimited audience.
That's worth saying again:
THE LINUX DRIVERS FOR QUICKNET CARDS ARE PRESENTLY IN A ALPHA STATE
AND SHOULD NOT BE CONSIDERED AS READY FOR NORMAL WIDESPREAD USE.
They are released early in the spirit of Internet development and to
make this technology available to innovators who would benefit from
early exposure.
When we promote the device driver to "beta" level it will be
considered ready for non-programmer, non-technical users. Until then,
please be aware that these drivers may not be stable and may affect
the performance of your system.
1.1 Latest Additions/Improvements
The 0.3.4 version of the driver is the first GPL release. Several
features had to be removed from the prior binary only module, mostly
for reasons of Intellectual Property rights. We can't release
information that is not ours - so certain aspects of the driver had to
be removed to protect the rights of others.
Specifically, very old Internet PhoneJACK cards have non-standard
G.723.1 codecs (due to the early nature of the DSPs in those days).
The auto-conversion code to bring those cards into compliance with
today's standards is available as a binary only module to those people
needing it. If you bought your card after 1997 or so, you are OK -
it's only the very old cards that are affected.
Also, the code to download G.728/G.729/G.729a codecs to the DSP is
available as a binary only module as well. This IP is not ours to
release.
Hooks are built into the GPL driver to allow it to work with other
companion modules that are completely separate from this module.
1.2 Copyright, Trademarks, Disclaimer, & Credits
Copyright
Copyright (c) 1999 Quicknet Technologies, Inc. Permission is granted
to freely copy and distribute this document provided you preserve it
in its original form. For corrections and minor changes contact the
maintainer at linux@quicknet.net.
Trademarks
Internet PhoneJACK and Internet LineJACK are registered trademarks of
Quicknet Technologies, Inc.
Disclaimer
Much of the info in this HOWTO is early information released by
Quicknet Technologies, Inc. for the express purpose of allowing early
testing and use of the Linux drivers developed for their products.
While every attempt has been made to be thorough, complete and
accurate, the information contained here may be unreliable and there
are likely a number of errors in this document. Please let the
maintainer know about them. Since this is free documentation, it
should be obvious that neither I nor previous authors can be held
legally responsible for any errors.
Credits
This HOWTO was written by:
Greg Herlein <gherlein@quicknet.net>
Ed Okerson <eokerson@quicknet.net>
1.3 Future Plans: You Can Help
Please let the maintainer know of any errors in facts, opinions,
logic, spelling, grammar, clarity, links, etc. But first, if the date
is over a month old, check to see that you have the latest
version. Please send any info that you think belongs in this document.
You can also contribute code and/or bug-fixes for the sample
applications.
1.4 Where to get things
Info on latest versions of the driver are here:
http://web.archive.org/web/*/http://www.quicknet.net/develop.htm
1.5 Mailing List
Quicknet operates a mailing list to provide a public forum on using
these drivers.
To subscribe to the linux-sdk mailing list, send an email to:
majordomo@linux.quicknet.net
In the body of the email, type:
subscribe linux-sdk <your-email-address>
Please delete any signature block that you would normally add to the
bottom of your email - it tends to confuse majordomo.
To send mail to the list, address your mail to
linux-sdk@linux.quicknet.net
Your message will go out to everyone on the list.
To unsubscribe to the linux-sdk mailing list, send an email to:
majordomo@linux.quicknet.net
In the body of the email, type:
unsubscribe linux-sdk <your-email-address>
2.0 Requirements
2.1 Quicknet Card(s)
You will need at least one Internet PhoneJACK or Internet LineJACK
cards. These are ISA or PCI bus devices that use Plug-n-Play for
configuration, and use no IRQs. The driver will support up to 16
cards in any one system, of any mix between the two types.
Note that you will need two cards to do any useful testing alone, since
you will need a card on both ends of the connection. Of course, if
you are doing collaborative work, perhaps your friends or coworkers
have cards too. If not, we'll gladly sell them some!
2.2 ISAPNP
Since the Quicknet cards are Plug-n-Play devices, you will need the
isapnp tools package to configure the cards, or you can use the isapnp
module to autoconfigure them. The former package probably came with
your Linux distribution. Documentation on this package is available
online at:
http://mailer.wiwi.uni-marburg.de/linux/LDP/HOWTO/Plug-and-Play-HOWTO.html
The isapnp autoconfiguration is available on the Quicknet website at:
http://www.quicknet.net/develop.htm
though it may be in the kernel by the time you read this.
3.0 Card Configuration
If you did not get your drivers as part of the linux kernel, do the
following to install them:
a. untar the distribution file. We use the following command:
tar -xvzf ixj-0.x.x.tgz
This creates a subdirectory holding all the necessary files. Go to that
subdirectory.
b. run the "ixj_dev_create" script to remove any stray device
files left in the /dev directory, and to create the new officially
designated device files. Note that the old devices were called
/dev/ixj, and the new method uses /dev/phone.
c. type "make;make install" - this will compile and install the
module.
d. type "depmod -av" to rebuild all your kernel version dependencies.
e. if you are using the isapnp module to configure the cards
automatically, then skip to step f. Otherwise, ensure that you
have run the isapnp configuration utility to properly configure
the cards.
e1. The Internet PhoneJACK has one configuration register that
requires 16 IO ports. The Internet LineJACK card has two
configuration registers and isapnp reports that IO 0
requires 16 IO ports and IO 1 requires 8. The Quicknet
driver assumes that these registers are configured to be
contiguous, i.e. if IO 0 is set to 0x340 then IO 1 should
be set to 0x350.
Make sure that none of the cards overlap if you have
multiple cards in the system.
If you are new to the isapnp tools, you can jumpstart
yourself by doing the following:
e2. go to the /etc directory and run pnpdump to get a blank
isapnp.conf file.
pnpdump > /etc/isapnp.conf
e3. edit the /etc/isapnp.conf file to set the IO warnings and
the register IO addresses. The IO warnings means that you
should find the line in the file that looks like this:
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING
and you should edit the line to look like this:
(CONFLICT (IO WARNING)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) #
or WARNING
The next step is to set the IO port addresses. The issue
here is that isapnp does not identify all of the ports out
there. Specifically any device that does not have a driver
or module loaded by Linux will not be registered. This
includes older sound cards and network cards. We have
found that the IO port 0x300 is often used even though
isapnp claims that no-one is using those ports. We
recommend that for a single card installation that port
0x340 (and 0x350) be used. The IO port line should change
from this:
(IO 0 (SIZE 16) (BASE 0x0300) (CHECK))
to this:
(IO 0 (SIZE 16) (BASE 0x0340) )
e4. if you have multiple Quicknet cards, make sure that you do
not have any overlaps. Be especially careful if you are
mixing Internet PhoneJACK and Internet LineJACK cards in
the same system. In these cases we recommend moving the
IO port addresses to the 0x400 block. Please note that on
a few machines the 0x400 series are used. Feel free to
experiment with other addresses. Our cards have been
proven to work using IO addresses of up to 0xFF0.
e5. the last step is to uncomment the activation line so the
drivers will be associated with the port. This means the
line (immediately below) the IO line should go from this:
# (ACT Y)
to this:
(ACT Y)
Once you have finished editing the isapnp.conf file you
must submit it into the pnp driverconfigure the cards.
This is done using the following command:
isapnp isapnp.conf
If this works you should see a line that identifies the
Quicknet device, the IO port(s) chosen, and a message
"Enabled OK".
f. if you are loading the module by hand, use insmod. An example
of this would look like this:
insmod phonedev
insmod ixj dspio=0x320,0x310 xio=0,0x330
Then verify the module loaded by running lsmod. If you are not using a
module that matches your kernel version, you may need to "force" the
load using the -f option in the insmod command.
insmod phonedev
insmod -f ixj dspio=0x320,0x310 xio=0,0x330
If you are using isapnp to autoconfigure your card, then you do NOT
need any of the above, though you need to use depmod to load the
driver, like this:
depmod ixj
which will result in the needed drivers getting loaded automatically.
g. if you are planning on having the kernel automatically request
the module for you, then you need to edit /etc/conf.modules and add the
following lines:
options ixj dspio=0x340 xio=0x330 ixjdebug=0
If you do this, then when you execute an application that uses the
module the kernel will request that it is loaded.
h. if you want non-root users to be able to read and write to the
ixj devices (this is a good idea!) you should do the following:
- decide upon a group name to use and create that group if
needed. Add the user names to that group that you wish to
have access to the device. For example, we typically will
create a group named "ixj" in /etc/group and add all users
to that group that we want to run software that can use the
ixjX devices.
- change the permissions on the device files, like this:
chgrp ixj /dev/ixj*
chmod 660 /dev/ixj*
Once this is done, then non-root users should be able to use the
devices. If you have enabled autoloading of modules, then the user
should be able to open the device and have the module loaded
automatically for them.
4.0 Driver Installation problems.
We have tested these drivers on the 2.2.9, 2.2.10, 2.2.12, and 2.2.13 kernels
and in all cases have eventually been able to get the drivers to load and
run. We have found four types of problems that prevent this from happening.
The problems and solutions are:
a. A step was missed in the installation. Go back and use section 3
as a checklist. Many people miss running the ixj_dev_create script and thus
never load the device names into the filesystem.
b. The kernel is inconsistently linked. We have found this problem in
the Out Of the Box installation of several distributions. The symptoms
are that neither driver will load, and that the unknown symbols include "jiffy"
and "kmalloc". The solution is to recompile both the kernel and the
modules. The command string for the final compile looks like this:
In the kernel directory:
1. cp .config /tmp
2. make mrproper
3. cp /tmp/.config .
4. make clean;make bzImage;make modules;make modules_install
This rebuilds both the kernel and all the modules and makes sure they all
have the same linkages. This generally solves the problem once the new
kernel is installed and the system rebooted.
c. The kernel has been patched, then unpatched. This happens when
someone decides to use an earlier kernel after they load a later kernel.
The symptoms are proceeding through all three above steps and still not
being able to load the driver. What has happened is that the generated
header files are out of sync with the kernel itself. The solution is
to recompile (again) using "make mrproper". This will remove and then
regenerate all the necessary header files. Once this is done, then you
need to install and reboot the kernel. We have not seen any problem
loading one of our drivers after this treatment.
5.0 Known Limitations
We cannot currently play "dial-tone" and listen for DTMF digits at the
same time using the ISA PhoneJACK. This is a bug in the 8020 DSP chip
used on that product. All other Quicknet products function normally
in this regard. We have a work-around, but it's not done yet. Until
then, if you want dial-tone, you can always play a recorded dial-tone
sound into the audio until you have gathered the DTMF digits.

View File

@ -3788,6 +3788,15 @@ M: Stanislaw Gruszka <stf_xl@wp.pl>
S: Maintained
F: drivers/usb/atm/ueagle-atm.c
INDUSTRY PACK SUBSYSTEM (IPACK)
M: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
M: Jens Taprogge <jens.taprogge@taprogge.org>
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: industrypack-devel@lists.sourceforge.net
W: http://industrypack.sourceforge.net
S: Maintained
F: drivers/ipack/
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
M: Mimi Zohar <zohar@us.ibm.com>
S: Supported

View File

@ -45,7 +45,6 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include "common.h"
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-tfp410.h>

View File

@ -23,15 +23,20 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/platform_data/omap_drm.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
#include <plat/cpu.h>
#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
static struct omap_drm_platform_data platform_data;
static struct platform_device omap_drm_device = {
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &platform_data,
},
.name = "omapdrm",
.id = 0,
@ -52,6 +57,8 @@ static int __init omap_init_drm(void)
oh->name);
}
platform_data.omaprev = GET_OMAP_REVISION();
return platform_device_register(&omap_drm_device);
}

View File

@ -156,4 +156,6 @@ source "drivers/pwm/Kconfig"
source "drivers/irqchip/Kconfig"
source "drivers/ipack/Kconfig"
endmenu

View File

@ -145,3 +145,4 @@ obj-$(CONFIG_EXTCON) += extcon/
obj-$(CONFIG_MEMORY) += memory/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_IPACK_BUS) += ipack/

View File

@ -20,6 +20,12 @@ config IIO_BUFFER
if IIO_BUFFER
config IIO_BUFFER_CB
boolean "IIO callback buffer used for push in-kernel interfaces"
help
Should be selected by any drivers that do-inkernel push
usage. That is, those where the data is pushed to the consumer.
config IIO_KFIFO_BUF
select IIO_TRIGGER
tristate "Industrial I/O buffering based on kfifo"
@ -57,11 +63,12 @@ config IIO_CONSUMERS_PER_TRIGGER
source "drivers/iio/accel/Kconfig"
source "drivers/iio/adc/Kconfig"
source "drivers/iio/amplifiers/Kconfig"
source "drivers/iio/light/Kconfig"
source "drivers/iio/frequency/Kconfig"
source "drivers/iio/dac/Kconfig"
source "drivers/iio/common/Kconfig"
source "drivers/iio/dac/Kconfig"
source "drivers/iio/frequency/Kconfig"
source "drivers/iio/gyro/Kconfig"
source "drivers/iio/imu/Kconfig"
source "drivers/iio/light/Kconfig"
source "drivers/iio/magnetometer/Kconfig"
endif # IIO

View File

@ -6,6 +6,7 @@ obj-$(CONFIG_IIO) += industrialio.o
industrialio-y := industrialio-core.o industrialio-event.o inkern.o
industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o
obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
@ -13,9 +14,10 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
obj-y += accel/
obj-y += adc/
obj-y += amplifiers/
obj-y += light/
obj-y += frequency/
obj-y += dac/
obj-y += common/
obj-y += dac/
obj-y += gyro/
obj-y += frequency/
obj-y += imu/
obj-y += light/
obj-y += magnetometer/

View File

@ -8,7 +8,7 @@ config HID_SENSOR_ACCEL_3D
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select HID_SENSOR_IIO_COMMON
tristate "HID Acelerometers 3D"
tristate "HID Accelerometers 3D"
help
Say yes here to build support for the HID SENSOR
accelerometers 3D.

View File

@ -197,21 +197,8 @@ static const struct iio_info accel_3d_info = {
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) {
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@ -319,10 +306,10 @@ static int __devinit hid_accel_3d_probe(struct platform_device *pdev)
goto error_free_dev;
}
channels = kmemdup(accel_3d_channels,
sizeof(accel_3d_channels),
GFP_KERNEL);
channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}

View File

@ -18,6 +18,18 @@ config AD7266
Say yes here to build support for Analog Devices AD7265 and AD7266
ADCs.
config AD7298
tristate "Analog Devices AD7298 ADC driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices AD7298
8 Channel ADC with temperature sensor.
To compile this driver as a module, choose M here: the
module will be called ad7298.
config AD7791
tristate "Analog Devices AD7791 ADC driver"
depends on SPI
@ -30,6 +42,18 @@ config AD7791
To compile this driver as a module, choose M here: the module will be
called ad7791.
config AD7793
tristate "Analog Devices AD7793 and similar ADCs driver"
depends on SPI
select AD_SIGMA_DELTA
help
Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
AD7794 and AD7795 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
module will be called AD7793.
config AD7476
tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
depends on SPI
@ -45,6 +69,19 @@ config AD7476
To compile this driver as a module, choose M here: the
module will be called ad7476.
config AD7887
tristate "Analog Devices AD7887 ADC driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices
AD7887 SPI analog to digital converter (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
module will be called ad7887.
config AT91_ADC
tristate "Atmel AT91 ADC"
depends on ARCH_AT91
@ -60,4 +97,32 @@ config LP8788_ADC
help
Say yes here to build support for TI LP8788 ADC.
config MAX1363
tristate "Maxim max1363 ADC driver"
depends on I2C
select IIO_TRIGGER
select MAX1363_RING_BUFFER
select IIO_BUFFER
select IIO_KFIFO_BUF
help
Say yes here to build support for many Maxim i2c analog to digital
converters (ADC). (max1361, max1362, max1363, max1364, max1036,
max1037, max1038, max1039, max1136, max1136, max1137, max1138,
max1139, max1236, max1237, max11238, max1239, max11600, max11601,
max11602, max11603, max11604, max11605, max11606, max11607,
max11608, max11609, max11610, max11611, max11612, max11613,
max11614, max11615, max11616, max11617, max11644, max11645,
max11646, max11647) Provides direct access via sysfs and buffered
data via the iio dev interface.
config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
help
If you say yes here you get support for Texas Instruments ADC081C021
and ADC081C027 ADC chips.
This driver can also be built as a module. If so, the module will be
called ti-adc081c.
endmenu

View File

@ -4,7 +4,13 @@
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7298) += ad7298.o
obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AD7793) += ad7793.o
obj-$(CONFIG_AD7887) += ad7887.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o

View File

@ -91,7 +91,6 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct iio_buffer *buffer = indio_dev->buffer;
struct ad7266_state *st = iio_priv(indio_dev);
int ret;
@ -99,7 +98,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
if (ret == 0) {
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = pf->timestamp;
iio_push_to_buffer(buffer, (u8 *)st->data);
iio_push_to_buffers(indio_dev, (u8 *)st->data);
}
iio_trigger_notify_done(indio_dev->trig);

View File

@ -15,12 +15,48 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include "ad7298.h"
#include <linux/platform_data/ad7298.h>
#define AD7298_WRITE (1 << 15) /* write to the control register */
#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */
#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */
#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */
#define AD7298_EXTREF (1 << 2) /* external reference enable */
#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */
#define AD7298_PDD (1 << 0) /* partial power down enable */
#define AD7298_MAX_CHAN 8
#define AD7298_BITS 12
#define AD7298_STORAGE_BITS 16
#define AD7298_INTREF_mV 2500
#define AD7298_CH_TEMP 9
#define RES_MASK(bits) ((1 << (bits)) - 1)
struct ad7298_state {
struct spi_device *spi;
struct regulator *reg;
unsigned ext_ref;
struct spi_transfer ring_xfer[10];
struct spi_transfer scan_single_xfer[3];
struct spi_message ring_msg;
struct spi_message scan_single_msg;
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
__be16 rx_buf[12] ____cacheline_aligned;
__be16 tx_buf[2];
};
#define AD7298_V_CHAN(index) \
{ \
@ -35,6 +71,7 @@
.sign = 'u', \
.realbits = 12, \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
}
@ -44,7 +81,8 @@ static const struct iio_chan_spec ad7298_channels[] = {
.indexed = 1,
.channel = 0,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
.address = AD7298_CH_TEMP,
.scan_index = -1,
.scan_type = {
@ -64,6 +102,84 @@ static const struct iio_chan_spec ad7298_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(8),
};
/**
* ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask
**/
static int ad7298_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *active_scan_mask)
{
struct ad7298_state *st = iio_priv(indio_dev);
int i, m;
unsigned short command;
int scan_count;
/* Now compute overall size */
scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength);
command = AD7298_WRITE | st->ext_ref;
for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
if (test_bit(i, active_scan_mask))
command |= m;
st->tx_buf[0] = cpu_to_be16(command);
/* build spi ring message */
st->ring_xfer[0].tx_buf = &st->tx_buf[0];
st->ring_xfer[0].len = 2;
st->ring_xfer[0].cs_change = 1;
st->ring_xfer[1].tx_buf = &st->tx_buf[1];
st->ring_xfer[1].len = 2;
st->ring_xfer[1].cs_change = 1;
spi_message_init(&st->ring_msg);
spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
for (i = 0; i < scan_count; i++) {
st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i];
st->ring_xfer[i + 2].len = 2;
st->ring_xfer[i + 2].cs_change = 1;
spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg);
}
/* make sure last transfer cs_change is not set */
st->ring_xfer[i + 1].cs_change = 0;
return 0;
}
/**
* ad7298_trigger_handler() bh of trigger launched polling to ring buffer
*
* Currently there is no option in this driver to disable the saving of
* timestamps within the ring.
**/
static irqreturn_t ad7298_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7298_state *st = iio_priv(indio_dev);
s64 time_ns = 0;
int b_sent;
b_sent = spi_sync(st->spi, &st->ring_msg);
if (b_sent)
goto done;
if (indio_dev->scan_timestamp) {
time_ns = iio_get_time_ns();
memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
}
iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
{
int ret;
@ -79,7 +195,7 @@ static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
static int ad7298_scan_temp(struct ad7298_state *st, int *val)
{
int tmp, ret;
int ret;
__be16 buf;
buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
@ -101,26 +217,26 @@ static int ad7298_scan_temp(struct ad7298_state *st, int *val)
if (ret)
return ret;
tmp = be16_to_cpu(buf) & RES_MASK(AD7298_BITS);
/*
* One LSB of the ADC corresponds to 0.25 deg C.
* The temperature reading is in 12-bit twos complement format
*/
if (tmp & (1 << (AD7298_BITS - 1))) {
tmp = (4096 - tmp) * 250;
tmp -= (2 * tmp);
} else {
tmp *= 250; /* temperature in milli degrees Celsius */
}
*val = tmp;
*val = sign_extend32(be16_to_cpu(buf), 11);
return 0;
}
static int ad7298_get_ref_voltage(struct ad7298_state *st)
{
int vref;
if (st->ext_ref) {
vref = regulator_get_voltage(st->reg);
if (vref < 0)
return vref;
return vref / 1000;
} else {
return AD7298_INTREF_mV;
}
}
static int ad7298_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@ -129,7 +245,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7298_state *st = iio_priv(indio_dev);
unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@ -154,17 +269,19 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
*val = scale_uv / 1000;
*val2 = (scale_uv % 1000) * 1000;
return IIO_VAL_INT_PLUS_MICRO;
*val = ad7298_get_ref_voltage(st);
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_TEMP:
*val = 1;
*val2 = 0;
return IIO_VAL_INT_PLUS_MICRO;
*val = ad7298_get_ref_voltage(st);
*val2 = 10;
return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_OFFSET:
*val = 1093 - 2732500 / ad7298_get_ref_voltage(st);
return IIO_VAL_INT;
}
return -EINVAL;
}
@ -179,16 +296,23 @@ static int __devinit ad7298_probe(struct spi_device *spi)
{
struct ad7298_platform_data *pdata = spi->dev.platform_data;
struct ad7298_state *st;
int ret;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
int ret;
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
if (pdata && pdata->ext_ref)
st->ext_ref = AD7298_EXTREF;
if (st->ext_ref) {
st->reg = regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free;
}
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
@ -221,14 +345,8 @@ static int __devinit ad7298_probe(struct spi_device *spi)
spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg);
if (pdata && pdata->vref_mv) {
st->int_vref_mv = pdata->vref_mv;
st->ext_ref = AD7298_EXTREF;
} else {
st->int_vref_mv = AD7298_INTREF_mV;
}
ret = ad7298_register_ring_funcs_and_init(indio_dev);
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&ad7298_trigger_handler, NULL);
if (ret)
goto error_disable_reg;
@ -239,13 +357,14 @@ static int __devinit ad7298_probe(struct spi_device *spi)
return 0;
error_cleanup_ring:
ad7298_ring_cleanup(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
if (!IS_ERR(st->reg))
if (st->ext_ref)
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
if (st->ext_ref)
regulator_put(st->reg);
error_free:
iio_device_free(indio_dev);
return ret;
@ -257,8 +376,8 @@ static int __devexit ad7298_remove(struct spi_device *spi)
struct ad7298_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
ad7298_ring_cleanup(indio_dev);
if (!IS_ERR(st->reg)) {
iio_triggered_buffer_cleanup(indio_dev);
if (st->ext_ref) {
regulator_disable(st->reg);
regulator_put(st->reg);
}

View File

@ -76,7 +76,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = time_ns;
iio_push_to_buffer(indio_dev->buffer, st->data);
iio_push_to_buffers(indio_dev, st->data);
done:
iio_trigger_notify_done(indio_dev->trig);

View File

@ -25,8 +25,106 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/adc/ad_sigma_delta.h>
#include <linux/platform_data/ad7793.h>
#include "ad7793.h"
/* Registers */
#define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */
#define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */
#define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */
#define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */
#define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */
#define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */
#define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */
#define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit
* (AD7792)/24-bit (AD7793)) */
#define AD7793_REG_FULLSALE 7 /* Full-Scale Register
* (RW, 16-bit (AD7792)/24-bit (AD7793)) */
/* Communications Register Bit Designations (AD7793_REG_COMM) */
#define AD7793_COMM_WEN (1 << 7) /* Write Enable */
#define AD7793_COMM_WRITE (0 << 6) /* Write Operation */
#define AD7793_COMM_READ (1 << 6) /* Read Operation */
#define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */
#define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */
/* Status Register Bit Designations (AD7793_REG_STAT) */
#define AD7793_STAT_RDY (1 << 7) /* Ready */
#define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */
#define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */
#define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */
#define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */
/* Mode Register Bit Designations (AD7793_REG_MODE) */
#define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */
#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */
#define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */
#define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */
#define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */
#define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */
#define AD7793_MODE_IDLE 2 /* Idle Mode */
#define AD7793_MODE_PWRDN 3 /* Power-Down Mode */
#define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */
#define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */
#define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */
#define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */
#define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not
* available at the CLK pin */
#define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available
* at the CLK pin */
#define AD7793_CLK_EXT 2 /* External 64 kHz Clock */
#define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */
/* Configuration Register Bit Designations (AD7793_REG_CONF) */
#define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage
* Generator Enable */
#define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */
#define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */
#define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */
#define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */
#define AD7793_CONF_REFSEL(x) ((x) << 6) /* INT/EXT Reference Select */
#define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */
#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */
#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */
#define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */
#define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */
#define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */
#define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */
#define AD7793_CH_TEMP 6 /* Temp Sensor */
#define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */
#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */
#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */
#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */
#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */
/* ID Register Bit Designations (AD7793_REG_ID) */
#define AD7785_ID 0xB
#define AD7792_ID 0xA
#define AD7793_ID 0xB
#define AD7794_ID 0xF
#define AD7795_ID 0xF
#define AD7796_ID 0xA
#define AD7797_ID 0xB
#define AD7798_ID 0x8
#define AD7799_ID 0x9
#define AD7793_ID_MASK 0xF
/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
#define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1,
* IEXC2 connect to IOUT2 */
#define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2,
* IEXC2 connect to IOUT1 */
#define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources
* IEXC1,2 connect to IOUT1 */
#define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources
* IEXC1,2 connect to IOUT2 */
#define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */
#define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */
#define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */
/* NOTE:
* The AD7792/AD7793 features a dual use data out ready DOUT/RDY output.
@ -36,9 +134,21 @@
* The DOUT/RDY output must also be wired to an interrupt capable GPIO.
*/
#define AD7793_FLAG_HAS_CLKSEL BIT(0)
#define AD7793_FLAG_HAS_REFSEL BIT(1)
#define AD7793_FLAG_HAS_VBIAS BIT(2)
#define AD7793_HAS_EXITATION_CURRENT BIT(3)
#define AD7793_FLAG_HAS_GAIN BIT(4)
#define AD7793_FLAG_HAS_BUFFER BIT(5)
struct ad7793_chip_info {
unsigned int id;
const struct iio_chan_spec *channels;
unsigned int num_channels;
unsigned int flags;
const struct iio_info *iio_info;
const u16 *sample_freq_avail;
};
struct ad7793_state {
@ -59,6 +169,10 @@ enum ad7793_supported_device_ids {
ID_AD7793,
ID_AD7794,
ID_AD7795,
ID_AD7796,
ID_AD7797,
ID_AD7798,
ID_AD7799,
};
static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
@ -110,19 +224,52 @@ static int ad7793_calibrate_all(struct ad7793_state *st)
ARRAY_SIZE(ad7793_calib_arr));
}
static int ad7793_setup(struct iio_dev *indio_dev,
static int ad7793_check_platform_data(struct ad7793_state *st,
const struct ad7793_platform_data *pdata)
{
if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 ||
pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) &&
((pdata->exitation_current != AD7793_IX_10uA) &&
(pdata->exitation_current != AD7793_IX_210uA)))
return -EINVAL;
if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) &&
pdata->clock_src != AD7793_CLK_SRC_INT)
return -EINVAL;
if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) &&
pdata->refsel != AD7793_REFSEL_REFIN1)
return -EINVAL;
if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) &&
pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED)
return -EINVAL;
if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) &&
pdata->exitation_current != AD7793_IX_DISABLED)
return -EINVAL;
return 0;
}
static int ad7793_setup(struct iio_dev *indio_dev,
const struct ad7793_platform_data *pdata,
unsigned int vref_mv)
{
struct ad7793_state *st = iio_priv(indio_dev);
int i, ret = -1;
unsigned long long scale_uv;
u32 id;
ret = ad7793_check_platform_data(st, pdata);
if (ret)
return ret;
/* reset the serial interface */
ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret));
if (ret < 0)
goto out;
msleep(1); /* Wait for at least 500us */
usleep_range(500, 2000); /* Wait for at least 500us */
/* write/read test for device presence */
ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
@ -131,13 +278,32 @@ static int ad7793_setup(struct iio_dev *indio_dev,
id &= AD7793_ID_MASK;
if (!((id == AD7792_ID) || (id == AD7793_ID) || (id == AD7795_ID))) {
if (id != st->chip_info->id) {
dev_err(&st->sd.spi->dev, "device ID query failed\n");
goto out;
}
st->mode = pdata->mode;
st->conf = pdata->conf;
st->mode = AD7793_MODE_RATE(1);
st->conf = 0;
if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL)
st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src);
if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL)
st->conf |= AD7793_CONF_REFSEL(pdata->refsel);
if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)
st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage);
if (pdata->buffered || !(st->chip_info->flags & AD7793_FLAG_HAS_BUFFER))
st->conf |= AD7793_CONF_BUF;
if (pdata->boost_enable &&
(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS))
st->conf |= AD7793_CONF_BOOST;
if (pdata->burnout_current)
st->conf |= AD7793_CONF_BO_EN;
if (pdata->unipolar)
st->conf |= AD7793_CONF_UNIPOLAR;
if (!(st->chip_info->flags & AD7793_FLAG_HAS_GAIN))
st->conf |= AD7793_CONF_GAIN(7);
ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
if (ret)
@ -147,10 +313,13 @@ static int ad7793_setup(struct iio_dev *indio_dev,
if (ret)
goto out;
ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO,
sizeof(pdata->io), pdata->io);
if (ret)
goto out;
if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) {
ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1,
pdata->exitation_current |
(pdata->current_source_direction << 2));
if (ret)
goto out;
}
ret = ad7793_calibrate_all(st);
if (ret)
@ -158,7 +327,7 @@ static int ad7793_setup(struct iio_dev *indio_dev,
/* Populate available ADC input ranges */
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
scale_uv = ((u64)st->int_vref_mv * 100000000)
scale_uv = ((u64)vref_mv * 100000000)
>> (st->chip_info->channels[0].scan_type.realbits -
(!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
scale_uv >>= i;
@ -173,8 +342,11 @@ out:
return ret;
}
static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19,
17, 16, 12, 10, 8, 6, 4};
static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
33, 19, 17, 16, 12, 10, 8, 6, 4};
static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
33, 0, 17, 16, 12, 10, 8, 6, 4};
static ssize_t ad7793_read_frequency(struct device *dev,
struct device_attribute *attr,
@ -184,7 +356,7 @@ static ssize_t ad7793_read_frequency(struct device *dev,
struct ad7793_state *st = iio_priv(indio_dev);
return sprintf(buf, "%d\n",
sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
st->chip_info->sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
}
static ssize_t ad7793_write_frequency(struct device *dev,
@ -204,14 +376,17 @@ static ssize_t ad7793_write_frequency(struct device *dev,
}
mutex_unlock(&indio_dev->mlock);
ret = strict_strtol(buf, 10, &lval);
ret = kstrtol(buf, 10, &lval);
if (ret)
return ret;
if (lval == 0)
return -EINVAL;
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++)
if (lval == sample_freq_avail[i]) {
for (i = 0; i < 16; i++)
if (lval == st->chip_info->sample_freq_avail[i]) {
mutex_lock(&indio_dev->mlock);
st->mode &= ~AD7793_MODE_RATE(-1);
st->mode |= AD7793_MODE_RATE(i);
@ -231,6 +406,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797,
sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4");
static ssize_t ad7793_show_scale_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -262,6 +440,16 @@ static const struct attribute_group ad7793_attribute_group = {
.attrs = ad7793_attributes,
};
static struct attribute *ad7797_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
NULL
};
static const struct attribute_group ad7797_attribute_group = {
.attrs = ad7797_attributes,
};
static int ad7793_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@ -292,12 +480,12 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT_PLUS_NANO;
} else {
/* 1170mV / 2^23 * 6 */
scale_uv = (1170ULL * 100000000ULL * 6ULL);
scale_uv = (1170ULL * 1000000000ULL * 6ULL);
}
break;
case IIO_TEMP:
/* 1170mV / 0.81 mV/C / 2^23 */
scale_uv = 1444444444444ULL;
scale_uv = 1444444444444444ULL;
break;
default:
return -EINVAL;
@ -387,6 +575,15 @@ static const struct iio_info ad7793_info = {
.driver_module = THIS_MODULE,
};
static const struct iio_info ad7797_info = {
.read_raw = &ad7793_read_raw,
.write_raw = &ad7793_write_raw,
.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
.attrs = &ad7793_attribute_group,
.validate_trigger = ad_sd_validate_trigger,
.driver_module = THIS_MODULE,
};
#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
const struct iio_chan_spec _name##_channels[] = { \
AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
@ -412,41 +609,143 @@ const struct iio_chan_spec _name##_channels[] = { \
IIO_CHAN_SOFT_TIMESTAMP(9), \
}
#define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
const struct iio_chan_spec _name##_channels[] = { \
AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
IIO_CHAN_SOFT_TIMESTAMP(4), \
}
#define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
const struct iio_chan_spec _name##_channels[] = { \
AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
IIO_CHAN_SOFT_TIMESTAMP(5), \
}
static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
static DECLARE_AD7797_CHANNELS(ad7796, 16, 16);
static DECLARE_AD7797_CHANNELS(ad7797, 24, 32);
static DECLARE_AD7799_CHANNELS(ad7798, 16, 16);
static DECLARE_AD7799_CHANNELS(ad7799, 24, 32);
static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
[ID_AD7785] = {
.id = AD7785_ID,
.channels = ad7785_channels,
.num_channels = ARRAY_SIZE(ad7785_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL |
AD7793_FLAG_HAS_REFSEL |
AD7793_FLAG_HAS_VBIAS |
AD7793_HAS_EXITATION_CURRENT |
AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7792] = {
.id = AD7792_ID,
.channels = ad7792_channels,
.num_channels = ARRAY_SIZE(ad7792_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL |
AD7793_FLAG_HAS_REFSEL |
AD7793_FLAG_HAS_VBIAS |
AD7793_HAS_EXITATION_CURRENT |
AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7793] = {
.id = AD7793_ID,
.channels = ad7793_channels,
.num_channels = ARRAY_SIZE(ad7793_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL |
AD7793_FLAG_HAS_REFSEL |
AD7793_FLAG_HAS_VBIAS |
AD7793_HAS_EXITATION_CURRENT |
AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7794] = {
.id = AD7794_ID,
.channels = ad7794_channels,
.num_channels = ARRAY_SIZE(ad7794_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL |
AD7793_FLAG_HAS_REFSEL |
AD7793_FLAG_HAS_VBIAS |
AD7793_HAS_EXITATION_CURRENT |
AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7795] = {
.id = AD7795_ID,
.channels = ad7795_channels,
.num_channels = ARRAY_SIZE(ad7795_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL |
AD7793_FLAG_HAS_REFSEL |
AD7793_FLAG_HAS_VBIAS |
AD7793_HAS_EXITATION_CURRENT |
AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7796] = {
.id = AD7796_ID,
.channels = ad7796_channels,
.num_channels = ARRAY_SIZE(ad7796_channels),
.iio_info = &ad7797_info,
.sample_freq_avail = ad7797_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL,
},
[ID_AD7797] = {
.id = AD7797_ID,
.channels = ad7797_channels,
.num_channels = ARRAY_SIZE(ad7797_channels),
.iio_info = &ad7797_info,
.sample_freq_avail = ad7797_sample_freq_avail,
.flags = AD7793_FLAG_HAS_CLKSEL,
},
[ID_AD7798] = {
.id = AD7798_ID,
.channels = ad7798_channels,
.num_channels = ARRAY_SIZE(ad7798_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
[ID_AD7799] = {
.id = AD7799_ID,
.channels = ad7799_channels,
.num_channels = ARRAY_SIZE(ad7799_channels),
.iio_info = &ad7793_info,
.sample_freq_avail = ad7793_sample_freq_avail,
.flags = AD7793_FLAG_HAS_GAIN |
AD7793_FLAG_HAS_BUFFER,
},
};
static int __devinit ad7793_probe(struct spi_device *spi)
static int ad7793_probe(struct spi_device *spi)
{
const struct ad7793_platform_data *pdata = spi->dev.platform_data;
struct ad7793_state *st;
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
int ret, vref_mv = 0;
if (!pdata) {
dev_err(&spi->dev, "no platform data?\n");
@ -466,25 +765,31 @@ static int __devinit ad7793_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
st->reg = regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_device_free;
}
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
vref_mv = regulator_get_voltage(st->reg);
if (vref_mv < 0) {
ret = vref_mv;
goto error_disable_reg;
}
vref_mv /= 1000;
} else {
vref_mv = 1170; /* Build-in ref */
}
st->chip_info =
&ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
st->int_vref_mv = voltage_uv / 1000;
else
st->int_vref_mv = 1170; /* Build-in ref */
spi_set_drvdata(spi, indio_dev);
indio_dev->dev.parent = &spi->dev;
@ -492,13 +797,13 @@ static int __devinit ad7793_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = st->chip_info->channels;
indio_dev->num_channels = st->chip_info->num_channels;
indio_dev->info = &ad7793_info;
indio_dev->info = st->chip_info->iio_info;
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
goto error_disable_reg;
ret = ad7793_setup(indio_dev, pdata);
ret = ad7793_setup(indio_dev, pdata, vref_mv);
if (ret)
goto error_remove_trigger;
@ -511,26 +816,27 @@ static int __devinit ad7793_probe(struct spi_device *spi)
error_remove_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
if (!IS_ERR(st->reg))
if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_put(st->reg);
error_device_free:
iio_device_free(indio_dev);
return ret;
}
static int __devexit ad7793_remove(struct spi_device *spi)
static int ad7793_remove(struct spi_device *spi)
{
const struct ad7793_platform_data *pdata = spi->dev.platform_data;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7793_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
if (!IS_ERR(st->reg)) {
if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
regulator_disable(st->reg);
regulator_put(st->reg);
}
@ -546,6 +852,10 @@ static const struct spi_device_id ad7793_id[] = {
{"ad7793", ID_AD7793},
{"ad7794", ID_AD7794},
{"ad7795", ID_AD7795},
{"ad7796", ID_AD7796},
{"ad7797", ID_AD7797},
{"ad7798", ID_AD7798},
{"ad7799", ID_AD7799},
{}
};
MODULE_DEVICE_TABLE(spi, ad7793_id);
@ -556,7 +866,7 @@ static struct spi_driver ad7793_driver = {
.owner = THIS_MODULE,
},
.probe = ad7793_probe,
.remove = __devexit_p(ad7793_remove),
.remove = ad7793_remove,
.id_table = ad7793_id,
};
module_spi_driver(ad7793_driver);

View File

@ -14,13 +14,139 @@
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include "ad7887.h"
#include <linux/platform_data/ad7887.h>
#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
#define AD7887_DUAL (1 << 4) /* dual-channel mode */
#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
#define AD7887_PM_MODE1 (0) /* CS based shutdown */
#define AD7887_PM_MODE2 (1) /* full on */
#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
#define AD7887_PM_MODE4 (3) /* standby mode */
enum ad7887_channels {
AD7887_CH0,
AD7887_CH0_CH1,
AD7887_CH1,
};
#define RES_MASK(bits) ((1 << (bits)) - 1)
/**
* struct ad7887_chip_info - chip specifc information
* @int_vref_mv: the internal reference voltage
* @channel: channel specification
*/
struct ad7887_chip_info {
u16 int_vref_mv;
struct iio_chan_spec channel[3];
};
struct ad7887_state {
struct spi_device *spi;
const struct ad7887_chip_info *chip_info;
struct regulator *reg;
struct spi_transfer xfer[4];
struct spi_message msg[3];
struct spi_message *ring_msg;
unsigned char tx_cmd_buf[4];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
* Buffer needs to be large enough to hold two 16 bit samples and a
* 64 bit aligned 64 bit timestamp.
*/
unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
____cacheline_aligned;
};
enum ad7887_supported_device_ids {
ID_AD7887
};
static int ad7887_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
int ret;
ret = iio_sw_buffer_preenable(indio_dev);
if (ret < 0)
return ret;
/* We know this is a single long so can 'cheat' */
switch (*indio_dev->active_scan_mask) {
case (1 << 0):
st->ring_msg = &st->msg[AD7887_CH0];
break;
case (1 << 1):
st->ring_msg = &st->msg[AD7887_CH1];
/* Dummy read: push CH1 setting down to hardware */
spi_sync(st->spi, st->ring_msg);
break;
case ((1 << 1) | (1 << 0)):
st->ring_msg = &st->msg[AD7887_CH0_CH1];
break;
}
return 0;
}
static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
/* dummy read: restore default CH0 settin */
return spi_sync(st->spi, &st->msg[AD7887_CH0]);
}
/**
* ad7887_trigger_handler() bh of trigger launched polling to ring buffer
*
* Currently there is no option in this driver to disable the saving of
* timestamps within the ring.
**/
static irqreturn_t ad7887_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7887_state *st = iio_priv(indio_dev);
s64 time_ns;
int b_sent;
b_sent = spi_sync(st->spi, st->ring_msg);
if (b_sent)
goto done;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
iio_push_to_buffers(indio_dev, st->data);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
.preenable = &ad7887_ring_preenable,
.postenable = &iio_triggered_buffer_postenable,
.predisable = &iio_triggered_buffer_predisable,
.postdisable = &ad7887_ring_postdisable,
};
static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
{
@ -39,7 +165,6 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7887_state *st = iio_priv(indio_dev);
unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@ -52,15 +177,22 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
RES_MASK(st->chip_info->channel[0].scan_type.realbits);
*val = ret >> chan->scan_type.shift;
*val &= RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
scale_uv = (st->int_vref_mv * 1000)
>> st->chip_info->channel[0].scan_type.realbits;
*val = scale_uv/1000;
*val2 = (scale_uv%1000)*1000;
return IIO_VAL_INT_PLUS_MICRO;
if (st->reg) {
*val = regulator_get_voltage(st->reg);
if (*val < 0)
return *val;
*val /= 1000;
} else {
*val = st->chip_info->int_vref_mv;
}
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
}
return -EINVAL;
}
@ -105,21 +237,25 @@ static int __devinit ad7887_probe(struct spi_device *spi)
{
struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st;
int ret, voltage_uv = 0;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
uint8_t mode;
int ret;
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
if (!pdata || !pdata->use_onchip_ref) {
st->reg = regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free;
}
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
}
st->chip_info =
@ -136,9 +272,13 @@ static int __devinit ad7887_probe(struct spi_device *spi)
/* Setup default message */
st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 |
((pdata && pdata->use_onchip_ref) ?
0 : AD7887_REF_DIS);
mode = AD7887_PM_MODE4;
if (!pdata || !pdata->use_onchip_ref)
mode |= AD7887_REF_DIS;
if (pdata && pdata->en_dual)
mode |= AD7887_DUAL;
st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode;
st->xfer[0].rx_buf = &st->data[0];
st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
@ -148,56 +288,36 @@ static int __devinit ad7887_probe(struct spi_device *spi)
spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]);
if (pdata && pdata->en_dual) {
st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS;
st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL |
AD7887_REF_DIS | AD7887_PM_MODE4;
st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL |
AD7887_REF_DIS | AD7887_PM_MODE4;
st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL |
AD7887_REF_DIS | AD7887_PM_MODE4;
st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode;
st->xfer[1].rx_buf = &st->data[0];
st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
st->xfer[1].len = 2;
st->xfer[2].rx_buf = &st->data[2];
st->xfer[2].tx_buf = &st->tx_cmd_buf[4];
st->xfer[2].tx_buf = &st->tx_cmd_buf[0];
st->xfer[2].len = 2;
spi_message_init(&st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]);
st->xfer[3].rx_buf = &st->data[0];
st->xfer[3].tx_buf = &st->tx_cmd_buf[6];
st->xfer[3].rx_buf = &st->data[2];
st->xfer[3].tx_buf = &st->tx_cmd_buf[2];
st->xfer[3].len = 2;
spi_message_init(&st->msg[AD7887_CH1]);
spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
st->int_vref_mv = voltage_uv / 1000;
else
dev_warn(&spi->dev, "reference voltage unspecified\n");
indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = 3;
} else {
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (pdata && pdata->use_onchip_ref)
st->int_vref_mv = st->chip_info->int_vref_mv;
else
dev_warn(&spi->dev, "reference voltage unspecified\n");
indio_dev->channels = &st->chip_info->channel[1];
indio_dev->num_channels = 2;
}
ret = ad7887_register_ring_funcs_and_init(indio_dev);
ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
&ad7887_trigger_handler, &ad7887_ring_setup_ops);
if (ret)
goto error_disable_reg;
@ -207,13 +327,14 @@ static int __devinit ad7887_probe(struct spi_device *spi)
return 0;
error_unregister_ring:
ad7887_ring_cleanup(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
if (!IS_ERR(st->reg))
if (st->reg)
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
if (st->reg)
regulator_put(st->reg);
error_free:
iio_device_free(indio_dev);
return ret;
@ -225,8 +346,8 @@ static int __devexit ad7887_remove(struct spi_device *spi)
struct ad7887_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
ad7887_ring_cleanup(indio_dev);
if (!IS_ERR(st->reg)) {
iio_triggered_buffer_cleanup(indio_dev);
if (st->reg) {
regulator_disable(st->reg);
regulator_put(st->reg);
}

View File

@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
break;
}
iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data);
iio_push_to_buffers(indio_dev, (uint8_t *)data);
iio_trigger_notify_done(indio_dev->trig);
sigma_delta->irq_dis = false;

View File

@ -46,7 +46,6 @@ struct at91_adc_state {
struct clk *clk;
bool done;
int irq;
bool irq_enabled;
u16 last_value;
struct mutex lock;
u8 num_channels;
@ -66,7 +65,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *idev = pf->indio_dev;
struct at91_adc_state *st = iio_priv(idev);
struct iio_buffer *buffer = idev->buffer;
int i, j = 0;
for (i = 0; i < idev->masklength; i++) {
@ -82,10 +80,9 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
*timestamp = pf->timestamp;
}
buffer->access->store_to(buffer, (u8 *)st->buffer);
iio_push_to_buffers(indio_dev, (u8 *)st->buffer);
iio_trigger_notify_done(idev->trig);
st->irq_enabled = true;
/* Needed to ACK the DRDY interruption */
at91_adc_readl(st, AT91_ADC_LCDR);
@ -106,7 +103,6 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
if (iio_buffer_enabled(idev)) {
disable_irq_nosync(irq);
st->irq_enabled = false;
iio_trigger_poll(idev->trig, iio_get_time_ns());
} else {
st->last_value = at91_adc_readl(st, AT91_ADC_LCDR);

View File

@ -37,8 +37,151 @@
#include <linux/iio/events.h>
#include <linux/iio/buffer.h>
#include <linux/iio/driver.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger_consumer.h>
#include "max1363.h"
#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
/* There is a fair bit more defined here than currently
* used, but the intention is to support everything these
* chips do in the long run */
/* see data sheets */
/* max1363 and max1236, max1237, max1238, max1239 */
#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00
#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20
#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40
#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60
#define MAX1363_SETUP_POWER_UP_INT_REF 0x10
#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00
/* think about includeing max11600 etc - more settings */
#define MAX1363_SETUP_EXT_CLOCK 0x08
#define MAX1363_SETUP_INT_CLOCK 0x00
#define MAX1363_SETUP_UNIPOLAR 0x00
#define MAX1363_SETUP_BIPOLAR 0x04
#define MAX1363_SETUP_RESET 0x00
#define MAX1363_SETUP_NORESET 0x02
/* max1363 only - though don't care on others.
* For now monitor modes are not implemented as the relevant
* line is not connected on my test board.
* The definitions are here as I intend to add this soon.
*/
#define MAX1363_SETUP_MONITOR_SETUP 0x01
/* Specific to the max1363 */
#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
#define MAX1363_MON_INT_ENABLE 0x01
/* defined for readability reasons */
/* All chips */
#define MAX1363_CONFIG_BYTE(a) ((a))
#define MAX1363_CONFIG_SE 0x01
#define MAX1363_CONFIG_DE 0x00
#define MAX1363_CONFIG_SCAN_TO_CS 0x00
#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20
#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40
#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60
/* max123{6-9} only */
#define MAX1236_SCAN_MID_TO_CHANNEL 0x40
/* max1363 only - merely part of channel selects or don't care for others*/
#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
/* max1363 strictly 0x06 - but doesn't matter */
#define MAX1363_CHANNEL_SEL_MASK 0x1E
#define MAX1363_SCAN_MASK 0x60
#define MAX1363_SE_DE_MASK 0x01
#define MAX1363_MAX_CHANNELS 25
/**
* struct max1363_mode - scan mode information
* @conf: The corresponding value of the configuration register
* @modemask: Bit mask corresponding to channels enabled in this mode
*/
struct max1363_mode {
int8_t conf;
DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
};
/* This must be maintained along side the max1363_mode_table in max1363_core */
enum max1363_modes {
/* Single read of a single channel */
_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
/* Differential single read */
d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
/* Scan to channel and mid to channel where overlapping */
s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
s6to7, s0to7, s6to8, s0to8, s6to9,
s0to9, s6to10, s0to10, s6to11, s0to11,
/* Differential scan to channel and mid to channel where overlapping */
d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
d7m6to11m10, d1m0to11m10,
};
/**
* struct max1363_chip_info - chip specifc information
* @info: iio core function callbacks structure
* @channels: channel specification
* @num_channels: number of channels
* @mode_list: array of available scan modes
* @default_mode: the scan mode in which the chip starts up
* @int_vref_mv: the internal reference voltage
* @num_channels: number of channels
* @bits: accuracy of the adc in bits
*/
struct max1363_chip_info {
const struct iio_info *info;
const struct iio_chan_spec *channels;
int num_channels;
const enum max1363_modes *mode_list;
enum max1363_modes default_mode;
u16 int_vref_mv;
u8 num_modes;
u8 bits;
};
/**
* struct max1363_state - driver instance specific data
* @client: i2c_client
* @setupbyte: cache of current device setup byte
* @configbyte: cache of current device config byte
* @chip_info: chip model specific constants, available modes etc
* @current_mode: the scan mode of this chip
* @requestedmask: a valid requested set of channels
* @reg: supply regulator
* @monitor_on: whether monitor mode is enabled
* @monitor_speed: parameter corresponding to device monitor speed setting
* @mask_high: bitmask for enabled high thresholds
* @mask_low: bitmask for enabled low thresholds
* @thresh_high: high threshold values
* @thresh_low: low threshold values
*/
struct max1363_state {
struct i2c_client *client;
u8 setupbyte;
u8 configbyte;
const struct max1363_chip_info *chip_info;
const struct max1363_mode *current_mode;
u32 requestedmask;
struct regulator *reg;
/* Using monitor modes and buffer at the same time is
currently not supported */
bool monitor_on;
unsigned int monitor_speed:3;
u8 mask_high;
u8 mask_low;
/* 4x unipolar first then the fours bipolar ones */
s16 thresh_high[8];
s16 thresh_low[8];
};
#define MAX1363_MODE_SINGLE(_num, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
@ -148,7 +291,7 @@ static const struct max1363_mode max1363_mode_table[] = {
MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000),
};
const struct max1363_mode
static const struct max1363_mode
*max1363_match_mode(const unsigned long *mask,
const struct max1363_chip_info *ci)
{
@ -172,7 +315,7 @@ static int max1363_write_basic_config(struct i2c_client *client,
return i2c_master_send(client, tx_buf, 2);
}
int max1363_set_scan_mode(struct max1363_state *st)
static int max1363_set_scan_mode(struct max1363_state *st)
{
st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
| MAX1363_SCAN_MASK
@ -622,9 +765,9 @@ static int max1363_read_event_config(struct iio_dev *indio_dev,
u64 event_code)
{
struct max1363_state *st = iio_priv(indio_dev);
int val;
int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
mutex_lock(&indio_dev->mlock);
if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
val = (1 << number) & st->mask_low;
@ -644,7 +787,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
const long *modemask;
if (!enabled) {
/* transition to ring capture is not currently supported */
/* transition to buffered capture is not currently supported */
st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP;
st->configbyte &= ~MAX1363_SCAN_MASK;
st->monitor_on = false;
@ -826,8 +969,21 @@ static struct attribute_group max1363_event_attribute_group = {
.name = "events",
};
#define MAX1363_EVENT_FUNCS \
static int max1363_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct max1363_state *st = iio_priv(indio_dev);
/*
* Need to figure out the current mode based upon the requested
* scan mask in iio_dev
*/
st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
if (!st->current_mode)
return -EINVAL;
max1363_set_scan_mode(st);
return 0;
}
static const struct iio_info max1238_info = {
.read_raw = &max1363_read_raw,
@ -1230,8 +1386,6 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
},
};
static int max1363_initial_setup(struct max1363_state *st)
{
st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
@ -1269,34 +1423,137 @@ static int __devinit max1363_alloc_scan_masks(struct iio_dev *indio_dev)
return 0;
}
static irqreturn_t max1363_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct max1363_state *st = iio_priv(indio_dev);
s64 time_ns;
__u8 *rxbuf;
int b_sent;
size_t d_size;
unsigned long numvals = bitmap_weight(st->current_mode->modemask,
MAX1363_MAX_CHANNELS);
/* Ensure the timestamp is 8 byte aligned */
if (st->chip_info->bits != 8)
d_size = numvals*2;
else
d_size = numvals;
if (indio_dev->scan_timestamp) {
d_size += sizeof(s64);
if (d_size % sizeof(s64))
d_size += sizeof(s64) - (d_size % sizeof(s64));
}
/* Monitor mode prevents reading. Whilst not currently implemented
* might as well have this test in here in the meantime as it does
* no harm.
*/
if (numvals == 0)
goto done;
rxbuf = kmalloc(d_size, GFP_KERNEL);
if (rxbuf == NULL)
goto done;
if (st->chip_info->bits != 8)
b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
else
b_sent = i2c_master_recv(st->client, rxbuf, numvals);
if (b_sent < 0)
goto done_free;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
iio_push_to_buffers(indio_dev, rxbuf);
done_free:
kfree(rxbuf);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = {
.postenable = &iio_triggered_buffer_postenable,
.preenable = &iio_sw_buffer_preenable,
.predisable = &iio_triggered_buffer_predisable,
};
static int max1363_register_buffered_funcs_and_init(struct iio_dev *indio_dev)
{
struct max1363_state *st = iio_priv(indio_dev);
int ret = 0;
indio_dev->buffer = iio_kfifo_allocate(indio_dev);
if (!indio_dev->buffer) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
&max1363_trigger_handler,
IRQF_ONESHOT,
indio_dev,
"%s_consumer%d",
st->client->name,
indio_dev->id);
if (indio_dev->pollfunc == NULL) {
ret = -ENOMEM;
goto error_deallocate_sw_rb;
}
/* Buffer functions - here trigger setup related */
indio_dev->setup_ops = &max1363_buffered_setup_ops;
/* Flag that polled buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
return 0;
error_deallocate_sw_rb:
iio_kfifo_free(indio_dev->buffer);
error_ret:
return ret;
}
static void max1363_buffer_cleanup(struct iio_dev *indio_dev)
{
/* ensure that the trigger has been detached */
iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_kfifo_free(indio_dev->buffer);
}
static int __devinit max1363_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
struct max1363_state *st;
struct iio_dev *indio_dev;
struct regulator *reg;
reg = regulator_get(&client->dev, "vcc");
if (IS_ERR(reg)) {
ret = PTR_ERR(reg);
goto error_out;
}
ret = regulator_enable(reg);
if (ret)
goto error_put_reg;
indio_dev = iio_device_alloc(sizeof(struct max1363_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_disable_reg;
goto error_out;
}
ret = iio_map_array_register(indio_dev, client->dev.platform_data);
if (ret < 0)
goto error_free_device;
st = iio_priv(indio_dev);
st->reg = reg;
st->reg = regulator_get(&client->dev, "vcc");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_unregister_map;
}
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
/* this is only used for device removal purposes */
i2c_set_clientdata(client, indio_dev);
@ -1305,7 +1562,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
ret = max1363_alloc_scan_masks(indio_dev);
if (ret)
goto error_unregister_map;
goto error_disable_reg;
/* Estabilish that the iio_dev is a child of the i2c device */
indio_dev->dev.parent = &client->dev;
@ -1320,7 +1577,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
if (ret < 0)
goto error_free_available_scan_masks;
ret = max1363_register_ring_funcs_and_init(indio_dev);
ret = max1363_register_buffered_funcs_and_init(indio_dev);
if (ret)
goto error_free_available_scan_masks;
@ -1328,7 +1585,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
st->chip_info->channels,
st->chip_info->num_channels);
if (ret)
goto error_cleanup_ring;
goto error_cleanup_buffer;
if (client->irq) {
ret = request_threaded_irq(st->client->irq,
@ -1339,7 +1596,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
indio_dev);
if (ret)
goto error_uninit_ring;
goto error_uninit_buffer;
}
ret = iio_device_register(indio_dev);
@ -1349,20 +1606,20 @@ static int __devinit max1363_probe(struct i2c_client *client,
return 0;
error_free_irq:
free_irq(st->client->irq, indio_dev);
error_uninit_ring:
error_uninit_buffer:
iio_buffer_unregister(indio_dev);
error_cleanup_ring:
max1363_ring_cleanup(indio_dev);
error_cleanup_buffer:
max1363_buffer_cleanup(indio_dev);
error_free_available_scan_masks:
kfree(indio_dev->available_scan_masks);
error_unregister_map:
iio_map_array_unregister(indio_dev, client->dev.platform_data);
error_disable_reg:
regulator_disable(st->reg);
error_put_reg:
regulator_put(st->reg);
error_free_device:
iio_device_free(indio_dev);
error_disable_reg:
regulator_disable(reg);
error_put_reg:
regulator_put(reg);
error_out:
return ret;
}
@ -1371,17 +1628,16 @@ static int __devexit max1363_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct max1363_state *st = iio_priv(indio_dev);
struct regulator *reg = st->reg;
iio_device_unregister(indio_dev);
if (client->irq)
free_irq(st->client->irq, indio_dev);
iio_buffer_unregister(indio_dev);
max1363_ring_cleanup(indio_dev);
max1363_buffer_cleanup(indio_dev);
kfree(indio_dev->available_scan_masks);
if (!IS_ERR(reg)) {
regulator_disable(reg);
regulator_put(reg);
if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_map_array_unregister(indio_dev, client->dev.platform_data);
iio_device_free(indio_dev);

View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 2012 Avionic Design GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/regulator/consumer.h>
struct adc081c {
struct i2c_client *i2c;
struct regulator *ref;
};
#define REG_CONV_RES 0x00
static int adc081c_read_raw(struct iio_dev *iio,
struct iio_chan_spec const *channel, int *value,
int *shift, long mask)
{
struct adc081c *adc = iio_priv(iio);
int err;
switch (mask) {
case IIO_CHAN_INFO_RAW:
err = i2c_smbus_read_word_swapped(adc->i2c, REG_CONV_RES);
if (err < 0)
return err;
*value = (err >> 4) & 0xff;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
err = regulator_get_voltage(adc->ref);
if (err < 0)
return err;
*value = err / 1000;
*shift = 8;
return IIO_VAL_FRACTIONAL_LOG2;
default:
break;
}
return -EINVAL;
}
static const struct iio_chan_spec adc081c_channel = {
.type = IIO_VOLTAGE,
.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
IIO_CHAN_INFO_RAW_SEPARATE_BIT,
};
static const struct iio_info adc081c_info = {
.read_raw = adc081c_read_raw,
.driver_module = THIS_MODULE,
};
static int adc081c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *iio;
struct adc081c *adc;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
iio = iio_device_alloc(sizeof(*adc));
if (!iio)
return -ENOMEM;
adc = iio_priv(iio);
adc->i2c = client;
adc->ref = regulator_get(&client->dev, "vref");
if (IS_ERR(adc->ref)) {
err = PTR_ERR(adc->ref);
goto iio_free;
}
err = regulator_enable(adc->ref);
if (err < 0)
goto regulator_put;
iio->dev.parent = &client->dev;
iio->name = dev_name(&client->dev);
iio->modes = INDIO_DIRECT_MODE;
iio->info = &adc081c_info;
iio->channels = &adc081c_channel;
iio->num_channels = 1;
err = iio_device_register(iio);
if (err < 0)
goto regulator_disable;
i2c_set_clientdata(client, iio);
return 0;
regulator_disable:
regulator_disable(adc->ref);
regulator_put:
regulator_put(adc->ref);
iio_free:
iio_device_free(iio);
return err;
}
static int adc081c_remove(struct i2c_client *client)
{
struct iio_dev *iio = i2c_get_clientdata(client);
struct adc081c *adc = iio_priv(iio);
iio_device_unregister(iio);
regulator_disable(adc->ref);
regulator_put(adc->ref);
iio_device_free(iio);
return 0;
}
static const struct i2c_device_id adc081c_id[] = {
{ "adc081c", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adc081c_id);
#ifdef CONFIG_OF
static const struct of_device_id adc081c_of_match[] = {
{ .compatible = "ti,adc081c" },
{ }
};
MODULE_DEVICE_TABLE(of, adc081c_of_match);
#endif
static struct i2c_driver adc081c_driver = {
.driver = {
.name = "adc081c",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(adc081c_of_match),
},
.probe = adc081c_probe,
.remove = adc081c_remove,
.id_table = adc081c_id,
};
module_i2c_driver(adc081c_driver);
MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
MODULE_DESCRIPTION("Texas Instruments ADC081C021/027 driver");
MODULE_LICENSE("GPL v2");

113
drivers/iio/buffer_cb.c Normal file
View File

@ -0,0 +1,113 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/iio/buffer.h>
#include <linux/iio/consumer.h>
struct iio_cb_buffer {
struct iio_buffer buffer;
int (*cb)(u8 *data, void *private);
void *private;
struct iio_channel *channels;
};
static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
{
struct iio_cb_buffer *cb_buff = container_of(buffer,
struct iio_cb_buffer,
buffer);
return cb_buff->cb(data, cb_buff->private);
}
static struct iio_buffer_access_funcs iio_cb_access = {
.store_to = &iio_buffer_cb_store_to,
};
struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
int (*cb)(u8 *data,
void *private),
void *private)
{
int ret;
struct iio_cb_buffer *cb_buff;
struct iio_dev *indio_dev;
struct iio_channel *chan;
cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
if (cb_buff == NULL) {
ret = -ENOMEM;
goto error_ret;
}
cb_buff->private = private;
cb_buff->cb = cb;
cb_buff->buffer.access = &iio_cb_access;
INIT_LIST_HEAD(&cb_buff->buffer.demux_list);
cb_buff->channels = iio_channel_get_all(name);
if (IS_ERR(cb_buff->channels)) {
ret = PTR_ERR(cb_buff->channels);
goto error_free_cb_buff;
}
indio_dev = cb_buff->channels[0].indio_dev;
cb_buff->buffer.scan_mask
= kcalloc(BITS_TO_LONGS(indio_dev->masklength), sizeof(long),
GFP_KERNEL);
if (cb_buff->buffer.scan_mask == NULL) {
ret = -ENOMEM;
goto error_release_channels;
}
chan = &cb_buff->channels[0];
while (chan->indio_dev) {
if (chan->indio_dev != indio_dev) {
ret = -EINVAL;
goto error_release_channels;
}
set_bit(chan->channel->scan_index,
cb_buff->buffer.scan_mask);
chan++;
}
return cb_buff;
error_release_channels:
iio_channel_release_all(cb_buff->channels);
error_free_cb_buff:
kfree(cb_buff);
error_ret:
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
{
return iio_update_buffers(cb_buff->channels[0].indio_dev,
&cb_buff->buffer,
NULL);
}
EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);
void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)
{
iio_update_buffers(cb_buff->channels[0].indio_dev,
NULL,
&cb_buff->buffer);
}
EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
{
iio_channel_release_all(cb_buff->channels);
kfree(cb_buff);
}
EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
struct iio_channel
*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer)
{
return cb_buffer->channels;
}
EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);

View File

@ -15,7 +15,7 @@ config HID_SENSOR_IIO_COMMON
attributes.
config HID_SENSOR_ENUM_BASE_QUIRKS
tristate "ENUM base quirks for HID Sensor IIO drivers"
bool "ENUM base quirks for HID Sensor IIO drivers"
depends on HID_SENSOR_IIO_COMMON
help
Say yes here to build support for sensor hub FW using

View File

@ -36,10 +36,8 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
int state_val;
state_val = state ? 1 : 0;
#if (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS) || \
(defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS_MODULE)
++state_val;
#endif
if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS))
++state_val;
st->data_ready = state;
sensor_hub_set_feature(st->hsdev, st->power_state.report_id,
st->power_state.index,

View File

@ -67,6 +67,16 @@ config AD5446
To compile this driver as a module, choose M here: the
module will be called ad5446.
config AD5449
tristate "Analog Device AD5449 and similar DACs driver"
depends on SPI_MASTER
help
Say yes here to build support for Analog Devices AD5415, AD5426, AD5429,
AD5432, AD5439, AD5443, AD5449 Digital to Analog Converters.
To compile this driver as a module, choose M here: the
module will be called ad5449.
config AD5504
tristate "Analog Devices AD5504/AD5501 DAC SPI driver"
depends on SPI
@ -122,7 +132,7 @@ config AD5686
config MAX517
tristate "Maxim MAX517/518/519 DAC driver"
depends on I2C && EXPERIMENTAL
depends on I2C
help
If you say yes here you get support for the Maxim chips MAX517,
MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs).

View File

@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
obj-$(CONFIG_AD5064) += ad5064.o
obj-$(CONFIG_AD5504) += ad5504.o
obj-$(CONFIG_AD5446) += ad5446.o
obj-$(CONFIG_AD5449) += ad5449.o
obj-$(CONFIG_AD5755) += ad5755.o
obj-$(CONFIG_AD5764) += ad5764.o
obj-$(CONFIG_AD5791) += ad5791.o

376
drivers/iio/dac/ad5449.c Normal file
View File

@ -0,0 +1,376 @@
/*
* AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog
* Converter driver.
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/platform_data/ad5449.h>
#define AD5449_MAX_CHANNELS 2
#define AD5449_MAX_VREFS 2
#define AD5449_CMD_NOOP 0x0
#define AD5449_CMD_LOAD_AND_UPDATE(x) (0x1 + (x) * 3)
#define AD5449_CMD_READ(x) (0x2 + (x) * 3)
#define AD5449_CMD_LOAD(x) (0x3 + (x) * 3)
#define AD5449_CMD_CTRL 13
#define AD5449_CTRL_SDO_OFFSET 10
#define AD5449_CTRL_DAISY_CHAIN BIT(9)
#define AD5449_CTRL_HCLR_TO_MIDSCALE BIT(8)
#define AD5449_CTRL_SAMPLE_RISING BIT(7)
/**
* struct ad5449_chip_info - chip specific information
* @channels: Channel specification
* @num_channels: Number of channels
* @has_ctrl: Chip has a control register
*/
struct ad5449_chip_info {
const struct iio_chan_spec *channels;
unsigned int num_channels;
bool has_ctrl;
};
/**
* struct ad5449 - driver instance specific data
* @spi: the SPI device for this driver instance
* @chip_info: chip model specific constants, available modes etc
* @vref_reg: vref supply regulators
* @has_sdo: whether the SDO line is connected
* @dac_cache: Cache for the DAC values
* @data: spi transfer buffers
*/
struct ad5449 {
struct spi_device *spi;
const struct ad5449_chip_info *chip_info;
struct regulator_bulk_data vref_reg[AD5449_MAX_VREFS];
bool has_sdo;
uint16_t dac_cache[AD5449_MAX_CHANNELS];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
__be16 data[2] ____cacheline_aligned;
};
enum ad5449_type {
ID_AD5426,
ID_AD5429,
ID_AD5432,
ID_AD5439,
ID_AD5443,
ID_AD5449,
};
static int ad5449_write(struct iio_dev *indio_dev, unsigned int addr,
unsigned int val)
{
struct ad5449 *st = iio_priv(indio_dev);
int ret;
mutex_lock(&indio_dev->mlock);
st->data[0] = cpu_to_be16((addr << 12) | val);
ret = spi_write(st->spi, st->data, 2);
mutex_unlock(&indio_dev->mlock);
return ret;
}
static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
unsigned int *val)
{
struct ad5449 *st = iio_priv(indio_dev);
int ret;
struct spi_message msg;
struct spi_transfer t[] = {
{
.tx_buf = &st->data[0],
.len = 2,
.cs_change = 1,
}, {
.tx_buf = &st->data[1],
.rx_buf = &st->data[1],
.len = 2,
},
};
spi_message_init(&msg);
spi_message_add_tail(&t[0], &msg);
spi_message_add_tail(&t[1], &msg);
mutex_lock(&indio_dev->mlock);
st->data[0] = cpu_to_be16(addr << 12);
st->data[1] = cpu_to_be16(AD5449_CMD_NOOP);
ret = spi_sync(st->spi, &msg);
if (ret < 0)
goto out_unlock;
*val = be16_to_cpu(st->data[1]);
out_unlock:
mutex_unlock(&indio_dev->mlock);
return ret;
}
static int ad5449_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long info)
{
struct ad5449 *st = iio_priv(indio_dev);
struct regulator_bulk_data *reg;
int scale_uv;
int ret;
switch (info) {
case IIO_CHAN_INFO_RAW:
if (st->has_sdo) {
ret = ad5449_read(indio_dev,
AD5449_CMD_READ(chan->address), val);
if (ret)
return ret;
*val &= 0xfff;
} else {
*val = st->dac_cache[chan->address];
}
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
reg = &st->vref_reg[chan->channel];
scale_uv = regulator_get_voltage(reg->consumer);
if (scale_uv < 0)
return scale_uv;
*val = scale_uv / 1000;
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
default:
break;
}
return -EINVAL;
}
static int ad5449_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val, int val2, long info)
{
struct ad5449 *st = iio_priv(indio_dev);
int ret;
switch (info) {
case IIO_CHAN_INFO_RAW:
if (val < 0 || val >= (1 << chan->scan_type.realbits))
return -EINVAL;
ret = ad5449_write(indio_dev,
AD5449_CMD_LOAD_AND_UPDATE(chan->address),
val << chan->scan_type.shift);
if (ret == 0)
st->dac_cache[chan->address] = val;
break;
default:
ret = -EINVAL;
}
return ret;
}
static const struct iio_info ad5449_info = {
.read_raw = ad5449_read_raw,
.write_raw = ad5449_write_raw,
.driver_module = THIS_MODULE,
};
#define AD5449_CHANNEL(chan, bits) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.output = 1, \
.channel = (chan), \
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
.address = (chan), \
.scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \
}
#define DECLARE_AD5449_CHANNELS(name, bits) \
const struct iio_chan_spec name[] = { \
AD5449_CHANNEL(0, bits), \
AD5449_CHANNEL(1, bits), \
}
static DECLARE_AD5449_CHANNELS(ad5429_channels, 8);
static DECLARE_AD5449_CHANNELS(ad5439_channels, 10);
static DECLARE_AD5449_CHANNELS(ad5449_channels, 12);
static const struct ad5449_chip_info ad5449_chip_info[] = {
[ID_AD5426] = {
.channels = ad5429_channels,
.num_channels = 1,
.has_ctrl = false,
},
[ID_AD5429] = {
.channels = ad5429_channels,
.num_channels = 2,
.has_ctrl = true,
},
[ID_AD5432] = {
.channels = ad5439_channels,
.num_channels = 1,
.has_ctrl = false,
},
[ID_AD5439] = {
.channels = ad5439_channels,
.num_channels = 2,
.has_ctrl = true,
},
[ID_AD5443] = {
.channels = ad5449_channels,
.num_channels = 1,
.has_ctrl = false,
},
[ID_AD5449] = {
.channels = ad5449_channels,
.num_channels = 2,
.has_ctrl = true,
},
};
static const char *ad5449_vref_name(struct ad5449 *st, int n)
{
if (st->chip_info->num_channels == 1)
return "VREF";
if (n == 0)
return "VREFA";
else
return "VREFB";
}
static int __devinit ad5449_spi_probe(struct spi_device *spi)
{
struct ad5449_platform_data *pdata = spi->dev.platform_data;
const struct spi_device_id *id = spi_get_device_id(spi);
struct iio_dev *indio_dev;
struct ad5449 *st;
unsigned int i;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
st->chip_info = &ad5449_chip_info[id->driver_data];
st->spi = spi;
for (i = 0; i < st->chip_info->num_channels; ++i)
st->vref_reg[i].supply = ad5449_vref_name(st, i);
ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
st->vref_reg);
if (ret)
goto error_free;
ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg);
if (ret)
goto error_free_reg;
indio_dev->dev.parent = &spi->dev;
indio_dev->name = id->name;
indio_dev->info = &ad5449_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = st->chip_info->channels;
indio_dev->num_channels = st->chip_info->num_channels;
if (st->chip_info->has_ctrl) {
unsigned int ctrl = 0x00;
if (pdata) {
if (pdata->hardware_clear_to_midscale)
ctrl |= AD5449_CTRL_HCLR_TO_MIDSCALE;
ctrl |= pdata->sdo_mode << AD5449_CTRL_SDO_OFFSET;
st->has_sdo = pdata->sdo_mode != AD5449_SDO_DISABLED;
} else {
st->has_sdo = true;
}
ad5449_write(indio_dev, AD5449_CMD_CTRL, ctrl);
}
ret = iio_device_register(indio_dev);
if (ret)
goto error_disable_reg;
return 0;
error_disable_reg:
regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
error_free_reg:
regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
static int __devexit ad5449_spi_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad5449 *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
iio_device_free(indio_dev);
return 0;
}
static const struct spi_device_id ad5449_spi_ids[] = {
{ "ad5415", ID_AD5449 },
{ "ad5426", ID_AD5426 },
{ "ad5429", ID_AD5429 },
{ "ad5432", ID_AD5432 },
{ "ad5439", ID_AD5439 },
{ "ad5443", ID_AD5443 },
{ "ad5449", ID_AD5449 },
{}
};
MODULE_DEVICE_TABLE(spi, ad5449_spi_ids);
static struct spi_driver ad5449_spi_driver = {
.driver = {
.name = "ad5449",
.owner = THIS_MODULE,
},
.probe = ad5449_spi_probe,
.remove = __devexit_p(ad5449_spi_remove),
.id_table = ad5449_spi_ids,
};
module_spi_driver(ad5449_spi_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Analog Devices AD5449 and similar DACs");
MODULE_LICENSE("GPL v2");

View File

@ -188,7 +188,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
if (ret)
return ret;
if (readin == true)
if (readin)
st->pwr_down_mask |= (0x3 << (chan->channel * 2));
else
st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));

View File

@ -3,6 +3,15 @@
#
menu "Digital gyroscope sensors"
config ADIS16136
tristate "Analog devices ADIS16136 and similar gyroscopes driver"
depends on SPI_MASTER
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
ADIS16136 gyroscope devices.
config HID_SENSOR_GYRO_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER

View File

@ -2,4 +2,5 @@
# Makefile for industrial I/O gyroscope sensor drivers
#
obj-$(CONFIG_ADIS16136) += adis16136.o
obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o

View File

@ -0,0 +1,580 @@
/*
* ADIS16133/ADIS16135/ADIS16136 gyroscope driver
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/imu/adis.h>
#include <linux/debugfs.h>
#define ADIS16136_REG_FLASH_CNT 0x00
#define ADIS16136_REG_TEMP_OUT 0x02
#define ADIS16136_REG_GYRO_OUT2 0x04
#define ADIS16136_REG_GYRO_OUT 0x06
#define ADIS16136_REG_GYRO_OFF2 0x08
#define ADIS16136_REG_GYRO_OFF 0x0A
#define ADIS16136_REG_ALM_MAG1 0x10
#define ADIS16136_REG_ALM_MAG2 0x12
#define ADIS16136_REG_ALM_SAMPL1 0x14
#define ADIS16136_REG_ALM_SAMPL2 0x16
#define ADIS16136_REG_ALM_CTRL 0x18
#define ADIS16136_REG_GPIO_CTRL 0x1A
#define ADIS16136_REG_MSC_CTRL 0x1C
#define ADIS16136_REG_SMPL_PRD 0x1E
#define ADIS16136_REG_AVG_CNT 0x20
#define ADIS16136_REG_DEC_RATE 0x22
#define ADIS16136_REG_SLP_CTRL 0x24
#define ADIS16136_REG_DIAG_STAT 0x26
#define ADIS16136_REG_GLOB_CMD 0x28
#define ADIS16136_REG_LOT1 0x32
#define ADIS16136_REG_LOT2 0x34
#define ADIS16136_REG_LOT3 0x36
#define ADIS16136_REG_PROD_ID 0x38
#define ADIS16136_REG_SERIAL_NUM 0x3A
#define ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL 2
#define ADIS16136_DIAG_STAT_SPI_FAIL 3
#define ADIS16136_DIAG_STAT_SELF_TEST_FAIL 5
#define ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL 6
#define ADIS16136_MSC_CTRL_MEMORY_TEST BIT(11)
#define ADIS16136_MSC_CTRL_SELF_TEST BIT(10)
struct adis16136_chip_info {
unsigned int precision;
unsigned int fullscale;
};
struct adis16136 {
const struct adis16136_chip_info *chip_info;
struct adis adis;
};
#ifdef CONFIG_DEBUG_FS
static ssize_t adis16136_show_serial(struct file *file,
char __user *userbuf, size_t count, loff_t *ppos)
{
struct adis16136 *adis16136 = file->private_data;
uint16_t lot1, lot2, lot3, serial;
char buf[20];
size_t len;
int ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SERIAL_NUM,
&serial);
if (ret < 0)
return ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT1, &lot1);
if (ret < 0)
return ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT2, &lot2);
if (ret < 0)
return ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT3, &lot3);
if (ret < 0)
return ret;
len = snprintf(buf, sizeof(buf), "%.4x%.4x%.4x-%.4x\n", lot1, lot2,
lot3, serial);
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
static const struct file_operations adis16136_serial_fops = {
.open = simple_open,
.read = adis16136_show_serial,
.llseek = default_llseek,
.owner = THIS_MODULE,
};
static int adis16136_show_product_id(void *arg, u64 *val)
{
struct adis16136 *adis16136 = arg;
u16 prod_id;
int ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID,
&prod_id);
if (ret < 0)
return ret;
*val = prod_id;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(adis16136_product_id_fops,
adis16136_show_product_id, NULL, "%llu\n");
static int adis16136_show_flash_count(void *arg, u64 *val)
{
struct adis16136 *adis16136 = arg;
uint16_t flash_count;
int ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_FLASH_CNT,
&flash_count);
if (ret < 0)
return ret;
*val = flash_count;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(adis16136_flash_count_fops,
adis16136_show_flash_count, NULL, "%lld\n");
static int adis16136_debugfs_init(struct iio_dev *indio_dev)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
adis16136, &adis16136_serial_fops);
debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
adis16136, &adis16136_product_id_fops);
debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
adis16136, &adis16136_flash_count_fops);
return 0;
}
#else
static int adis16136_debugfs_init(struct iio_dev *indio_dev)
{
return 0;
}
#endif
static int adis16136_set_freq(struct adis16136 *adis16136, unsigned int freq)
{
unsigned int t;
t = 32768 / freq;
if (t < 0xf)
t = 0xf;
else if (t > 0xffff)
t = 0xffff;
else
t--;
return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, t);
}
static int adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq)
{
uint16_t t;
int ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t);
if (ret < 0)
return ret;
*freq = 32768 / (t + 1);
return 0;
}
static ssize_t adis16136_write_frequency(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16136 *adis16136 = iio_priv(indio_dev);
unsigned int val;
int ret;
ret = kstrtouint(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
return -EINVAL;
ret = adis16136_set_freq(adis16136, val);
return ret ? ret : len;
}
static ssize_t adis16136_read_frequency(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16136 *adis16136 = iio_priv(indio_dev);
unsigned int freq;
int ret;
ret = adis16136_get_freq(adis16136, &freq);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", freq);
}
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
adis16136_read_frequency,
adis16136_write_frequency);
static const unsigned adis16136_3db_divisors[] = {
[0] = 2, /* Special case */
[1] = 6,
[2] = 12,
[3] = 25,
[4] = 50,
[5] = 100,
[6] = 200,
[7] = 200, /* Not a valid setting */
};
static int adis16136_set_filter(struct iio_dev *indio_dev, int val)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
unsigned int freq;
int i, ret;
ret = adis16136_get_freq(adis16136, &freq);
if (ret < 0)
return ret;
for (i = ARRAY_SIZE(adis16136_3db_divisors) - 1; i >= 1; i--) {
if (freq / adis16136_3db_divisors[i] >= val)
break;
}
return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i);
}
static int adis16136_get_filter(struct iio_dev *indio_dev, int *val)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
unsigned int freq;
uint16_t val16;
int ret;
mutex_lock(&indio_dev->mlock);
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, &val16);
if (ret < 0)
goto err_unlock;
ret = adis16136_get_freq(adis16136, &freq);
if (ret < 0)
goto err_unlock;
*val = freq / adis16136_3db_divisors[val16 & 0x07];
err_unlock:
mutex_unlock(&indio_dev->mlock);
return ret ? ret : IIO_VAL_INT;
}
static int adis16136_read_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *val, int *val2, long info)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
uint32_t val32;
int ret;
switch (info) {
case IIO_CHAN_INFO_RAW:
return adis_single_conversion(indio_dev, chan, 0, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
*val = adis16136->chip_info->precision;
*val2 = (adis16136->chip_info->fullscale << 16);
return IIO_VAL_FRACTIONAL;
case IIO_TEMP:
*val = 10;
*val2 = 697000; /* 0.010697 degree Celsius */
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_CALIBBIAS:
ret = adis_read_reg_32(&adis16136->adis,
ADIS16136_REG_GYRO_OFF2, &val32);
if (ret < 0)
return ret;
*val = sign_extend32(val32, 31);
return IIO_VAL_INT;
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
return adis16136_get_filter(indio_dev, val);
default:
return -EINVAL;
}
}
static int adis16136_write_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int val, int val2, long info)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
switch (info) {
case IIO_CHAN_INFO_CALIBBIAS:
return adis_write_reg_32(&adis16136->adis,
ADIS16136_REG_GYRO_OFF2, val);
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
return adis16136_set_filter(indio_dev, val);
default:
break;
}
return -EINVAL;
}
enum {
ADIS16136_SCAN_GYRO,
ADIS16136_SCAN_TEMP,
};
static const struct iio_chan_spec adis16136_channels[] = {
{
.type = IIO_ANGL_VEL,
.modified = 1,
.channel2 = IIO_MOD_X,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SHARED_BIT |
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT,
.address = ADIS16136_REG_GYRO_OUT2,
.scan_index = ADIS16136_SCAN_GYRO,
.scan_type = {
.sign = 's',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_BE,
},
}, {
.type = IIO_TEMP,
.indexed = 1,
.channel = 0,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
.address = ADIS16136_REG_TEMP_OUT,
.scan_index = ADIS16136_SCAN_TEMP,
.scan_type = {
.sign = 's',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_BE,
},
},
IIO_CHAN_SOFT_TIMESTAMP(2),
};
static struct attribute *adis16136_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL
};
static const struct attribute_group adis16136_attribute_group = {
.attrs = adis16136_attributes,
};
static const struct iio_info adis16136_info = {
.driver_module = THIS_MODULE,
.attrs = &adis16136_attribute_group,
.read_raw = &adis16136_read_raw,
.write_raw = &adis16136_write_raw,
.update_scan_mode = adis_update_scan_mode,
.debugfs_reg_access = adis_debugfs_reg_access,
};
static int adis16136_stop_device(struct iio_dev *indio_dev)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
int ret;
ret = adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SLP_CTRL, 0xff);
if (ret)
dev_err(&indio_dev->dev,
"Could not power down device: %d\n", ret);
return ret;
}
static int adis16136_initial_setup(struct iio_dev *indio_dev)
{
struct adis16136 *adis16136 = iio_priv(indio_dev);
unsigned int device_id;
uint16_t prod_id;
int ret;
ret = adis_initial_startup(&adis16136->adis);
if (ret)
return ret;
ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID,
&prod_id);
if (ret)
return ret;
sscanf(indio_dev->name, "adis%u\n", &device_id);
if (prod_id != device_id)
dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
device_id, prod_id);
return 0;
}
static const char * const adis16136_status_error_msgs[] = {
[ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL] = "Flash update failed",
[ADIS16136_DIAG_STAT_SPI_FAIL] = "SPI failure",
[ADIS16136_DIAG_STAT_SELF_TEST_FAIL] = "Self test error",
[ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL] = "Flash checksum error",
};
static const struct adis_data adis16136_data = {
.diag_stat_reg = ADIS16136_REG_DIAG_STAT,
.glob_cmd_reg = ADIS16136_REG_GLOB_CMD,
.msc_ctrl_reg = ADIS16136_REG_MSC_CTRL,
.self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST,
.startup_delay = 80,
.read_delay = 10,
.write_delay = 10,
.status_error_msgs = adis16136_status_error_msgs,
.status_error_mask = BIT(ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL) |
BIT(ADIS16136_DIAG_STAT_SPI_FAIL) |
BIT(ADIS16136_DIAG_STAT_SELF_TEST_FAIL) |
BIT(ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL),
};
enum adis16136_id {
ID_ADIS16133,
ID_ADIS16135,
ID_ADIS16136,
};
static const struct adis16136_chip_info adis16136_chip_info[] = {
[ID_ADIS16133] = {
.precision = IIO_DEGREE_TO_RAD(1200),
.fullscale = 24000,
},
[ID_ADIS16135] = {
.precision = IIO_DEGREE_TO_RAD(300),
.fullscale = 24000,
},
[ID_ADIS16136] = {
.precision = IIO_DEGREE_TO_RAD(450),
.fullscale = 24623,
},
};
static int adis16136_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct adis16136 *adis16136;
struct iio_dev *indio_dev;
int ret;
indio_dev = iio_device_alloc(sizeof(*adis16136));
if (indio_dev == NULL)
return -ENOMEM;
spi_set_drvdata(spi, indio_dev);
adis16136 = iio_priv(indio_dev);
adis16136->chip_info = &adis16136_chip_info[id->driver_data];
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->channels = adis16136_channels;
indio_dev->num_channels = ARRAY_SIZE(adis16136_channels);
indio_dev->info = &adis16136_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
if (ret)
goto error_free_dev;
ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
ret = adis16136_initial_setup(indio_dev);
if (ret)
goto error_cleanup_buffer;
ret = iio_device_register(indio_dev);
if (ret)
goto error_stop_device;
adis16136_debugfs_init(indio_dev);
return 0;
error_stop_device:
adis16136_stop_device(indio_dev);
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
return ret;
}
static int adis16136_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adis16136 *adis16136 = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis16136_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
iio_device_free(indio_dev);
return 0;
}
static const struct spi_device_id adis16136_ids[] = {
{ "adis16133", ID_ADIS16133 },
{ "adis16135", ID_ADIS16135 },
{ "adis16136", ID_ADIS16136 },
{ }
};
MODULE_DEVICE_TABLE(spi, adis16136_ids);
static struct spi_driver adis16136_driver = {
.driver = {
.name = "adis16136",
.owner = THIS_MODULE,
},
.id_table = adis16136_ids,
.probe = adis16136_probe,
.remove = adis16136_remove,
};
module_spi_driver(adis16136_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver");
MODULE_LICENSE("GPL v2");

View File

@ -197,21 +197,8 @@ static const struct iio_info gyro_3d_info = {
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) {
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@ -319,10 +306,10 @@ static int __devinit hid_gyro_3d_probe(struct platform_device *pdev)
goto error_free_dev;
}
channels = kmemdup(gyro_3d_channels,
sizeof(gyro_3d_channels),
GFP_KERNEL);
channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels),
GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}

27
drivers/iio/imu/Kconfig Normal file
View File

@ -0,0 +1,27 @@
#
# IIO imu drivers configuration
#
menu "Inertial measurement units"
config ADIS16480
tristate "Analog Devices ADIS16480 and similar IMU driver"
depends on SPI
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
ADIS16485, ADIS16488 inertial sensors.
endmenu
config IIO_ADIS_LIB
tristate
help
A set of IO helper functions for the Analog Devices ADIS* device family.
config IIO_ADIS_LIB_BUFFER
bool
select IIO_TRIGGERED_BUFFER
help
A set of buffer helper functions for the Analog Devices ADIS* device
family.

10
drivers/iio/imu/Makefile Normal file
View File

@ -0,0 +1,10 @@
#
# Makefile for Inertial Measurement Units
#
obj-$(CONFIG_ADIS16480) += adis16480.o
adis_lib-y += adis.o
adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o

440
drivers/iio/imu/adis.c Normal file
View File

@ -0,0 +1,440 @@
/*
* Common library for ADIS16XXX devices
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <asm/unaligned.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/imu/adis.h>
#define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2)
#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1)
#define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
#define ADIS_GLOB_CMD_SW_RESET BIT(7)
int adis_write_reg(struct adis *adis, unsigned int reg,
unsigned int value, unsigned int size)
{
unsigned int page = reg / ADIS_PAGE_SIZE;
int ret, i;
struct spi_message msg;
struct spi_transfer xfers[] = {
{
.tx_buf = adis->tx,
.bits_per_word = 8,
.len = 2,
.cs_change = 1,
.delay_usecs = adis->data->write_delay,
}, {
.tx_buf = adis->tx + 2,
.bits_per_word = 8,
.len = 2,
.cs_change = 1,
.delay_usecs = adis->data->write_delay,
}, {
.tx_buf = adis->tx + 4,
.bits_per_word = 8,
.len = 2,
.cs_change = 1,
.delay_usecs = adis->data->write_delay,
}, {
.tx_buf = adis->tx + 6,
.bits_per_word = 8,
.len = 2,
.delay_usecs = adis->data->write_delay,
}, {
.tx_buf = adis->tx + 8,
.bits_per_word = 8,
.len = 2,
.delay_usecs = adis->data->write_delay,
},
};
mutex_lock(&adis->txrx_lock);
spi_message_init(&msg);
if (adis->current_page != page) {
adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
adis->tx[1] = page;
spi_message_add_tail(&xfers[0], &msg);
}
switch (size) {
case 4:
adis->tx[8] = ADIS_WRITE_REG(reg + 3);
adis->tx[9] = (value >> 24) & 0xff;
adis->tx[6] = ADIS_WRITE_REG(reg + 2);
adis->tx[7] = (value >> 16) & 0xff;
case 2:
adis->tx[4] = ADIS_WRITE_REG(reg + 1);
adis->tx[5] = (value >> 8) & 0xff;
case 1:
adis->tx[2] = ADIS_WRITE_REG(reg);
adis->tx[3] = value & 0xff;
break;
default:
ret = -EINVAL;
goto out_unlock;
}
xfers[size].cs_change = 0;
for (i = 1; i <= size; i++)
spi_message_add_tail(&xfers[i], &msg);
ret = spi_sync(adis->spi, &msg);
if (ret) {
dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
reg, ret);
} else {
adis->current_page = page;
}
out_unlock:
mutex_unlock(&adis->txrx_lock);
return ret;
}
EXPORT_SYMBOL_GPL(adis_write_reg);
/**
* adis_read_reg() - read 2 bytes from a 16-bit register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*/
int adis_read_reg(struct adis *adis, unsigned int reg,
unsigned int *val, unsigned int size)
{
unsigned int page = reg / ADIS_PAGE_SIZE;
struct spi_message msg;
int ret;
struct spi_transfer xfers[] = {
{
.tx_buf = adis->tx,
.bits_per_word = 8,
.len = 2,
.cs_change = 1,
.delay_usecs = adis->data->write_delay,
}, {
.tx_buf = adis->tx + 2,
.bits_per_word = 8,
.len = 2,
.cs_change = 1,
.delay_usecs = adis->data->read_delay,
}, {
.tx_buf = adis->tx + 4,
.rx_buf = adis->rx,
.bits_per_word = 8,
.len = 2,
.cs_change = 1,
.delay_usecs = adis->data->read_delay,
}, {
.rx_buf = adis->rx + 2,
.bits_per_word = 8,
.len = 2,
.delay_usecs = adis->data->read_delay,
},
};
mutex_lock(&adis->txrx_lock);
spi_message_init(&msg);
if (adis->current_page != page) {
adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
adis->tx[1] = page;
spi_message_add_tail(&xfers[0], &msg);
}
switch (size) {
case 4:
adis->tx[2] = ADIS_READ_REG(reg + 2);
adis->tx[3] = 0;
spi_message_add_tail(&xfers[1], &msg);
case 2:
adis->tx[4] = ADIS_READ_REG(reg);
adis->tx[5] = 0;
spi_message_add_tail(&xfers[2], &msg);
spi_message_add_tail(&xfers[3], &msg);
break;
default:
ret = -EINVAL;
goto out_unlock;
}
ret = spi_sync(adis->spi, &msg);
if (ret) {
dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
reg, ret);
goto out_unlock;
} else {
adis->current_page = page;
}
switch (size) {
case 4:
*val = get_unaligned_be32(adis->rx);
break;
case 2:
*val = get_unaligned_be16(adis->rx + 2);
break;
}
out_unlock:
mutex_unlock(&adis->txrx_lock);
return ret;
}
EXPORT_SYMBOL_GPL(adis_read_reg);
#ifdef CONFIG_DEBUG_FS
int adis_debugfs_reg_access(struct iio_dev *indio_dev,
unsigned int reg, unsigned int writeval, unsigned int *readval)
{
struct adis *adis = iio_device_get_drvdata(indio_dev);
if (readval) {
uint16_t val16;
int ret;
ret = adis_read_reg_16(adis, reg, &val16);
*readval = val16;
return ret;
} else {
return adis_write_reg_16(adis, reg, writeval);
}
}
EXPORT_SYMBOL(adis_debugfs_reg_access);
#endif
/**
* adis_enable_irq() - Enable or disable data ready IRQ
* @adis: The adis device
* @enable: Whether to enable the IRQ
*
* Returns 0 on success, negative error code otherwise
*/
int adis_enable_irq(struct adis *adis, bool enable)
{
int ret = 0;
uint16_t msc;
if (adis->data->enable_irq)
return adis->data->enable_irq(adis, enable);
ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
if (ret)
goto error_ret;
msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
if (enable)
msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
else
msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
error_ret:
return ret;
}
EXPORT_SYMBOL(adis_enable_irq);
/**
* adis_check_status() - Check the device for error conditions
* @adis: The adis device
*
* Returns 0 on success, a negative error code otherwise
*/
int adis_check_status(struct adis *adis)
{
uint16_t status;
int ret;
int i;
ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
if (ret < 0)
return ret;
status &= adis->data->status_error_mask;
if (status == 0)
return 0;
for (i = 0; i < 16; ++i) {
if (status & BIT(i)) {
dev_err(&adis->spi->dev, "%s.\n",
adis->data->status_error_msgs[i]);
}
}
return -EIO;
}
EXPORT_SYMBOL_GPL(adis_check_status);
/**
* adis_reset() - Reset the device
* @adis: The adis device
*
* Returns 0 on success, a negative error code otherwise
*/
int adis_reset(struct adis *adis)
{
int ret;
ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
ADIS_GLOB_CMD_SW_RESET);
if (ret)
dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
return ret;
}
EXPORT_SYMBOL_GPL(adis_reset);
static int adis_self_test(struct adis *adis)
{
int ret;
ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
adis->data->self_test_mask);
if (ret) {
dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
ret);
return ret;
}
msleep(adis->data->startup_delay);
return adis_check_status(adis);
}
/**
* adis_inital_startup() - Performs device self-test
* @adis: The adis device
*
* Returns 0 if the device is operational, a negative error code otherwise.
*
* This function should be called early on in the device initialization sequence
* to ensure that the device is in a sane and known state and that it is usable.
*/
int adis_initial_startup(struct adis *adis)
{
int ret;
ret = adis_self_test(adis);
if (ret) {
dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
adis_reset(adis);
msleep(adis->data->startup_delay);
ret = adis_self_test(adis);
if (ret) {
dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
return ret;
}
}
return 0;
}
EXPORT_SYMBOL_GPL(adis_initial_startup);
/**
* adis_single_conversion() - Performs a single sample conversion
* @indio_dev: The IIO device
* @chan: The IIO channel
* @error_mask: Mask for the error bit
* @val: Result of the conversion
*
* Returns IIO_VAL_INT on success, a negative error code otherwise.
*
* The function performs a single conversion on a given channel and post
* processes the value accordingly to the channel spec. If a error_mask is given
* the function will check if the mask is set in the returned raw value. If it
* is set the function will perform a self-check. If the device does not report
* a error bit in the channels raw value set error_mask to 0.
*/
int adis_single_conversion(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
{
struct adis *adis = iio_device_get_drvdata(indio_dev);
unsigned int uval;
int ret;
mutex_lock(&indio_dev->mlock);
ret = adis_read_reg(adis, chan->address, &uval,
chan->scan_type.storagebits / 8);
if (ret)
goto err_unlock;
if (uval & error_mask) {
ret = adis_check_status(adis);
if (ret)
goto err_unlock;
}
if (chan->scan_type.sign == 's')
*val = sign_extend32(uval, chan->scan_type.realbits - 1);
else
*val = uval & ((1 << chan->scan_type.realbits) - 1);
ret = IIO_VAL_INT;
err_unlock:
mutex_unlock(&indio_dev->mlock);
return ret;
}
EXPORT_SYMBOL_GPL(adis_single_conversion);
/**
* adis_init() - Initialize adis device structure
* @adis: The adis device
* @indio_dev: The iio device
* @spi: The spi device
* @data: Chip specific data
*
* Returns 0 on success, a negative error code otherwise.
*
* This function must be called, before any other adis helper function may be
* called.
*/
int adis_init(struct adis *adis, struct iio_dev *indio_dev,
struct spi_device *spi, const struct adis_data *data)
{
mutex_init(&adis->txrx_lock);
adis->spi = spi;
adis->data = data;
iio_device_set_drvdata(indio_dev, adis);
if (data->has_paging) {
/* Need to set the page before first read/write */
adis->current_page = -1;
} else {
/* Page will always be 0 */
adis->current_page = 0;
}
return adis_enable_irq(adis, false);
}
EXPORT_SYMBOL_GPL(adis_init);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");

924
drivers/iio/imu/adis16480.c Normal file
View File

@ -0,0 +1,924 @@
/*
* ADIS16480 and similar IMUs driver
*
* Copyright 2012 Analog Devices Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/imu/adis.h>
#include <linux/debugfs.h>
#define ADIS16480_PAGE_SIZE 0x80
#define ADIS16480_REG(page, reg) ((page) * ADIS16480_PAGE_SIZE + (reg))
#define ADIS16480_REG_PAGE_ID 0x00 /* Same address on each page */
#define ADIS16480_REG_SEQ_CNT ADIS16480_REG(0x00, 0x06)
#define ADIS16480_REG_SYS_E_FLA ADIS16480_REG(0x00, 0x08)
#define ADIS16480_REG_DIAG_STS ADIS16480_REG(0x00, 0x0A)
#define ADIS16480_REG_ALM_STS ADIS16480_REG(0x00, 0x0C)
#define ADIS16480_REG_TEMP_OUT ADIS16480_REG(0x00, 0x0E)
#define ADIS16480_REG_X_GYRO_OUT ADIS16480_REG(0x00, 0x10)
#define ADIS16480_REG_Y_GYRO_OUT ADIS16480_REG(0x00, 0x14)
#define ADIS16480_REG_Z_GYRO_OUT ADIS16480_REG(0x00, 0x18)
#define ADIS16480_REG_X_ACCEL_OUT ADIS16480_REG(0x00, 0x1C)
#define ADIS16480_REG_Y_ACCEL_OUT ADIS16480_REG(0x00, 0x20)
#define ADIS16480_REG_Z_ACCEL_OUT ADIS16480_REG(0x00, 0x24)
#define ADIS16480_REG_X_MAGN_OUT ADIS16480_REG(0x00, 0x28)
#define ADIS16480_REG_Y_MAGN_OUT ADIS16480_REG(0x00, 0x2A)
#define ADIS16480_REG_Z_MAGN_OUT ADIS16480_REG(0x00, 0x2C)
#define ADIS16480_REG_BAROM_OUT ADIS16480_REG(0x00, 0x2E)
#define ADIS16480_REG_X_DELTAANG_OUT ADIS16480_REG(0x00, 0x40)
#define ADIS16480_REG_Y_DELTAANG_OUT ADIS16480_REG(0x00, 0x44)
#define ADIS16480_REG_Z_DELTAANG_OUT ADIS16480_REG(0x00, 0x48)
#define ADIS16480_REG_X_DELTAVEL_OUT ADIS16480_REG(0x00, 0x4C)
#define ADIS16480_REG_Y_DELTAVEL_OUT ADIS16480_REG(0x00, 0x50)
#define ADIS16480_REG_Z_DELTAVEL_OUT ADIS16480_REG(0x00, 0x54)
#define ADIS16480_REG_PROD_ID ADIS16480_REG(0x00, 0x7E)
#define ADIS16480_REG_X_GYRO_SCALE ADIS16480_REG(0x02, 0x04)
#define ADIS16480_REG_Y_GYRO_SCALE ADIS16480_REG(0x02, 0x06)
#define ADIS16480_REG_Z_GYRO_SCALE ADIS16480_REG(0x02, 0x08)
#define ADIS16480_REG_X_ACCEL_SCALE ADIS16480_REG(0x02, 0x0A)
#define ADIS16480_REG_Y_ACCEL_SCALE ADIS16480_REG(0x02, 0x0C)
#define ADIS16480_REG_Z_ACCEL_SCALE ADIS16480_REG(0x02, 0x0E)
#define ADIS16480_REG_X_GYRO_BIAS ADIS16480_REG(0x02, 0x10)
#define ADIS16480_REG_Y_GYRO_BIAS ADIS16480_REG(0x02, 0x14)
#define ADIS16480_REG_Z_GYRO_BIAS ADIS16480_REG(0x02, 0x18)
#define ADIS16480_REG_X_ACCEL_BIAS ADIS16480_REG(0x02, 0x1C)
#define ADIS16480_REG_Y_ACCEL_BIAS ADIS16480_REG(0x02, 0x20)
#define ADIS16480_REG_Z_ACCEL_BIAS ADIS16480_REG(0x02, 0x24)
#define ADIS16480_REG_X_HARD_IRON ADIS16480_REG(0x02, 0x28)
#define ADIS16480_REG_Y_HARD_IRON ADIS16480_REG(0x02, 0x2A)
#define ADIS16480_REG_Z_HARD_IRON ADIS16480_REG(0x02, 0x2C)
#define ADIS16480_REG_BAROM_BIAS ADIS16480_REG(0x02, 0x40)
#define ADIS16480_REG_FLASH_CNT ADIS16480_REG(0x02, 0x7C)
#define ADIS16480_REG_GLOB_CMD ADIS16480_REG(0x03, 0x02)
#define ADIS16480_REG_FNCTIO_CTRL ADIS16480_REG(0x03, 0x06)
#define ADIS16480_REG_GPIO_CTRL ADIS16480_REG(0x03, 0x08)
#define ADIS16480_REG_CONFIG ADIS16480_REG(0x03, 0x0A)
#define ADIS16480_REG_DEC_RATE ADIS16480_REG(0x03, 0x0C)
#define ADIS16480_REG_SLP_CNT ADIS16480_REG(0x03, 0x10)
#define ADIS16480_REG_FILTER_BNK0 ADIS16480_REG(0x03, 0x16)
#define ADIS16480_REG_FILTER_BNK1 ADIS16480_REG(0x03, 0x18)
#define ADIS16480_REG_ALM_CNFG0 ADIS16480_REG(0x03, 0x20)
#define ADIS16480_REG_ALM_CNFG1 ADIS16480_REG(0x03, 0x22)
#define ADIS16480_REG_ALM_CNFG2 ADIS16480_REG(0x03, 0x24)
#define ADIS16480_REG_XG_ALM_MAGN ADIS16480_REG(0x03, 0x28)
#define ADIS16480_REG_YG_ALM_MAGN ADIS16480_REG(0x03, 0x2A)
#define ADIS16480_REG_ZG_ALM_MAGN ADIS16480_REG(0x03, 0x2C)
#define ADIS16480_REG_XA_ALM_MAGN ADIS16480_REG(0x03, 0x2E)
#define ADIS16480_REG_YA_ALM_MAGN ADIS16480_REG(0x03, 0x30)
#define ADIS16480_REG_ZA_ALM_MAGN ADIS16480_REG(0x03, 0x32)
#define ADIS16480_REG_XM_ALM_MAGN ADIS16480_REG(0x03, 0x34)
#define ADIS16480_REG_YM_ALM_MAGN ADIS16480_REG(0x03, 0x36)
#define ADIS16480_REG_ZM_ALM_MAGN ADIS16480_REG(0x03, 0x38)
#define ADIS16480_REG_BR_ALM_MAGN ADIS16480_REG(0x03, 0x3A)
#define ADIS16480_REG_FIRM_REV ADIS16480_REG(0x03, 0x78)
#define ADIS16480_REG_FIRM_DM ADIS16480_REG(0x03, 0x7A)
#define ADIS16480_REG_FIRM_Y ADIS16480_REG(0x03, 0x7C)
#define ADIS16480_REG_SERIAL_NUM ADIS16480_REG(0x04, 0x20)
/* Each filter coefficent bank spans two pages */
#define ADIS16480_FIR_COEF(page) (x < 60 ? ADIS16480_REG(page, (x) + 8) : \
ADIS16480_REG((page) + 1, (x) - 60 + 8))
#define ADIS16480_FIR_COEF_A(x) ADIS16480_FIR_COEF(0x05, (x))
#define ADIS16480_FIR_COEF_B(x) ADIS16480_FIR_COEF(0x07, (x))
#define ADIS16480_FIR_COEF_C(x) ADIS16480_FIR_COEF(0x09, (x))
#define ADIS16480_FIR_COEF_D(x) ADIS16480_FIR_COEF(0x0B, (x))
struct adis16480_chip_info {
unsigned int num_channels;
const struct iio_chan_spec *channels;
};
struct adis16480 {
const struct adis16480_chip_info *chip_info;
struct adis adis;
};
#ifdef CONFIG_DEBUG_FS
static ssize_t adis16480_show_firmware_revision(struct file *file,
char __user *userbuf, size_t count, loff_t *ppos)
{
struct adis16480 *adis16480 = file->private_data;
char buf[7];
size_t len;
u16 rev;
int ret;
ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_REV, &rev);
if (ret < 0)
return ret;
len = scnprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev & 0xff);
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
static const struct file_operations adis16480_firmware_revision_fops = {
.open = simple_open,
.read = adis16480_show_firmware_revision,
.llseek = default_llseek,
.owner = THIS_MODULE,
};
static ssize_t adis16480_show_firmware_date(struct file *file,
char __user *userbuf, size_t count, loff_t *ppos)
{
struct adis16480 *adis16480 = file->private_data;
u16 md, year;
char buf[12];
size_t len;
int ret;
ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_Y, &year);
if (ret < 0)
return ret;
ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_DM, &md);
if (ret < 0)
return ret;
len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n",
md >> 8, md & 0xff, year);
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
static const struct file_operations adis16480_firmware_date_fops = {
.open = simple_open,
.read = adis16480_show_firmware_date,
.llseek = default_llseek,
.owner = THIS_MODULE,
};
static int adis16480_show_serial_number(void *arg, u64 *val)
{
struct adis16480 *adis16480 = arg;
u16 serial;
int ret;
ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_SERIAL_NUM,
&serial);
if (ret < 0)
return ret;
*val = serial;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(adis16480_serial_number_fops,
adis16480_show_serial_number, NULL, "0x%.4llx\n");
static int adis16480_show_product_id(void *arg, u64 *val)
{
struct adis16480 *adis16480 = arg;
u16 prod_id;
int ret;
ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_PROD_ID,
&prod_id);
if (ret < 0)
return ret;
*val = prod_id;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(adis16480_product_id_fops,
adis16480_show_product_id, NULL, "%llu\n");
static int adis16480_show_flash_count(void *arg, u64 *val)
{
struct adis16480 *adis16480 = arg;
u32 flash_count;
int ret;
ret = adis_read_reg_32(&adis16480->adis, ADIS16480_REG_FLASH_CNT,
&flash_count);
if (ret < 0)
return ret;
*val = flash_count;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(adis16480_flash_count_fops,
adis16480_show_flash_count, NULL, "%lld\n");
static int adis16480_debugfs_init(struct iio_dev *indio_dev)
{
struct adis16480 *adis16480 = iio_priv(indio_dev);
debugfs_create_file("firmware_revision", 0400,
indio_dev->debugfs_dentry, adis16480,
&adis16480_firmware_revision_fops);
debugfs_create_file("firmware_date", 0400, indio_dev->debugfs_dentry,
adis16480, &adis16480_firmware_date_fops);
debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry,
adis16480, &adis16480_serial_number_fops);
debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry,
adis16480, &adis16480_product_id_fops);
debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry,
adis16480, &adis16480_flash_count_fops);
return 0;
}
#else
static int adis16480_debugfs_init(struct iio_dev *indio_dev)
{
return 0;
}
#endif
static int adis16480_set_freq(struct adis16480 *st, unsigned int freq)
{
unsigned int t;
t = 2460000 / freq;
if (t > 2048)
t = 2048;
if (t != 0)
t--;
return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t);
}
static int adis16480_get_freq(struct adis16480 *st, unsigned int *freq)
{
uint16_t t;
int ret;
ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t);
if (ret < 0)
return ret;
*freq = 2460000 / (t + 1);
return 0;
}
static ssize_t adis16480_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16480 *st = iio_priv(indio_dev);
unsigned int freq;
int ret;
ret = adis16480_get_freq(st, &freq);
if (ret < 0)
return ret;
return sprintf(buf, "%d.%.3d\n", freq / 1000, freq % 1000);
}
static ssize_t adis16480_write_frequency(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16480 *st = iio_priv(indio_dev);
int freq_int, freq_fract;
long val;
int ret;
ret = iio_str_to_fixpoint(buf, 100, &freq_int, &freq_fract);
if (ret)
return ret;
val = freq_int * 1000 + freq_fract;
if (val <= 0)
return -EINVAL;
ret = adis16480_set_freq(st, val);
return ret ? ret : len;
}
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
adis16480_read_frequency,
adis16480_write_frequency);
enum {
ADIS16480_SCAN_GYRO_X,
ADIS16480_SCAN_GYRO_Y,
ADIS16480_SCAN_GYRO_Z,
ADIS16480_SCAN_ACCEL_X,
ADIS16480_SCAN_ACCEL_Y,
ADIS16480_SCAN_ACCEL_Z,
ADIS16480_SCAN_MAGN_X,
ADIS16480_SCAN_MAGN_Y,
ADIS16480_SCAN_MAGN_Z,
ADIS16480_SCAN_BARO,
ADIS16480_SCAN_TEMP,
};
static const unsigned int adis16480_calibbias_regs[] = {
[ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_BIAS,
[ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_BIAS,
[ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_BIAS,
[ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_BIAS,
[ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_BIAS,
[ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_BIAS,
[ADIS16480_SCAN_MAGN_X] = ADIS16480_REG_X_HARD_IRON,
[ADIS16480_SCAN_MAGN_Y] = ADIS16480_REG_Y_HARD_IRON,
[ADIS16480_SCAN_MAGN_Z] = ADIS16480_REG_Z_HARD_IRON,
[ADIS16480_SCAN_BARO] = ADIS16480_REG_BAROM_BIAS,
};
static const unsigned int adis16480_calibscale_regs[] = {
[ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_SCALE,
[ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_SCALE,
[ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_SCALE,
[ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_SCALE,
[ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_SCALE,
[ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_SCALE,
};
static int adis16480_set_calibbias(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int bias)
{
unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
struct adis16480 *st = iio_priv(indio_dev);
switch (chan->type) {
case IIO_MAGN:
case IIO_PRESSURE:
if (bias < -0x8000 || bias >= 0x8000)
return -EINVAL;
return adis_write_reg_16(&st->adis, reg, bias);
case IIO_ANGL_VEL:
case IIO_ACCEL:
return adis_write_reg_32(&st->adis, reg, bias);
default:
break;
}
return -EINVAL;
}
static int adis16480_get_calibbias(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *bias)
{
unsigned int reg = adis16480_calibbias_regs[chan->scan_index];
struct adis16480 *st = iio_priv(indio_dev);
uint16_t val16;
uint32_t val32;
int ret;
switch (chan->type) {
case IIO_MAGN:
case IIO_PRESSURE:
ret = adis_read_reg_16(&st->adis, reg, &val16);
*bias = sign_extend32(val16, 15);
break;
case IIO_ANGL_VEL:
case IIO_ACCEL:
ret = adis_read_reg_32(&st->adis, reg, &val32);
*bias = sign_extend32(val32, 31);
break;
default:
ret = -EINVAL;
}
if (ret < 0)
return ret;
return IIO_VAL_INT;
}
static int adis16480_set_calibscale(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int scale)
{
unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
struct adis16480 *st = iio_priv(indio_dev);
if (scale < -0x8000 || scale >= 0x8000)
return -EINVAL;
return adis_write_reg_16(&st->adis, reg, scale);
}
static int adis16480_get_calibscale(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *scale)
{
unsigned int reg = adis16480_calibscale_regs[chan->scan_index];
struct adis16480 *st = iio_priv(indio_dev);
uint16_t val16;
int ret;
ret = adis_read_reg_16(&st->adis, reg, &val16);
if (ret < 0)
return ret;
*scale = sign_extend32(val16, 15);
return IIO_VAL_INT;
}
static const unsigned int adis16480_def_filter_freqs[] = {
310,
55,
275,
63,
};
static const unsigned int ad16480_filter_data[][2] = {
[ADIS16480_SCAN_GYRO_X] = { ADIS16480_REG_FILTER_BNK0, 0 },
[ADIS16480_SCAN_GYRO_Y] = { ADIS16480_REG_FILTER_BNK0, 3 },
[ADIS16480_SCAN_GYRO_Z] = { ADIS16480_REG_FILTER_BNK0, 6 },
[ADIS16480_SCAN_ACCEL_X] = { ADIS16480_REG_FILTER_BNK0, 9 },
[ADIS16480_SCAN_ACCEL_Y] = { ADIS16480_REG_FILTER_BNK0, 12 },
[ADIS16480_SCAN_ACCEL_Z] = { ADIS16480_REG_FILTER_BNK1, 0 },
[ADIS16480_SCAN_MAGN_X] = { ADIS16480_REG_FILTER_BNK1, 3 },
[ADIS16480_SCAN_MAGN_Y] = { ADIS16480_REG_FILTER_BNK1, 6 },
[ADIS16480_SCAN_MAGN_Z] = { ADIS16480_REG_FILTER_BNK1, 9 },
};
static int adis16480_get_filter_freq(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *freq)
{
struct adis16480 *st = iio_priv(indio_dev);
unsigned int enable_mask, offset, reg;
uint16_t val;
int ret;
reg = ad16480_filter_data[chan->scan_index][0];
offset = ad16480_filter_data[chan->scan_index][1];
enable_mask = BIT(offset + 2);
ret = adis_read_reg_16(&st->adis, reg, &val);
if (ret < 0)
return ret;
if (!(val & enable_mask))
*freq = 0;
else
*freq = adis16480_def_filter_freqs[(val >> offset) & 0x3];
return IIO_VAL_INT;
}
static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, unsigned int freq)
{
struct adis16480 *st = iio_priv(indio_dev);
unsigned int enable_mask, offset, reg;
unsigned int diff, best_diff;
unsigned int i, best_freq;
uint16_t val;
int ret;
reg = ad16480_filter_data[chan->scan_index][0];
offset = ad16480_filter_data[chan->scan_index][1];
enable_mask = BIT(offset + 2);
ret = adis_read_reg_16(&st->adis, reg, &val);
if (ret < 0)
return ret;
if (freq == 0) {
val &= ~enable_mask;
} else {
best_freq = 0;
best_diff = 310;
for (i = 0; i < ARRAY_SIZE(adis16480_def_filter_freqs); i++) {
if (adis16480_def_filter_freqs[i] >= freq) {
diff = adis16480_def_filter_freqs[i] - freq;
if (diff < best_diff) {
best_diff = diff;
best_freq = i;
}
}
}
val &= ~(0x3 << offset);
val |= best_freq << offset;
val |= enable_mask;
}
return adis_write_reg_16(&st->adis, reg, val);
}
static int adis16480_read_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *val, int *val2, long info)
{
switch (info) {
case IIO_CHAN_INFO_RAW:
return adis_single_conversion(indio_dev, chan, 0, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
*val = 0;
*val2 = IIO_DEGREE_TO_RAD(20000); /* 0.02 degree/sec */
return IIO_VAL_INT_PLUS_MICRO;
case IIO_ACCEL:
*val = 0;
*val2 = IIO_G_TO_M_S_2(800); /* 0.8 mg */
return IIO_VAL_INT_PLUS_MICRO;
case IIO_MAGN:
*val = 0;
*val2 = 100; /* 0.0001 gauss */
return IIO_VAL_INT_PLUS_MICRO;
case IIO_TEMP:
*val = 5;
*val2 = 650000; /* 5.65 milli degree Celsius */
return IIO_VAL_INT_PLUS_MICRO;
case IIO_PRESSURE:
*val = 0;
*val2 = 4000; /* 40ubar = 0.004 kPa */
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_OFFSET:
/* Only the temperature channel has a offset */
*val = 4425; /* 25 degree Celsius = 0x0000 */
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBBIAS:
return adis16480_get_calibbias(indio_dev, chan, val);
case IIO_CHAN_INFO_CALIBSCALE:
return adis16480_get_calibscale(indio_dev, chan, val);
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
return adis16480_get_filter_freq(indio_dev, chan, val);
default:
return -EINVAL;
}
}
static int adis16480_write_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int val, int val2, long info)
{
switch (info) {
case IIO_CHAN_INFO_CALIBBIAS:
return adis16480_set_calibbias(indio_dev, chan, val);
case IIO_CHAN_INFO_CALIBSCALE:
return adis16480_set_calibscale(indio_dev, chan, val);
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
return adis16480_set_filter_freq(indio_dev, chan, val);
default:
return -EINVAL;
}
}
#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info, _bits) \
{ \
.type = (_type), \
.modified = 1, \
.channel2 = (_mod), \
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
IIO_CHAN_INFO_SCALE_SHARED_BIT | \
_info, \
.address = (_address), \
.scan_index = (_si), \
.scan_type = { \
.sign = 's', \
.realbits = (_bits), \
.storagebits = (_bits), \
.endianness = IIO_BE, \
}, \
}
#define ADIS16480_GYRO_CHANNEL(_mod) \
ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \
IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \
32)
#define ADIS16480_ACCEL_CHANNEL(_mod) \
ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \
ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \
IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \
32)
#define ADIS16480_MAGN_CHANNEL(_mod) \
ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \
ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, \
16)
#define ADIS16480_PRESSURE_CHANNEL() \
{ \
.type = IIO_PRESSURE, \
.indexed = 1, \
.channel = 0, \
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
.address = ADIS16480_REG_BAROM_OUT, \
.scan_index = ADIS16480_SCAN_BARO, \
.scan_type = { \
.sign = 's', \
.realbits = 32, \
.storagebits = 32, \
.endianness = IIO_BE, \
}, \
}
#define ADIS16480_TEMP_CHANNEL() { \
.type = IIO_TEMP, \
.indexed = 1, \
.channel = 0, \
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \
.address = ADIS16480_REG_TEMP_OUT, \
.scan_index = ADIS16480_SCAN_TEMP, \
.scan_type = { \
.sign = 's', \
.realbits = 16, \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
}
static const struct iio_chan_spec adis16480_channels[] = {
ADIS16480_GYRO_CHANNEL(X),
ADIS16480_GYRO_CHANNEL(Y),
ADIS16480_GYRO_CHANNEL(Z),
ADIS16480_ACCEL_CHANNEL(X),
ADIS16480_ACCEL_CHANNEL(Y),
ADIS16480_ACCEL_CHANNEL(Z),
ADIS16480_MAGN_CHANNEL(X),
ADIS16480_MAGN_CHANNEL(Y),
ADIS16480_MAGN_CHANNEL(Z),
ADIS16480_PRESSURE_CHANNEL(),
ADIS16480_TEMP_CHANNEL(),
IIO_CHAN_SOFT_TIMESTAMP(11)
};
static const struct iio_chan_spec adis16485_channels[] = {
ADIS16480_GYRO_CHANNEL(X),
ADIS16480_GYRO_CHANNEL(Y),
ADIS16480_GYRO_CHANNEL(Z),
ADIS16480_ACCEL_CHANNEL(X),
ADIS16480_ACCEL_CHANNEL(Y),
ADIS16480_ACCEL_CHANNEL(Z),
ADIS16480_TEMP_CHANNEL(),
IIO_CHAN_SOFT_TIMESTAMP(7)
};
enum adis16480_variant {
ADIS16375,
ADIS16480,
ADIS16485,
ADIS16488,
};
static const struct adis16480_chip_info adis16480_chip_info[] = {
[ADIS16375] = {
.channels = adis16485_channels,
.num_channels = ARRAY_SIZE(adis16485_channels),
},
[ADIS16480] = {
.channels = adis16480_channels,
.num_channels = ARRAY_SIZE(adis16480_channels),
},
[ADIS16485] = {
.channels = adis16485_channels,
.num_channels = ARRAY_SIZE(adis16485_channels),
},
[ADIS16488] = {
.channels = adis16480_channels,
.num_channels = ARRAY_SIZE(adis16480_channels),
},
};
static struct attribute *adis16480_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL
};
static const struct attribute_group adis16480_attribute_group = {
.attrs = adis16480_attributes,
};
static const struct iio_info adis16480_info = {
.attrs = &adis16480_attribute_group,
.read_raw = &adis16480_read_raw,
.write_raw = &adis16480_write_raw,
.update_scan_mode = adis_update_scan_mode,
.driver_module = THIS_MODULE,
};
static int adis16480_stop_device(struct iio_dev *indio_dev)
{
struct adis16480 *st = iio_priv(indio_dev);
int ret;
ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9));
if (ret)
dev_err(&indio_dev->dev,
"Could not power down device: %d\n", ret);
return ret;
}
static int adis16480_enable_irq(struct adis *adis, bool enable)
{
return adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL,
enable ? BIT(3) : 0);
}
static int adis16480_initial_setup(struct iio_dev *indio_dev)
{
struct adis16480 *st = iio_priv(indio_dev);
uint16_t prod_id;
unsigned int device_id;
int ret;
adis_reset(&st->adis);
msleep(70);
ret = adis_write_reg_16(&st->adis, ADIS16480_REG_GLOB_CMD, BIT(1));
if (ret)
return ret;
msleep(30);
ret = adis_check_status(&st->adis);
if (ret)
return ret;
ret = adis_read_reg_16(&st->adis, ADIS16480_REG_PROD_ID, &prod_id);
if (ret)
return ret;
sscanf(indio_dev->name, "adis%u\n", &device_id);
if (prod_id != device_id)
dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
device_id, prod_id);
return 0;
}
#define ADIS16480_DIAG_STAT_XGYRO_FAIL 0
#define ADIS16480_DIAG_STAT_YGYRO_FAIL 1
#define ADIS16480_DIAG_STAT_ZGYRO_FAIL 2
#define ADIS16480_DIAG_STAT_XACCL_FAIL 3
#define ADIS16480_DIAG_STAT_YACCL_FAIL 4
#define ADIS16480_DIAG_STAT_ZACCL_FAIL 5
#define ADIS16480_DIAG_STAT_XMAGN_FAIL 8
#define ADIS16480_DIAG_STAT_YMAGN_FAIL 9
#define ADIS16480_DIAG_STAT_ZMAGN_FAIL 10
#define ADIS16480_DIAG_STAT_BARO_FAIL 11
static const char * const adis16480_status_error_msgs[] = {
[ADIS16480_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
[ADIS16480_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
[ADIS16480_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
[ADIS16480_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
[ADIS16480_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
[ADIS16480_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
[ADIS16480_DIAG_STAT_XMAGN_FAIL] = "X-axis magnetometer self-test failure",
[ADIS16480_DIAG_STAT_YMAGN_FAIL] = "Y-axis magnetometer self-test failure",
[ADIS16480_DIAG_STAT_ZMAGN_FAIL] = "Z-axis magnetometer self-test failure",
[ADIS16480_DIAG_STAT_BARO_FAIL] = "Barometer self-test failure",
};
static const struct adis_data adis16480_data = {
.diag_stat_reg = ADIS16480_REG_DIAG_STS,
.glob_cmd_reg = ADIS16480_REG_GLOB_CMD,
.has_paging = true,
.read_delay = 5,
.write_delay = 5,
.status_error_msgs = adis16480_status_error_msgs,
.status_error_mask = BIT(ADIS16480_DIAG_STAT_XGYRO_FAIL) |
BIT(ADIS16480_DIAG_STAT_YGYRO_FAIL) |
BIT(ADIS16480_DIAG_STAT_ZGYRO_FAIL) |
BIT(ADIS16480_DIAG_STAT_XACCL_FAIL) |
BIT(ADIS16480_DIAG_STAT_YACCL_FAIL) |
BIT(ADIS16480_DIAG_STAT_ZACCL_FAIL) |
BIT(ADIS16480_DIAG_STAT_XMAGN_FAIL) |
BIT(ADIS16480_DIAG_STAT_YMAGN_FAIL) |
BIT(ADIS16480_DIAG_STAT_ZMAGN_FAIL) |
BIT(ADIS16480_DIAG_STAT_BARO_FAIL),
.enable_irq = adis16480_enable_irq,
};
static int adis16480_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct iio_dev *indio_dev;
struct adis16480 *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
spi_set_drvdata(spi, indio_dev);
st = iio_priv(indio_dev);
st->chip_info = &adis16480_chip_info[id->driver_data];
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->channels = st->chip_info->channels;
indio_dev->num_channels = st->chip_info->num_channels;
indio_dev->info = &adis16480_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
if (ret)
goto error_free_dev;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
ret = adis16480_initial_setup(indio_dev);
if (ret)
goto error_cleanup_buffer;
ret = iio_device_register(indio_dev);
if (ret)
goto error_stop_device;
adis16480_debugfs_init(indio_dev);
return 0;
error_stop_device:
adis16480_stop_device(indio_dev);
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
return ret;
}
static int adis16480_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adis16480 *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis16480_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
iio_device_free(indio_dev);
return 0;
}
static const struct spi_device_id adis16480_ids[] = {
{ "adis16375", ADIS16375 },
{ "adis16480", ADIS16480 },
{ "adis16485", ADIS16485 },
{ "adis16488", ADIS16488 },
{ }
};
MODULE_DEVICE_TABLE(spi, adis16480_ids);
static struct spi_driver adis16480_driver = {
.driver = {
.name = "adis16480",
.owner = THIS_MODULE,
},
.id_table = adis16480_ids,
.probe = adis16480_probe,
.remove = adis16480_remove,
};
module_spi_driver(adis16480_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,176 @@
/*
* Common library for ADIS16XXX devices
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/imu/adis.h>
int adis_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct adis *adis = iio_device_get_drvdata(indio_dev);
const struct iio_chan_spec *chan;
unsigned int scan_count;
unsigned int i, j;
__be16 *tx, *rx;
kfree(adis->xfer);
kfree(adis->buffer);
scan_count = indio_dev->scan_bytes / 2;
adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL);
if (!adis->xfer)
return -ENOMEM;
adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL);
if (!adis->buffer)
return -ENOMEM;
rx = adis->buffer;
tx = rx + indio_dev->scan_bytes;
spi_message_init(&adis->msg);
for (j = 0; j <= scan_count; j++) {
adis->xfer[j].bits_per_word = 8;
if (j != scan_count)
adis->xfer[j].cs_change = 1;
adis->xfer[j].len = 2;
adis->xfer[j].delay_usecs = adis->data->read_delay;
if (j < scan_count)
adis->xfer[j].tx_buf = &tx[j];
if (j >= 1)
adis->xfer[j].rx_buf = &rx[j - 1];
spi_message_add_tail(&adis->xfer[j], &adis->msg);
}
chan = indio_dev->channels;
for (i = 0; i < indio_dev->num_channels; i++, chan++) {
if (!test_bit(chan->scan_index, scan_mask))
continue;
if (chan->scan_type.storagebits == 32)
*tx++ = cpu_to_be16((chan->address + 2) << 8);
*tx++ = cpu_to_be16(chan->address << 8);
}
return 0;
}
EXPORT_SYMBOL_GPL(adis_update_scan_mode);
static irqreturn_t adis_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis *adis = iio_device_get_drvdata(indio_dev);
int ret;
if (!adis->buffer)
return -ENOMEM;
if (adis->data->has_paging) {
mutex_lock(&adis->txrx_lock);
if (adis->current_page != 0) {
adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
adis->tx[1] = 0;
spi_write(adis->spi, adis->tx, 2);
}
}
ret = spi_sync(adis->spi, &adis->msg);
if (ret)
dev_err(&adis->spi->dev, "Failed to read data: %d", ret);
if (adis->data->has_paging) {
adis->current_page = 0;
mutex_unlock(&adis->txrx_lock);
}
/* Guaranteed to be aligned with 8 byte boundary */
if (indio_dev->scan_timestamp) {
void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
*(s64 *)b = pf->timestamp;
}
iio_push_to_buffers(indio_dev, adis->buffer);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
/**
* adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device
* @adis: The adis device.
* @indio_dev: The IIO device.
* @trigger_handler: Optional trigger handler, may be NULL.
*
* Returns 0 on success, a negative error code otherwise.
*
* This function sets up the buffer and trigger for a adis devices. If
* 'trigger_handler' is NULL the default trigger handler will be used. The
* default trigger handler will simply read the registers assigned to the
* currently active channels.
*
* adis_cleanup_buffer_and_trigger() should be called to free the resources
* allocated by this function.
*/
int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
irqreturn_t (*trigger_handler)(int, void *))
{
int ret;
if (!trigger_handler)
trigger_handler = adis_trigger_handler;
ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
trigger_handler, NULL);
if (ret)
return ret;
if (adis->spi->irq) {
ret = adis_probe_trigger(adis, indio_dev);
if (ret)
goto error_buffer_cleanup;
}
return 0;
error_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
/**
* adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
* @adis: The adis device.
* @indio_dev: The IIO device.
*
* Frees resources allocated by adis_setup_buffer_and_trigger()
*/
void adis_cleanup_buffer_and_trigger(struct adis *adis,
struct iio_dev *indio_dev)
{
if (adis->spi->irq)
adis_remove_trigger(adis);
kfree(adis->buffer);
kfree(adis->xfer);
iio_triggered_buffer_cleanup(indio_dev);
}
EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger);

View File

@ -0,0 +1,89 @@
/*
* Common library for ADIS16XXX devices
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/export.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/imu/adis.h>
static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct adis *adis = trig->private_data;
return adis_enable_irq(adis, state);
}
static const struct iio_trigger_ops adis_trigger_ops = {
.owner = THIS_MODULE,
.set_trigger_state = &adis_data_rdy_trigger_set_state,
};
/**
* adis_probe_trigger() - Sets up trigger for a adis device
* @adis: The adis device
* @indio_dev: The IIO device
*
* Returns 0 on success or a negative error code
*
* adis_remove_trigger() should be used to free the trigger.
*/
int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
{
int ret;
adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
indio_dev->id);
if (adis->trig == NULL)
return -ENOMEM;
ret = request_irq(adis->spi->irq,
&iio_trigger_generic_data_rdy_poll,
IRQF_TRIGGER_RISING,
indio_dev->name,
adis->trig);
if (ret)
goto error_free_trig;
adis->trig->dev.parent = &adis->spi->dev;
adis->trig->ops = &adis_trigger_ops;
adis->trig->private_data = adis;
ret = iio_trigger_register(adis->trig);
indio_dev->trig = adis->trig;
if (ret)
goto error_free_irq;
return 0;
error_free_irq:
free_irq(adis->spi->irq, adis->trig);
error_free_trig:
iio_trigger_free(adis->trig);
return ret;
}
EXPORT_SYMBOL_GPL(adis_probe_trigger);
/**
* adis_remove_trigger() - Remove trigger for a adis devices
* @adis: The adis device
*
* Removes the trigger previously registered with adis_probe_trigger().
*/
void adis_remove_trigger(struct adis *adis)
{
iio_trigger_unregister(adis->trig);
free_irq(adis->spi->irq, adis->trig);
iio_trigger_free(adis->trig);
}
EXPORT_SYMBOL_GPL(adis_remove_trigger);

View File

@ -31,6 +31,18 @@ static const char * const iio_endian_prefix[] = {
[IIO_LE] = "le",
};
static bool iio_buffer_is_active(struct iio_dev *indio_dev,
struct iio_buffer *buf)
{
struct list_head *p;
list_for_each(p, &indio_dev->buffer_list)
if (p == &buf->buffer_list)
return true;
return false;
}
/**
* iio_buffer_read_first_n_outer() - chrdev read for buffer access
*
@ -134,7 +146,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
if (ret < 0)
return ret;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev)) {
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
@ -180,12 +192,11 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
return ret;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev)) {
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
indio_dev->buffer->scan_timestamp = state;
indio_dev->scan_timestamp = state;
error_ret:
mutex_unlock(&indio_dev->mlock);
@ -371,12 +382,12 @@ ssize_t iio_buffer_write_length(struct device *dev,
const char *buf,
size_t len)
{
int ret;
ulong val;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *buffer = indio_dev->buffer;
unsigned int val;
int ret;
ret = strict_strtoul(buf, 10, &val);
ret = kstrtouint(buf, 10, &val);
if (ret)
return ret;
@ -385,7 +396,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
return len;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev)) {
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
} else {
if (buffer->access->set_length)
@ -398,102 +409,14 @@ ssize_t iio_buffer_write_length(struct device *dev,
}
EXPORT_SYMBOL(iio_buffer_write_length);
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
bool requested_state, current_state;
int previous_mode;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *buffer = indio_dev->buffer;
mutex_lock(&indio_dev->mlock);
previous_mode = indio_dev->currentmode;
requested_state = !(buf[0] == '0');
current_state = iio_buffer_enabled(indio_dev);
if (current_state == requested_state) {
printk(KERN_INFO "iio-buffer, current state requested again\n");
goto done;
}
if (requested_state) {
if (indio_dev->setup_ops->preenable) {
ret = indio_dev->setup_ops->preenable(indio_dev);
if (ret) {
printk(KERN_ERR
"Buffer not started: "
"buffer preenable failed\n");
goto error_ret;
}
}
if (buffer->access->request_update) {
ret = buffer->access->request_update(buffer);
if (ret) {
printk(KERN_INFO
"Buffer not started: "
"buffer parameter update failed\n");
goto error_ret;
}
}
/* Definitely possible for devices to support both of these. */
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
if (!indio_dev->trig) {
printk(KERN_INFO
"Buffer not started: no trigger\n");
ret = -EINVAL;
goto error_ret;
}
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE)
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
else { /* should never be reached */
ret = -EINVAL;
goto error_ret;
}
if (indio_dev->setup_ops->postenable) {
ret = indio_dev->setup_ops->postenable(indio_dev);
if (ret) {
printk(KERN_INFO
"Buffer not started: "
"postenable failed\n");
indio_dev->currentmode = previous_mode;
if (indio_dev->setup_ops->postdisable)
indio_dev->setup_ops->
postdisable(indio_dev);
goto error_ret;
}
}
} else {
if (indio_dev->setup_ops->predisable) {
ret = indio_dev->setup_ops->predisable(indio_dev);
if (ret)
goto error_ret;
}
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->setup_ops->postdisable) {
ret = indio_dev->setup_ops->postdisable(indio_dev);
if (ret)
goto error_ret;
}
}
done:
mutex_unlock(&indio_dev->mlock);
return len;
error_ret:
mutex_unlock(&indio_dev->mlock);
return ret;
}
EXPORT_SYMBOL(iio_buffer_store_enable);
ssize_t iio_buffer_show_enable(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev));
return sprintf(buf, "%d\n",
iio_buffer_is_active(indio_dev,
indio_dev->buffer));
}
EXPORT_SYMBOL(iio_buffer_show_enable);
@ -537,35 +460,220 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
return bytes;
}
int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
int iio_update_buffers(struct iio_dev *indio_dev,
struct iio_buffer *insert_buffer,
struct iio_buffer *remove_buffer)
{
struct iio_buffer *buffer = indio_dev->buffer;
dev_dbg(&indio_dev->dev, "%s\n", __func__);
int ret;
int success = 0;
struct iio_buffer *buffer;
unsigned long *compound_mask;
const unsigned long *old_mask;
/* How much space will the demuxed element take? */
indio_dev->scan_bytes =
iio_compute_scan_bytes(indio_dev, buffer->scan_mask,
buffer->scan_timestamp);
buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes);
/* Wind down existing buffers - iff there are any */
if (!list_empty(&indio_dev->buffer_list)) {
if (indio_dev->setup_ops->predisable) {
ret = indio_dev->setup_ops->predisable(indio_dev);
if (ret)
goto error_ret;
}
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->setup_ops->postdisable) {
ret = indio_dev->setup_ops->postdisable(indio_dev);
if (ret)
goto error_ret;
}
}
/* Keep a copy of current setup to allow roll back */
old_mask = indio_dev->active_scan_mask;
if (!indio_dev->available_scan_masks)
indio_dev->active_scan_mask = NULL;
if (remove_buffer)
list_del(&remove_buffer->buffer_list);
if (insert_buffer)
list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
/* If no buffers in list, we are done */
if (list_empty(&indio_dev->buffer_list)) {
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->available_scan_masks == NULL)
kfree(old_mask);
return 0;
}
/* What scan mask do we actually have ?*/
if (indio_dev->available_scan_masks)
compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
sizeof(long), GFP_KERNEL);
if (compound_mask == NULL) {
if (indio_dev->available_scan_masks == NULL)
kfree(old_mask);
return -ENOMEM;
}
indio_dev->scan_timestamp = 0;
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
bitmap_or(compound_mask, compound_mask, buffer->scan_mask,
indio_dev->masklength);
indio_dev->scan_timestamp |= buffer->scan_timestamp;
}
if (indio_dev->available_scan_masks) {
indio_dev->active_scan_mask =
iio_scan_mask_match(indio_dev->available_scan_masks,
indio_dev->masklength,
buffer->scan_mask);
else
indio_dev->active_scan_mask = buffer->scan_mask;
if (indio_dev->active_scan_mask == NULL)
return -EINVAL;
compound_mask);
if (indio_dev->active_scan_mask == NULL) {
/*
* Roll back.
* Note can only occur when adding a buffer.
*/
list_del(&insert_buffer->buffer_list);
indio_dev->active_scan_mask = old_mask;
success = -EINVAL;
}
} else {
indio_dev->active_scan_mask = compound_mask;
}
iio_update_demux(indio_dev);
if (indio_dev->info->update_scan_mode)
return indio_dev->info
/* Wind up again */
if (indio_dev->setup_ops->preenable) {
ret = indio_dev->setup_ops->preenable(indio_dev);
if (ret) {
printk(KERN_ERR
"Buffer not started:"
"buffer preenable failed\n");
goto error_remove_inserted;
}
}
indio_dev->scan_bytes =
iio_compute_scan_bytes(indio_dev,
indio_dev->active_scan_mask,
indio_dev->scan_timestamp);
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
if (buffer->access->request_update) {
ret = buffer->access->request_update(buffer);
if (ret) {
printk(KERN_INFO
"Buffer not started:"
"buffer parameter update failed\n");
goto error_run_postdisable;
}
}
if (indio_dev->info->update_scan_mode) {
ret = indio_dev->info
->update_scan_mode(indio_dev,
indio_dev->active_scan_mask);
if (ret < 0) {
printk(KERN_INFO "update scan mode failed\n");
goto error_run_postdisable;
}
}
/* Definitely possible for devices to support both of these.*/
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
if (!indio_dev->trig) {
printk(KERN_INFO "Buffer not started: no trigger\n");
ret = -EINVAL;
/* Can only occur on first buffer */
goto error_run_postdisable;
}
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
} else { /* should never be reached */
ret = -EINVAL;
goto error_run_postdisable;
}
if (indio_dev->setup_ops->postenable) {
ret = indio_dev->setup_ops->postenable(indio_dev);
if (ret) {
printk(KERN_INFO
"Buffer not started: postenable failed\n");
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->setup_ops->postdisable)
indio_dev->setup_ops->postdisable(indio_dev);
goto error_disable_all_buffers;
}
}
if (indio_dev->available_scan_masks)
kfree(compound_mask);
else
kfree(old_mask);
return success;
error_disable_all_buffers:
indio_dev->currentmode = INDIO_DIRECT_MODE;
error_run_postdisable:
if (indio_dev->setup_ops->postdisable)
indio_dev->setup_ops->postdisable(indio_dev);
error_remove_inserted:
if (insert_buffer)
list_del(&insert_buffer->buffer_list);
indio_dev->active_scan_mask = old_mask;
kfree(compound_mask);
error_ret:
return ret;
}
EXPORT_SYMBOL_GPL(iio_update_buffers);
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
bool requested_state;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *pbuf = indio_dev->buffer;
bool inlist;
ret = strtobool(buf, &requested_state);
if (ret < 0)
return ret;
mutex_lock(&indio_dev->mlock);
/* Find out if it is in the list */
inlist = iio_buffer_is_active(indio_dev, pbuf);
/* Already in desired state */
if (inlist == requested_state)
goto done;
if (requested_state)
ret = iio_update_buffers(indio_dev,
indio_dev->buffer, NULL);
else
ret = iio_update_buffers(indio_dev,
NULL, indio_dev->buffer);
if (ret < 0)
goto done;
done:
mutex_unlock(&indio_dev->mlock);
return (ret < 0) ? ret : len;
}
EXPORT_SYMBOL(iio_buffer_store_enable);
int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
{
struct iio_buffer *buffer;
unsigned bytes;
dev_dbg(&indio_dev->dev, "%s\n", __func__);
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
if (buffer->access->set_bytes_per_datum) {
bytes = iio_compute_scan_bytes(indio_dev,
buffer->scan_mask,
buffer->scan_timestamp);
buffer->access->set_bytes_per_datum(buffer, bytes);
}
return 0;
}
EXPORT_SYMBOL(iio_sw_buffer_preenable);
@ -599,7 +707,11 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
* iio_scan_mask_set() - set particular bit in the scan mask
* @buffer: the buffer whose scan mask we are interested in
* @bit: the bit to be set.
**/
*
* Note that at this point we have no way of knowing what other
* buffers might request, hence this code only verifies that the
* individual buffers request is plausible.
*/
int iio_scan_mask_set(struct iio_dev *indio_dev,
struct iio_buffer *buffer, int bit)
{
@ -682,13 +794,12 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
return buffer->demux_bounce;
}
int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
{
unsigned char *dataout = iio_demux(buffer, data);
return buffer->access->store_to(buffer, dataout);
}
EXPORT_SYMBOL_GPL(iio_push_to_buffer);
static void iio_buffer_demux_free(struct iio_buffer *buffer)
{
@ -699,10 +810,26 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
}
}
int iio_update_demux(struct iio_dev *indio_dev)
int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
{
int ret;
struct iio_buffer *buf;
list_for_each_entry(buf, &indio_dev->buffer_list, buffer_list) {
ret = iio_push_to_buffer(buf, data);
if (ret < 0)
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(iio_push_to_buffers);
static int iio_buffer_update_demux(struct iio_dev *indio_dev,
struct iio_buffer *buffer)
{
const struct iio_chan_spec *ch;
struct iio_buffer *buffer = indio_dev->buffer;
int ret, in_ind = -1, out_ind, length;
unsigned in_loc = 0, out_loc = 0;
struct iio_demux_table *p;
@ -787,4 +914,23 @@ error_clear_mux_table:
return ret;
}
int iio_update_demux(struct iio_dev *indio_dev)
{
struct iio_buffer *buffer;
int ret;
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
ret = iio_buffer_update_demux(indio_dev, buffer);
if (ret < 0)
goto error_clear_mux_table;
}
return 0;
error_clear_mux_table:
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
iio_buffer_demux_free(buffer);
return ret;
}
EXPORT_SYMBOL_GPL(iio_update_demux);

View File

@ -65,6 +65,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CAPACITANCE] = "capacitance",
[IIO_ALTVOLTAGE] = "altvoltage",
[IIO_CCT] = "cct",
[IIO_PRESSURE] = "pressure",
};
static const char * const iio_modifier_names[] = {
@ -397,11 +398,74 @@ static ssize_t iio_read_channel_info(struct device *dev,
val2 = do_div(tmp, 1000000000LL);
val = tmp;
return sprintf(buf, "%d.%09u\n", val, val2);
case IIO_VAL_FRACTIONAL_LOG2:
tmp = (s64)val * 1000000000LL >> val2;
val2 = do_div(tmp, 1000000000LL);
val = tmp;
return sprintf(buf, "%d.%09u\n", val, val2);
default:
return 0;
}
}
/**
* iio_str_to_fixpoint() - Parse a fixed-point number from a string
* @str: The string to parse
* @fract_mult: Multiplier for the first decimal place, should be a power of 10
* @integer: The integer part of the number
* @fract: The fractional part of the number
*
* Returns 0 on success, or a negative error code if the string could not be
* parsed.
*/
int iio_str_to_fixpoint(const char *str, int fract_mult,
int *integer, int *fract)
{
int i = 0, f = 0;
bool integer_part = true, negative = false;
if (str[0] == '-') {
negative = true;
str++;
} else if (str[0] == '+') {
str++;
}
while (*str) {
if ('0' <= *str && *str <= '9') {
if (integer_part) {
i = i * 10 + *str - '0';
} else {
f += fract_mult * (*str - '0');
fract_mult /= 10;
}
} else if (*str == '\n') {
if (*(str + 1) == '\0')
break;
else
return -EINVAL;
} else if (*str == '.' && integer_part) {
integer_part = false;
} else {
return -EINVAL;
}
str++;
}
if (negative) {
if (i)
i = -i;
else
f = -f;
}
*integer = i;
*fract = f;
return 0;
}
EXPORT_SYMBOL_GPL(iio_str_to_fixpoint);
static ssize_t iio_write_channel_info(struct device *dev,
struct device_attribute *attr,
const char *buf,
@ -409,8 +473,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret, integer = 0, fract = 0, fract_mult = 100000;
bool integer_part = true, negative = false;
int ret, fract_mult = 100000;
int integer, fract;
/* Assumes decimal - precision based on number of digits */
if (!indio_dev->info->write_raw)
@ -429,39 +493,9 @@ static ssize_t iio_write_channel_info(struct device *dev,
return -EINVAL;
}
if (buf[0] == '-') {
negative = true;
buf++;
}
while (*buf) {
if ('0' <= *buf && *buf <= '9') {
if (integer_part)
integer = integer*10 + *buf - '0';
else {
fract += fract_mult*(*buf - '0');
if (fract_mult == 1)
break;
fract_mult /= 10;
}
} else if (*buf == '\n') {
if (*(buf + 1) == '\0')
break;
else
return -EINVAL;
} else if (*buf == '.') {
integer_part = false;
} else {
return -EINVAL;
}
buf++;
}
if (negative) {
if (integer)
integer = -integer;
else
fract = -fract;
}
ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
if (ret)
return ret;
ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
integer, fract, this_attr->address);
@ -851,6 +885,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
return NULL;
}
dev_set_name(&dev->dev, "iio:device%d", dev->id);
INIT_LIST_HEAD(&dev->buffer_list);
}
return dev;

View File

@ -239,13 +239,13 @@ static ssize_t iio_ev_value_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
unsigned long val;
int val;
int ret;
if (!indio_dev->info->write_event_value)
return -EINVAL;
ret = strict_strtoul(buf, 10, &val);
ret = kstrtoint(buf, 10, &val);
if (ret)
return ret;
@ -350,15 +350,10 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
ret = iio_device_add_event_sysfs(indio_dev,
&indio_dev->channels[j]);
if (ret < 0)
goto error_clear_attrs;
return ret;
attrcount += ret;
}
return attrcount;
error_clear_attrs:
__iio_remove_event_config_attrs(indio_dev);
return ret;
}
static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)

View File

@ -78,7 +78,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev,
found_it = true;
break;
}
if (found_it == false) {
if (!found_it) {
ret = -ENODEV;
goto error_ret;
}
@ -203,6 +203,7 @@ struct iio_channel *iio_channel_get_all(const char *name)
if (name && strcmp(name, c->map->consumer_dev_name) != 0)
continue;
chans[mapind].indio_dev = c->indio_dev;
chans[mapind].data = c->map->consumer_data;
chans[mapind].channel =
iio_chan_spec_from_name(chans[mapind].indio_dev,
c->map->adc_channel_label);
@ -314,6 +315,9 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
*processed = div_s64(raw64 * (s64)scale_val * scale,
scale_val2);
break;
case IIO_VAL_FRACTIONAL_LOG2:
*processed = (raw64 * (s64)scale_val * scale) >> scale_val2;
break;
default:
return -EINVAL;
}

View File

@ -164,7 +164,6 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adjd_s311_data *data = iio_priv(indio_dev);
struct iio_buffer *buffer = indio_dev->buffer;
s64 time_ns = iio_get_time_ns();
int len = 0;
int i, j = 0;
@ -187,7 +186,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
= time_ns;
iio_push_to_buffer(buffer, (u8 *)data->buffer);
iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
done:
iio_trigger_notify_done(indio_dev->trig);

View File

@ -176,21 +176,8 @@ static const struct iio_info als_info = {
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) {
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@ -285,10 +272,9 @@ static int __devinit hid_als_probe(struct platform_device *pdev)
goto error_free_dev;
}
channels = kmemdup(als_channels,
sizeof(als_channels),
GFP_KERNEL);
channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}

View File

@ -198,21 +198,8 @@ static const struct iio_info magn_3d_info = {
/* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) {
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */
@ -320,10 +307,10 @@ static int __devinit hid_magn_3d_probe(struct platform_device *pdev)
goto error_free_dev;
}
channels = kmemdup(magn_3d_channels,
sizeof(magn_3d_channels),
GFP_KERNEL);
channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
}

24
drivers/ipack/Kconfig Normal file
View File

@ -0,0 +1,24 @@
#
# IPACK configuration.
#
menuconfig IPACK_BUS
tristate "IndustryPack bus support"
depends on HAS_IOMEM
---help---
This option provides support for the IndustryPack framework. There
are IndustryPack carrier boards, which interface another bus (such as
PCI) to an IndustryPack bus, and IndustryPack modules, that are
hosted on these buses. While IndustryPack modules can provide a
large variety of functionality, they are most often found in
industrial control applications.
Say N if unsure.
if IPACK_BUS
source "drivers/ipack/carriers/Kconfig"
source "drivers/ipack/devices/Kconfig"
endif # IPACK

View File

@ -3,4 +3,4 @@
#
obj-$(CONFIG_IPACK_BUS) += ipack.o
obj-y += devices/
obj-y += bridges/
obj-y += carriers/

View File

@ -0,0 +1,7 @@
config BOARD_TPCI200
tristate "Support for the TEWS TPCI-200 IndustryPack carrier board"
depends on IPACK_BUS
depends on PCI
help
This driver adds support for the TEWS TPCI200 IndustryPack carrier board.
default n

View File

@ -2,9 +2,10 @@
* tpci200.c
*
* driver for the TEWS TPCI-200 device
* Copyright (c) 2009 Nicolas Serafini, EIC2 SA
* Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
*
* Copyright (C) 2009-2012 CERN (www.cern.ch)
* Author: Nicolas Serafini, EIC2 SA
* Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@ -15,20 +16,36 @@
#include <linux/slab.h>
#include "tpci200.h"
static u16 tpci200_status_timeout[] = {
static const u16 tpci200_status_timeout[] = {
TPCI200_A_TIMEOUT,
TPCI200_B_TIMEOUT,
TPCI200_C_TIMEOUT,
TPCI200_D_TIMEOUT,
};
static u16 tpci200_status_error[] = {
static const u16 tpci200_status_error[] = {
TPCI200_A_ERROR,
TPCI200_B_ERROR,
TPCI200_C_ERROR,
TPCI200_D_ERROR,
};
static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
[IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
[IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
[IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
[IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
[IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
};
static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
[IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
[IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
[IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
[IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
[IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
};
static struct tpci200_board *check_slot(struct ipack_device *dev)
{
struct tpci200_board *tpci200;
@ -47,7 +64,7 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
if (dev->slot >= TPCI200_NB_SLOT) {
dev_info(&dev->dev,
"Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
return NULL;
}
@ -74,33 +91,19 @@ static void tpci200_set_mask(struct tpci200_board *tpci200,
static void tpci200_unregister(struct tpci200_board *tpci200)
{
int i;
free_irq(tpci200->info->pdev->irq, (void *) tpci200);
pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space);
pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space);
pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
pci_disable_device(tpci200->info->pdev);
pci_dev_put(tpci200->info->pdev);
for (i = 0; i < TPCI200_NB_SLOT; i++) {
tpci200->slots[i].io_phys.address = NULL;
tpci200->slots[i].io_phys.size = 0;
tpci200->slots[i].id_phys.address = NULL;
tpci200->slots[i].id_phys.size = 0;
tpci200->slots[i].int_phys.address = NULL;
tpci200->slots[i].int_phys.size = 0;
tpci200->slots[i].mem_phys.address = NULL;
tpci200->slots[i].mem_phys.size = 0;
}
}
static void tpci200_enable_irq(struct tpci200_board *tpci200,
@ -207,7 +210,8 @@ static int tpci200_request_irq(struct ipack_device *dev,
if (tpci200->slots[dev->slot].irq != NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] IRQ already registered !\n", dev->bus_nr,
"Slot [%d:%d] IRQ already registered !\n",
dev->bus->bus_nr,
dev->slot);
res = -EINVAL;
goto out_unlock;
@ -217,7 +221,7 @@ static int tpci200_request_irq(struct ipack_device *dev,
if (slot_irq == NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] unable to allocate memory for IRQ !\n",
dev->bus_nr, dev->slot);
dev->bus->bus_nr, dev->slot);
res = -ENOMEM;
goto out_unlock;
}
@ -244,8 +248,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
{
int i;
int res;
unsigned long ioidint_base;
unsigned long mem_base;
phys_addr_t ioidint_base;
unsigned short slot_ctrl;
if (pci_enable_device(tpci200->info->pdev) < 0)
@ -274,15 +277,26 @@ static int tpci200_register(struct tpci200_board *tpci200)
goto out_release_ip_space;
}
/* Request MEM space (Bar 4) */
/* Request MEM8 space (Bar 5) */
res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
"Carrier MEM space");
"Carrier MEM8 space");
if (res) {
dev_err(&tpci200->info->pdev->dev,
"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
tpci200->info->pdev->bus->number,
tpci200->info->pdev->devfn);
goto out_release_ioid_int_space;
}
/* Request MEM16 space (Bar 4) */
res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
"Carrier MEM16 space");
if (res) {
dev_err(&tpci200->info->pdev->dev,
"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
tpci200->info->pdev->bus->number,
tpci200->info->pdev->devfn);
goto out_release_ioid_int_space;
goto out_release_mem8_space;
}
/* Map internal tpci200 driver user space */
@ -290,22 +304,22 @@ static int tpci200_register(struct tpci200_board *tpci200)
ioremap_nocache(pci_resource_start(tpci200->info->pdev,
TPCI200_IP_INTERFACE_BAR),
TPCI200_IFACE_SIZE);
tpci200->info->ioidint_space =
ioremap_nocache(pci_resource_start(tpci200->info->pdev,
TPCI200_IO_ID_INT_SPACES_BAR),
TPCI200_IOIDINT_SIZE);
tpci200->info->mem8_space =
ioremap_nocache(pci_resource_start(tpci200->info->pdev,
TPCI200_MEM8_SPACE_BAR),
TPCI200_MEM8_SIZE);
/* Initialize lock that protects interface_regs */
spin_lock_init(&tpci200->regs_lock);
ioidint_base = pci_resource_start(tpci200->info->pdev,
TPCI200_IO_ID_INT_SPACES_BAR);
mem_base = pci_resource_start(tpci200->info->pdev,
TPCI200_MEM8_SPACE_BAR);
tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
tpci200->mod_mem[IPACK_INT_SPACE] =
ioidint_base + TPCI200_INT_SPACE_OFF;
tpci200->mod_mem[IPACK_MEM8_SPACE] =
pci_resource_start(tpci200->info->pdev,
TPCI200_MEM8_SPACE_BAR);
tpci200->mod_mem[IPACK_MEM16_SPACE] =
pci_resource_start(tpci200->info->pdev,
TPCI200_MEM16_SPACE_BAR);
/* Set the default parameters of the slot
* INT0 disabled, level sensitive
@ -316,30 +330,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
* clock rate 8 MHz
*/
slot_ctrl = 0;
/* Set all slot physical address space */
for (i = 0; i < TPCI200_NB_SLOT; i++) {
tpci200->slots[i].io_phys.address =
(void __iomem *)ioidint_base +
TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i;
tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE;
tpci200->slots[i].id_phys.address =
(void __iomem *)ioidint_base +
TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i;
tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE;
tpci200->slots[i].int_phys.address =
(void __iomem *)ioidint_base +
TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i;
tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE;
tpci200->slots[i].mem_phys.address =
(void __iomem *)mem_base + TPCI200_MEM8_GAP*i;
tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE;
for (i = 0; i < TPCI200_NB_SLOT; i++)
writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
}
res = request_irq(tpci200->info->pdev->irq,
tpci200_interrupt, IRQF_SHARED,
@ -354,6 +346,8 @@ static int tpci200_register(struct tpci200_board *tpci200)
return 0;
out_release_mem8_space:
pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
out_release_ioid_int_space:
pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
out_release_ip_space:
@ -363,166 +357,6 @@ out_disable_pci:
return res;
}
static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
{
struct ipack_addr_space *virt_addr_space;
struct tpci200_board *tpci200;
tpci200 = check_slot(dev);
if (tpci200 == NULL)
return -EINVAL;
if (mutex_lock_interruptible(&tpci200->mutex))
return -ERESTARTSYS;
switch (space) {
case IPACK_IO_SPACE:
if (dev->io_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] IO space not mapped !\n",
dev->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->io_space;
break;
case IPACK_ID_SPACE:
if (dev->id_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] ID space not mapped !\n",
dev->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->id_space;
break;
case IPACK_INT_SPACE:
if (dev->int_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] INT space not mapped !\n",
dev->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->int_space;
break;
case IPACK_MEM_SPACE:
if (dev->mem_space.address == NULL) {
dev_info(&dev->dev,
"Slot [%d:%d] MEM space not mapped !\n",
dev->bus_nr, dev->slot);
goto out_unlock;
}
virt_addr_space = &dev->mem_space;
break;
default:
dev_err(&dev->dev,
"Slot [%d:%d] space number %d doesn't exist !\n",
dev->bus_nr, dev->slot, space);
mutex_unlock(&tpci200->mutex);
return -EINVAL;
}
iounmap(virt_addr_space->address);
virt_addr_space->address = NULL;
virt_addr_space->size = 0;
out_unlock:
mutex_unlock(&tpci200->mutex);
return 0;
}
static int tpci200_slot_map_space(struct ipack_device *dev,
unsigned int memory_size, int space)
{
int res = 0;
unsigned int size_to_map;
void __iomem *phys_address;
struct ipack_addr_space *virt_addr_space;
struct tpci200_board *tpci200;
tpci200 = check_slot(dev);
if (tpci200 == NULL)
return -EINVAL;
if (mutex_lock_interruptible(&tpci200->mutex))
return -ERESTARTSYS;
switch (space) {
case IPACK_IO_SPACE:
if (dev->io_space.address != NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] IO space already mapped !\n",
tpci200->number, dev->slot);
res = -EINVAL;
goto out_unlock;
}
virt_addr_space = &dev->io_space;
phys_address = tpci200->slots[dev->slot].io_phys.address;
size_to_map = tpci200->slots[dev->slot].io_phys.size;
break;
case IPACK_ID_SPACE:
if (dev->id_space.address != NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] ID space already mapped !\n",
tpci200->number, dev->slot);
res = -EINVAL;
goto out_unlock;
}
virt_addr_space = &dev->id_space;
phys_address = tpci200->slots[dev->slot].id_phys.address;
size_to_map = tpci200->slots[dev->slot].id_phys.size;
break;
case IPACK_INT_SPACE:
if (dev->int_space.address != NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] INT space already mapped !\n",
tpci200->number, dev->slot);
res = -EINVAL;
goto out_unlock;
}
virt_addr_space = &dev->int_space;
phys_address = tpci200->slots[dev->slot].int_phys.address;
size_to_map = tpci200->slots[dev->slot].int_phys.size;
break;
case IPACK_MEM_SPACE:
if (dev->mem_space.address != NULL) {
dev_err(&dev->dev,
"Slot [%d:%d] MEM space already mapped !\n",
tpci200->number, dev->slot);
res = -EINVAL;
goto out_unlock;
}
virt_addr_space = &dev->mem_space;
if (memory_size > tpci200->slots[dev->slot].mem_phys.size) {
dev_err(&dev->dev,
"Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n",
dev->bus_nr, dev->slot, memory_size,
tpci200->slots[dev->slot].mem_phys.size);
res = -EINVAL;
goto out_unlock;
}
phys_address = tpci200->slots[dev->slot].mem_phys.address;
size_to_map = memory_size;
break;
default:
dev_err(&dev->dev, "Slot [%d:%d] space %d doesn't exist !\n",
tpci200->number, dev->slot, space);
res = -EINVAL;
goto out_unlock;
}
virt_addr_space->size = size_to_map;
virt_addr_space->address =
ioremap_nocache((unsigned long)phys_address, size_to_map);
out_unlock:
mutex_unlock(&tpci200->mutex);
return res;
}
static int tpci200_get_clockrate(struct ipack_device *dev)
{
struct tpci200_board *tpci200 = check_slot(dev);
@ -610,8 +444,6 @@ static void tpci200_uninstall(struct tpci200_board *tpci200)
}
static const struct ipack_bus_ops tpci200_bus_ops = {
.map_space = tpci200_slot_map_space,
.unmap_space = tpci200_slot_unmap_space,
.request_irq = tpci200_request_irq,
.free_irq = tpci200_free_irq,
.get_clockrate = tpci200_get_clockrate,
@ -641,6 +473,31 @@ static int tpci200_install(struct tpci200_board *tpci200)
return 0;
}
static void tpci200_release_device(struct ipack_device *dev)
{
kfree(dev);
}
static int tpci200_create_device(struct tpci200_board *tpci200, int i)
{
enum ipack_space space;
struct ipack_device *dev =
kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->slot = i;
dev->bus = tpci200->info->ipack_bus;
dev->release = tpci200_release_device;
for (space = 0; space < IPACK_SPACE_COUNT; space++) {
dev->region[space].start =
tpci200->mod_mem[space]
+ tpci200_space_interval[space] * i;
dev->region[space].size = tpci200_space_size[space];
}
return ipack_device_register(dev);
}
static int tpci200_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@ -716,7 +573,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
dev_set_drvdata(&pdev->dev, tpci200);
for (i = 0; i < TPCI200_NB_SLOT; i++)
ipack_device_register(tpci200->info->ipack_bus, i);
tpci200_create_device(tpci200, i);
return 0;
out_err_bus_register:
@ -742,7 +599,7 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200)
kfree(tpci200);
}
static void __devexit tpci200_pci_remove(struct pci_dev *dev)
static void tpci200_pci_remove(struct pci_dev *dev)
{
struct tpci200_board *tpci200 = pci_get_drvdata(dev);
@ -761,20 +618,10 @@ static struct pci_driver tpci200_pci_drv = {
.name = "tpci200",
.id_table = tpci200_idtable,
.probe = tpci200_pci_probe,
.remove = __devexit_p(tpci200_pci_remove),
.remove = tpci200_pci_remove,
};
static int __init tpci200_drvr_init_module(void)
{
return pci_register_driver(&tpci200_pci_drv);
}
static void __exit tpci200_drvr_exit_module(void)
{
pci_unregister_driver(&tpci200_pci_drv);
}
module_pci_driver(tpci200_pci_drv);
MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
MODULE_LICENSE("GPL");
module_init(tpci200_drvr_init_module);
module_exit(tpci200_drvr_exit_module);

View File

@ -2,9 +2,10 @@
* tpci200.h
*
* driver for the carrier TEWS TPCI-200
* Copyright (c) 2009 Nicolas Serafini, EIC2 SA
* Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
*
* Copyright (C) 2009-2012 CERN (www.cern.ch)
* Author: Nicolas Serafini, EIC2 SA
* Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@ -19,8 +20,7 @@
#include <linux/spinlock.h>
#include <linux/swab.h>
#include <linux/io.h>
#include "../ipack.h"
#include <linux/ipack.h>
#define TPCI200_NB_SLOT 0x4
#define TPCI200_NB_BAR 0x6
@ -49,20 +49,20 @@ struct tpci200_regs {
#define TPCI200_IFACE_SIZE 0x100
#define TPCI200_IO_SPACE_OFF 0x0000
#define TPCI200_IO_SPACE_GAP 0x0100
#define TPCI200_IO_SPACE_INTERVAL 0x0100
#define TPCI200_IO_SPACE_SIZE 0x0080
#define TPCI200_ID_SPACE_OFF 0x0080
#define TPCI200_ID_SPACE_GAP 0x0100
#define TPCI200_ID_SPACE_INTERVAL 0x0100
#define TPCI200_ID_SPACE_SIZE 0x0040
#define TPCI200_INT_SPACE_OFF 0x00C0
#define TPCI200_INT_SPACE_GAP 0x0100
#define TPCI200_INT_SPACE_INTERVAL 0x0100
#define TPCI200_INT_SPACE_SIZE 0x0040
#define TPCI200_IOIDINT_SIZE 0x0400
#define TPCI200_MEM8_GAP 0x00400000
#define TPCI200_MEM8_SIZE 0x00400000
#define TPCI200_MEM16_GAP 0x00800000
#define TPCI200_MEM16_SIZE 0x00800000
#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000
#define TPCI200_MEM8_SPACE_SIZE 0x00400000
#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000
#define TPCI200_MEM16_SPACE_SIZE 0x00800000
/* control field in tpci200_regs */
#define TPCI200_INT0_EN 0x0040
@ -137,11 +137,7 @@ struct slot_irq {
*
*/
struct tpci200_slot {
struct slot_irq *irq;
struct ipack_addr_space io_phys;
struct ipack_addr_space id_phys;
struct ipack_addr_space int_phys;
struct ipack_addr_space mem_phys;
struct slot_irq *irq;
};
/**
@ -156,8 +152,6 @@ struct tpci200_infos {
struct pci_dev *pdev;
struct pci_device_id *id_table;
struct tpci200_regs __iomem *interface_regs;
void __iomem *ioidint_space;
void __iomem *mem8_space;
void __iomem *cfg_regs;
struct ipack_bus_device *ipack_bus;
};
@ -167,6 +161,7 @@ struct tpci200_board {
spinlock_t regs_lock;
struct tpci200_slot *slots;
struct tpci200_infos *info;
phys_addr_t mod_mem[IPACK_SPACE_COUNT];
};
#endif /* _TPCI200_H_ */

View File

@ -4,4 +4,3 @@ config SERIAL_IPOCTAL
help
This driver supports the IPOCTAL serial port device for the IndustryPack bus.
default n

View File

@ -2,9 +2,10 @@
* ipoctal.c
*
* driver for the GE IP-OCTAL boards
* Copyright (c) 2009 Nicolas Serafini, EIC2 SA
* Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
*
* Copyright (C) 2009-2012 CERN (www.cern.ch)
* Author: Nicolas Serafini, EIC2 SA
* Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@ -21,7 +22,7 @@
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/io.h>
#include "../ipack.h"
#include <linux/ipack.h>
#include "ipoctal.h"
#include "scc2698.h"
@ -53,6 +54,8 @@ struct ipoctal {
struct ipoctal_channel channel[NR_CHANNELS];
unsigned char write;
struct tty_driver *tty_drv;
u8 __iomem *mem8_space;
u8 __iomem *int_space;
};
static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
@ -252,35 +255,12 @@ static irqreturn_t ipoctal_irq_handler(void *arg)
ipoctal_irq_channel(&ipoctal->channel[i]);
/* Clear the IPack device interrupt */
readw(ipoctal->dev->int_space.address + ACK_INT_REQ0);
readw(ipoctal->dev->int_space.address + ACK_INT_REQ1);
readw(ipoctal->int_space + ACK_INT_REQ0);
readw(ipoctal->int_space + ACK_INT_REQ1);
return IRQ_HANDLED;
}
static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id)
{
unsigned char manufacturerID;
unsigned char board_id;
manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID);
if (manufacturerID != IPACK1_VENDOR_ID_SBS)
return -ENODEV;
board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL);
switch (board_id) {
case IPACK1_DEVICE_ID_SBS_OCTAL_232:
case IPACK1_DEVICE_ID_SBS_OCTAL_422:
case IPACK1_DEVICE_ID_SBS_OCTAL_485:
*id = board_id;
break;
default:
return -ENODEV;
}
return 0;
}
static const struct tty_port_operations ipoctal_tty_port_ops = {
.dtr_rts = NULL,
.activate = ipoctal_port_activate,
@ -289,64 +269,55 @@ static const struct tty_port_operations ipoctal_tty_port_ops = {
static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
unsigned int slot)
{
int res = 0;
int res;
int i;
struct tty_driver *tty;
char name[20];
unsigned char board_id;
struct ipoctal_channel *channel;
struct ipack_region *region;
void __iomem *addr;
union scc2698_channel __iomem *chan_regs;
union scc2698_block __iomem *block_regs;
res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
IPACK_ID_SPACE);
if (res) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] ID space!\n",
bus_nr, slot);
return res;
}
ipoctal->board_id = ipoctal->dev->id_device;
res = ipoctal_check_model(ipoctal->dev, &board_id);
if (res) {
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev,
IPACK_ID_SPACE);
goto out_unregister_id_space;
}
ipoctal->board_id = board_id;
res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
IPACK_IO_SPACE);
if (res) {
region = &ipoctal->dev->region[IPACK_IO_SPACE];
addr = devm_ioremap_nocache(&ipoctal->dev->dev,
region->start, region->size);
if (!addr) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] IO space!\n",
bus_nr, slot);
goto out_unregister_id_space;
return -EADDRNOTAVAIL;
}
/* Save the virtual address to access the registers easily */
chan_regs =
(union scc2698_channel __iomem *) addr;
block_regs =
(union scc2698_block __iomem *) addr;
res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
IPACK_INT_SPACE);
if (res) {
region = &ipoctal->dev->region[IPACK_INT_SPACE];
ipoctal->int_space =
devm_ioremap_nocache(&ipoctal->dev->dev,
region->start, region->size);
if (!ipoctal->int_space) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] INT space!\n",
bus_nr, slot);
goto out_unregister_io_space;
return -EADDRNOTAVAIL;
}
res = ipoctal->dev->bus->ops->map_space(ipoctal->dev,
0x8000, IPACK_MEM_SPACE);
if (res) {
region = &ipoctal->dev->region[IPACK_MEM8_SPACE];
ipoctal->mem8_space =
devm_ioremap_nocache(&ipoctal->dev->dev,
region->start, 0x8000);
if (!addr) {
dev_err(&ipoctal->dev->dev,
"Unable to map slot [%d:%d] MEM space!\n",
"Unable to map slot [%d:%d] MEM8 space!\n",
bus_nr, slot);
goto out_unregister_int_space;
return -EADDRNOTAVAIL;
}
/* Save the virtual address to access the registers easily */
chan_regs =
(union scc2698_channel __iomem *) ipoctal->dev->io_space.address;
block_regs =
(union scc2698_block __iomem *) ipoctal->dev->io_space.address;
/* Disable RX and TX before touching anything */
for (i = 0; i < NR_CHANNELS ; i++) {
@ -389,17 +360,15 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
ipoctal_irq_handler, ipoctal);
/* Dummy write */
iowrite8(1, ipoctal->dev->mem_space.address + 1);
iowrite8(1, ipoctal->mem8_space + 1);
/* Register the TTY device */
/* Each IP-OCTAL channel is a TTY port */
tty = alloc_tty_driver(NR_CHANNELS);
if (!tty) {
res = -ENOMEM;
goto out_unregister_slot_unmap;
}
if (!tty)
return -ENOMEM;
/* Fill struct tty_driver with ipoctal data */
tty->owner = THIS_MODULE;
@ -422,7 +391,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
if (res) {
dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
put_tty_driver(tty);
goto out_unregister_slot_unmap;
return res;
}
/* Save struct tty_driver for use it when uninstalling the device */
@ -458,16 +427,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
}
return 0;
out_unregister_slot_unmap:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
out_unregister_int_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
out_unregister_io_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
out_unregister_id_space:
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
return res;
}
static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
@ -719,7 +678,7 @@ static int ipoctal_probe(struct ipack_device *dev)
return -ENOMEM;
ipoctal->dev = dev;
res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot);
res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot);
if (res)
goto out_uninst;
@ -745,10 +704,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
tty_unregister_driver(ipoctal->tty_drv);
put_tty_driver(ipoctal->tty_drv);
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE);
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
kfree(ipoctal);
}

View File

@ -2,9 +2,10 @@
* ipoctal.h
*
* driver for the IPOCTAL boards
* Copyright (c) 2009 Nicolas Serafini, EIC2 SA
* Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
* Copyright (C) 2009-2012 CERN (www.cern.ch)
* Author: Nicolas Serafini, EIC2 SA
* Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free

View File

@ -2,9 +2,10 @@
* scc2698.h
*
* driver for the IPOCTAL boards
* Copyright (c) 2009 Nicolas Serafini, EIC2 SA
* Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
*
* Copyright (C) 2009-2012 CERN (www.cern.ch)
* Author: Nicolas Serafini, EIC2 SA
* Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free

View File

@ -1,8 +1,8 @@
/*
* Industry-pack bus support functions.
*
* (C) 2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* (C) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
* Copyright (C) 2011-2012 CERN (www.cern.ch)
* Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@ -12,8 +12,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/idr.h>
#include <asm/io.h>
#include "ipack.h"
#include <linux/io.h>
#include <linux/ipack.h>
#define to_ipack_dev(device) container_of(device, struct ipack_device, dev)
#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver)
@ -24,7 +24,7 @@ static void ipack_device_release(struct device *dev)
{
struct ipack_device *device = to_ipack_dev(dev);
kfree(device->id);
kfree(device);
device->release(device);
}
static inline const struct ipack_device_id *
@ -85,8 +85,6 @@ static int ipack_bus_remove(struct device *device)
return 0;
}
#ifdef CONFIG_HOTPLUG
static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct ipack_device *idev;
@ -104,12 +102,6 @@ static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
#else /* !CONFIG_HOTPLUG */
#define ipack_uevent NULL
#endif /* !CONFIG_HOTPLUG */
#define ipack_device_attr(field, format_string) \
static ssize_t \
field##_show(struct device *dev, struct device_attribute *attr, \
@ -234,7 +226,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data)
struct ipack_device *idev = to_ipack_dev(dev);
struct ipack_bus_device *bus = data;
if (idev->bus_nr == bus->bus_nr)
if (idev->bus == bus)
ipack_device_unregister(idev);
return 1;
@ -242,7 +234,8 @@ static int ipack_unregister_bus_member(struct device *dev, void *data)
int ipack_bus_unregister(struct ipack_bus_device *bus)
{
bus_for_each_dev(&ipack_bus_type, NULL, bus, ipack_unregister_bus_member);
bus_for_each_dev(&ipack_bus_type, NULL, bus,
ipack_unregister_bus_member);
ida_simple_remove(&ipack_ida, bus->bus_nr);
kfree(bus);
return 0;
@ -351,12 +344,12 @@ static int ipack_device_read_id(struct ipack_device *dev)
int i;
int ret = 0;
ret = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
if (ret) {
idmem = ioremap(dev->region[IPACK_ID_SPACE].start,
dev->region[IPACK_ID_SPACE].size);
if (!idmem) {
dev_err(&dev->dev, "error mapping memory\n");
return ret;
return -ENOMEM;
}
idmem = dev->id_space.address;
/* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH"
* we are dealing with a IndustryPack format 1 device. If we detect
@ -421,57 +414,44 @@ static int ipack_device_read_id(struct ipack_device *dev)
}
out:
dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
iounmap(idmem);
return ret;
}
struct ipack_device *ipack_device_register(struct ipack_bus_device *bus,
int slot)
int ipack_device_register(struct ipack_device *dev)
{
int ret;
struct ipack_device *dev;
dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
if (!dev)
return NULL;
dev->dev.bus = &ipack_bus_type;
dev->dev.release = ipack_device_release;
dev->dev.parent = bus->parent;
dev->slot = slot;
dev->bus_nr = bus->bus_nr;
dev->bus = bus;
dev->dev.parent = dev->bus->parent;
dev_set_name(&dev->dev,
"ipack-dev.%u.%u", dev->bus_nr, dev->slot);
"ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
if (bus->ops->set_clockrate(dev, 8))
if (dev->bus->ops->set_clockrate(dev, 8))
dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n");
if (bus->ops->reset_timeout(dev))
if (dev->bus->ops->reset_timeout(dev))
dev_warn(&dev->dev, "failed to reset potential timeout.");
ret = ipack_device_read_id(dev);
if (ret < 0) {
dev_err(&dev->dev, "error reading device id section.\n");
kfree(dev);
return NULL;
return ret;
}
/* if the device supports 32 MHz operation, use it. */
if (dev->speed_32mhz) {
ret = bus->ops->set_clockrate(dev, 32);
ret = dev->bus->ops->set_clockrate(dev, 32);
if (ret < 0)
dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
}
ret = device_register(&dev->dev);
if (ret < 0) {
if (ret < 0)
kfree(dev->id);
kfree(dev);
return NULL;
}
return dev;
return ret;
}
EXPORT_SYMBOL_GPL(ipack_device_register);

View File

@ -52,8 +52,6 @@ source "drivers/staging/rtl8192e/Kconfig"
source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/rts_pstor/Kconfig"
source "drivers/staging/rts5139/Kconfig"
source "drivers/staging/frontier/Kconfig"
@ -120,14 +118,10 @@ source "drivers/staging/omapdrm/Kconfig"
source "drivers/staging/android/Kconfig"
source "drivers/staging/telephony/Kconfig"
source "drivers/staging/ozwpan/Kconfig"
source "drivers/staging/ccg/Kconfig"
source "drivers/staging/ipack/Kconfig"
source "drivers/staging/gdm72xx/Kconfig"
source "drivers/staging/csr/Kconfig"
@ -144,4 +138,6 @@ source "drivers/staging/imx-drm/Kconfig"
source "drivers/staging/dgrp/Kconfig"
source "drivers/staging/fwserial/Kconfig"
endif # STAGING

View File

@ -19,7 +19,6 @@ obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_RTS_PSTOR) += rts_pstor/
obj-$(CONFIG_RTS5139) += rts5139/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_IDE_PHISON) += phison/
@ -29,7 +28,6 @@ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_IPACK_BUS) += ipack/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
@ -53,7 +51,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
obj-$(CONFIG_USB_G_CCG) += ccg/
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
@ -64,3 +61,4 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
obj-$(CONFIG_CED1401) += ced1401/
obj-$(CONFIG_DRM_IMX) += imx-drm/
obj-$(CONFIG_DGRP) += dgrp/
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/

View File

@ -1,3 +1,5 @@
ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o
obj-$(CONFIG_ASHMEM) += ashmem.o
obj-$(CONFIG_ANDROID_LOGGER) += logger.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,327 @@
/*
* Copyright (C) 2012 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM binder
#if !defined(_BINDER_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _BINDER_TRACE_H
#include <linux/tracepoint.h>
struct binder_buffer;
struct binder_node;
struct binder_proc;
struct binder_ref;
struct binder_thread;
struct binder_transaction;
TRACE_EVENT(binder_ioctl,
TP_PROTO(unsigned int cmd, unsigned long arg),
TP_ARGS(cmd, arg),
TP_STRUCT__entry(
__field(unsigned int, cmd)
__field(unsigned long, arg)
),
TP_fast_assign(
__entry->cmd = cmd;
__entry->arg = arg;
),
TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
);
DECLARE_EVENT_CLASS(binder_lock_class,
TP_PROTO(const char *tag),
TP_ARGS(tag),
TP_STRUCT__entry(
__field(const char *, tag)
),
TP_fast_assign(
__entry->tag = tag;
),
TP_printk("tag=%s", __entry->tag)
);
#define DEFINE_BINDER_LOCK_EVENT(name) \
DEFINE_EVENT(binder_lock_class, name, \
TP_PROTO(const char *func), \
TP_ARGS(func))
DEFINE_BINDER_LOCK_EVENT(binder_lock);
DEFINE_BINDER_LOCK_EVENT(binder_locked);
DEFINE_BINDER_LOCK_EVENT(binder_unlock);
DECLARE_EVENT_CLASS(binder_function_return_class,
TP_PROTO(int ret),
TP_ARGS(ret),
TP_STRUCT__entry(
__field(int, ret)
),
TP_fast_assign(
__entry->ret = ret;
),
TP_printk("ret=%d", __entry->ret)
);
#define DEFINE_BINDER_FUNCTION_RETURN_EVENT(name) \
DEFINE_EVENT(binder_function_return_class, name, \
TP_PROTO(int ret), \
TP_ARGS(ret))
DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done);
DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_write_done);
DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_read_done);
TRACE_EVENT(binder_wait_for_work,
TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo),
TP_ARGS(proc_work, transaction_stack, thread_todo),
TP_STRUCT__entry(
__field(bool, proc_work)
__field(bool, transaction_stack)
__field(bool, thread_todo)
),
TP_fast_assign(
__entry->proc_work = proc_work;
__entry->transaction_stack = transaction_stack;
__entry->thread_todo = thread_todo;
),
TP_printk("proc_work=%d transaction_stack=%d thread_todo=%d",
__entry->proc_work, __entry->transaction_stack,
__entry->thread_todo)
);
TRACE_EVENT(binder_transaction,
TP_PROTO(bool reply, struct binder_transaction *t,
struct binder_node *target_node),
TP_ARGS(reply, t, target_node),
TP_STRUCT__entry(
__field(int, debug_id)
__field(int, target_node)
__field(int, to_proc)
__field(int, to_thread)
__field(int, reply)
__field(unsigned int, code)
__field(unsigned int, flags)
),
TP_fast_assign(
__entry->debug_id = t->debug_id;
__entry->target_node = target_node ? target_node->debug_id : 0;
__entry->to_proc = t->to_proc->pid;
__entry->to_thread = t->to_thread ? t->to_thread->pid : 0;
__entry->reply = reply;
__entry->code = t->code;
__entry->flags = t->flags;
),
TP_printk("transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x code=0x%x",
__entry->debug_id, __entry->target_node,
__entry->to_proc, __entry->to_thread,
__entry->reply, __entry->flags, __entry->code)
);
TRACE_EVENT(binder_transaction_received,
TP_PROTO(struct binder_transaction *t),
TP_ARGS(t),
TP_STRUCT__entry(
__field(int, debug_id)
),
TP_fast_assign(
__entry->debug_id = t->debug_id;
),
TP_printk("transaction=%d", __entry->debug_id)
);
TRACE_EVENT(binder_transaction_node_to_ref,
TP_PROTO(struct binder_transaction *t, struct binder_node *node,
struct binder_ref *ref),
TP_ARGS(t, node, ref),
TP_STRUCT__entry(
__field(int, debug_id)
__field(int, node_debug_id)
__field(void __user *, node_ptr)
__field(int, ref_debug_id)
__field(uint32_t, ref_desc)
),
TP_fast_assign(
__entry->debug_id = t->debug_id;
__entry->node_debug_id = node->debug_id;
__entry->node_ptr = node->ptr;
__entry->ref_debug_id = ref->debug_id;
__entry->ref_desc = ref->desc;
),
TP_printk("transaction=%d node=%d src_ptr=0x%p ==> dest_ref=%d dest_desc=%d",
__entry->debug_id, __entry->node_debug_id, __entry->node_ptr,
__entry->ref_debug_id, __entry->ref_desc)
);
TRACE_EVENT(binder_transaction_ref_to_node,
TP_PROTO(struct binder_transaction *t, struct binder_ref *ref),
TP_ARGS(t, ref),
TP_STRUCT__entry(
__field(int, debug_id)
__field(int, ref_debug_id)
__field(uint32_t, ref_desc)
__field(int, node_debug_id)
__field(void __user *, node_ptr)
),
TP_fast_assign(
__entry->debug_id = t->debug_id;
__entry->ref_debug_id = ref->debug_id;
__entry->ref_desc = ref->desc;
__entry->node_debug_id = ref->node->debug_id;
__entry->node_ptr = ref->node->ptr;
),
TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%p",
__entry->debug_id, __entry->node_debug_id,
__entry->ref_debug_id, __entry->ref_desc, __entry->node_ptr)
);
TRACE_EVENT(binder_transaction_ref_to_ref,
TP_PROTO(struct binder_transaction *t, struct binder_ref *src_ref,
struct binder_ref *dest_ref),
TP_ARGS(t, src_ref, dest_ref),
TP_STRUCT__entry(
__field(int, debug_id)
__field(int, node_debug_id)
__field(int, src_ref_debug_id)
__field(uint32_t, src_ref_desc)
__field(int, dest_ref_debug_id)
__field(uint32_t, dest_ref_desc)
),
TP_fast_assign(
__entry->debug_id = t->debug_id;
__entry->node_debug_id = src_ref->node->debug_id;
__entry->src_ref_debug_id = src_ref->debug_id;
__entry->src_ref_desc = src_ref->desc;
__entry->dest_ref_debug_id = dest_ref->debug_id;
__entry->dest_ref_desc = dest_ref->desc;
),
TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ref=%d dest_desc=%d",
__entry->debug_id, __entry->node_debug_id,
__entry->src_ref_debug_id, __entry->src_ref_desc,
__entry->dest_ref_debug_id, __entry->dest_ref_desc)
);
TRACE_EVENT(binder_transaction_fd,
TP_PROTO(struct binder_transaction *t, int src_fd, int dest_fd),
TP_ARGS(t, src_fd, dest_fd),
TP_STRUCT__entry(
__field(int, debug_id)
__field(int, src_fd)
__field(int, dest_fd)
),
TP_fast_assign(
__entry->debug_id = t->debug_id;
__entry->src_fd = src_fd;
__entry->dest_fd = dest_fd;
),
TP_printk("transaction=%d src_fd=%d ==> dest_fd=%d",
__entry->debug_id, __entry->src_fd, __entry->dest_fd)
);
DECLARE_EVENT_CLASS(binder_buffer_class,
TP_PROTO(struct binder_buffer *buf),
TP_ARGS(buf),
TP_STRUCT__entry(
__field(int, debug_id)
__field(size_t, data_size)
__field(size_t, offsets_size)
),
TP_fast_assign(
__entry->debug_id = buf->debug_id;
__entry->data_size = buf->data_size;
__entry->offsets_size = buf->offsets_size;
),
TP_printk("transaction=%d data_size=%zd offsets_size=%zd",
__entry->debug_id, __entry->data_size, __entry->offsets_size)
);
DEFINE_EVENT(binder_buffer_class, binder_transaction_alloc_buf,
TP_PROTO(struct binder_buffer *buffer),
TP_ARGS(buffer));
DEFINE_EVENT(binder_buffer_class, binder_transaction_buffer_release,
TP_PROTO(struct binder_buffer *buffer),
TP_ARGS(buffer));
DEFINE_EVENT(binder_buffer_class, binder_transaction_failed_buffer_release,
TP_PROTO(struct binder_buffer *buffer),
TP_ARGS(buffer));
TRACE_EVENT(binder_update_page_range,
TP_PROTO(struct binder_proc *proc, bool allocate,
void *start, void *end),
TP_ARGS(proc, allocate, start, end),
TP_STRUCT__entry(
__field(int, proc)
__field(bool, allocate)
__field(size_t, offset)
__field(size_t, size)
),
TP_fast_assign(
__entry->proc = proc->pid;
__entry->allocate = allocate;
__entry->offset = start - proc->buffer;
__entry->size = end - start;
),
TP_printk("proc=%d allocate=%d offset=%zu size=%zu",
__entry->proc, __entry->allocate,
__entry->offset, __entry->size)
);
TRACE_EVENT(binder_command,
TP_PROTO(uint32_t cmd),
TP_ARGS(cmd),
TP_STRUCT__entry(
__field(uint32_t, cmd)
),
TP_fast_assign(
__entry->cmd = cmd;
),
TP_printk("cmd=0x%x %s",
__entry->cmd,
_IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_command_strings) ?
binder_command_strings[_IOC_NR(__entry->cmd)] :
"unknown")
);
TRACE_EVENT(binder_return,
TP_PROTO(uint32_t cmd),
TP_ARGS(cmd),
TP_STRUCT__entry(
__field(uint32_t, cmd)
),
TP_fast_assign(
__entry->cmd = cmd;
),
TP_printk("cmd=0x%x %s",
__entry->cmd,
_IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_return_strings) ?
binder_return_strings[_IOC_NR(__entry->cmd)] :
"unknown")
);
#endif /* _BINDER_TRACE_H */
#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE binder_trace
#include <trace/define_trace.h>

View File

@ -676,4 +676,25 @@ static int __init logger_init(void)
out:
return ret;
}
static void __exit logger_exit(void)
{
struct logger_log *current_log, *next_log;
list_for_each_entry_safe(current_log, next_log, &log_list, logs) {
/* we have to delete all the entry inside log_list */
misc_deregister(&current_log->misc);
vfree(current_log->buffer);
kfree(current_log->misc.name);
list_del(&current_log->logs);
kfree(current_log);
}
}
device_initcall(logger_init);
module_exit(logger_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Love, <rlove@google.com>");
MODULE_DESCRIPTION("Android Logger");

View File

@ -151,7 +151,7 @@ struct bcm_packet_info {
UINT NumOfPacketsSent;
UCHAR ucDirection;
USHORT usCID;
S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable;
struct bcm_mibs_parameters stMibsExtServiceFlowTable;
UINT uiCurrentRxRate;
UINT uiThisPeriodRxBytes;
UINT uiTotalRxBytes;
@ -198,7 +198,7 @@ struct bcm_tarang_data {
int AppCtrlQueueLen;
BOOLEAN MacTracingEnabled;
BOOLEAN bApplicationToExit;
S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs;
struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs;
ULONG RxCntrlMsgBitMask;
};
@ -371,8 +371,8 @@ struct bcm_mini_adapter {
PFLASH2X_VENDORSPECIFIC_INFO psFlash2xVendorInfo;
UINT uiFlashBaseAdd; /* Flash start address */
UINT uiActiveISOOffset; /* Active ISO offset chosen before f/w download */
FLASH2X_SECTION_VAL eActiveISO; /* Active ISO section val */
FLASH2X_SECTION_VAL eActiveDSD; /* Active DSD val chosen before f/w download */
enum bcm_flash2x_section_val eActiveISO; /* Active ISO section val */
enum bcm_flash2x_section_val eActiveDSD; /* Active DSD val chosen before f/w download */
UINT uiActiveDSDOffsetAtFwDld; /* For accessing Active DSD chosen before f/w download */
UINT uiFlashLayoutMajorVersion;
UINT uiFlashLayoutMinorVersion;

View File

@ -160,7 +160,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
struct bcm_mini_adapter *Adapter = pTarang->Adapter;
INT Status = STATUS_FAILURE;
int timeout = 0;
IOCTL_BUFFER IoBuffer;
struct bcm_ioctl_buffer IoBuffer;
int bytes;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
@ -203,13 +203,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
switch (cmd) {
/* Rdms for Swin Idle... */
case IOCTL_BCM_REGISTER_READ_PRIVATE: {
RDM_BUFFER sRdmBuffer = {0};
struct bcm_rdm_buffer sRdmBuffer = {0};
PCHAR temp_buff;
UINT Bufflen;
u16 temp_value;
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sRdmBuffer))
@ -248,11 +248,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
case IOCTL_BCM_REGISTER_WRITE_PRIVATE: {
WRM_BUFFER sWrmBuffer = {0};
struct bcm_wrm_buffer sWrmBuffer = {0};
UINT uiTempVar = 0;
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sWrmBuffer))
@ -287,7 +287,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_REGISTER_READ:
case IOCTL_BCM_EEPROM_REGISTER_READ: {
RDM_BUFFER sRdmBuffer = {0};
struct bcm_rdm_buffer sRdmBuffer = {0};
PCHAR temp_buff = NULL;
UINT uiTempVar = 0;
if ((Adapter->IdleMode == TRUE) ||
@ -299,7 +299,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sRdmBuffer))
@ -345,8 +345,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
case IOCTL_BCM_REGISTER_WRITE:
case IOCTL_BCM_EEPROM_REGISTER_WRITE: {
WRM_BUFFER sWrmBuffer = {0};
struct bcm_wrm_buffer sWrmBuffer = {0};
UINT uiTempVar = 0;
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE)) {
@ -356,7 +357,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
}
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(sWrmBuffer))
@ -401,8 +402,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
UINT value = 0;
UINT uiBit = 0;
UINT uiOperation = 0;
struct bcm_gpio_info gpio_info = {0};
GPIO_INFO gpio_info = {0};
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE)) {
@ -411,7 +412,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
return -EACCES;
}
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_info))
@ -478,7 +479,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
break;
case BCM_LED_THREAD_STATE_CHANGE_REQ: {
USER_THREAD_REQ threadReq = {0};
struct bcm_user_thread_req threadReq = {0};
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive");
if ((Adapter->IdleMode == TRUE) ||
@ -490,7 +491,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
break;
}
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(threadReq))
@ -518,14 +519,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_GPIO_STATUS_REQUEST: {
ULONG uiBit = 0;
UCHAR ucRead[4];
GPIO_INFO gpio_info = {0};
struct bcm_gpio_info gpio_info = {0};
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE))
return -EACCES;
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_info))
@ -552,17 +553,17 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_GPIO_MULTI_REQUEST: {
UCHAR ucResetValue[4];
GPIO_MULTI_INFO gpio_multi_info[MAX_IDX];
PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info;
struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
struct bcm_gpio_multi_info *pgpio_multi_info = (struct bcm_gpio_multi_info *)gpio_multi_info;
memset(pgpio_multi_info, 0, MAX_IDX * sizeof(GPIO_MULTI_INFO));
memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE))
return -EINVAL;
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_multi_info))
@ -636,15 +637,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
case IOCTL_BCM_GPIO_MODE_REQUEST: {
UCHAR ucResetValue[4];
GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX];
PGPIO_MULTI_MODE pgpio_multi_mode = (PGPIO_MULTI_MODE)gpio_multi_mode;
struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
struct bcm_gpio_multi_mode *pgpio_multi_mode = (struct bcm_gpio_multi_mode *)gpio_multi_mode;
if ((Adapter->IdleMode == TRUE) ||
(Adapter->bShutStatus == TRUE) ||
(Adapter->bPreparingForLowPowerMode == TRUE))
return -EINVAL;
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
@ -719,7 +720,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
PVOID pvBuffer = NULL;
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
@ -799,7 +800,7 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
up(&Adapter->fw_download_sema);
return -EFAULT;
}
@ -895,7 +896,7 @@ cntrlEnd:
mdelay(10);
/* Wait for MailBox Interrupt */
if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter))
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
timeout = 5*HZ;
@ -1000,7 +1001,7 @@ cntrlEnd:
ulong len;
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
len = min_t(ulong, IoBuffer.OutputLength, strlen(VER_FILEVERSION_STR) + 1);
@ -1015,7 +1016,7 @@ cntrlEnd:
LINK_STATE link_state;
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
return -EFAULT;
}
@ -1042,7 +1043,7 @@ cntrlEnd:
UINT tracing_flag;
/* copy ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT)))
@ -1057,13 +1058,13 @@ cntrlEnd:
case IOCTL_BCM_GET_DSX_INDICATION: {
ULONG ulSFId = 0;
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) {
if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
"Mismatch req: %lx needed is =0x%zx!!!",
IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
IoBuffer.OutputLength, sizeof(struct bcm_add_indication_alt));
return -EINVAL;
}
@ -1079,18 +1080,18 @@ cntrlEnd:
case IOCTL_BCM_GET_HOST_MIBS: {
PVOID temp_buff;
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) {
if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
"Length Check failed %lu %zd\n",
IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS));
IoBuffer.OutputLength, sizeof(struct bcm_host_stats_mibs));
return -EINVAL;
}
/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL);
temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
if (!temp_buff)
return STATUS_FAILURE;
@ -1098,7 +1099,7 @@ cntrlEnd:
GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
if (Status != STATUS_FAILURE)
if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) {
if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(struct bcm_host_stats_mibs))) {
kfree(temp_buff);
return -EFAULT;
}
@ -1118,7 +1119,7 @@ cntrlEnd:
break;
case IOCTL_BCM_BULK_WRM: {
PBULKWRM_BUFFER pBulkBuffer;
struct bcm_bulk_wrm_buffer *pBulkBuffer;
UINT uiTempVar = 0;
PCHAR pvBuffer = NULL;
@ -1132,7 +1133,7 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.InputLength < sizeof(ULONG) * 2)
@ -1143,7 +1144,7 @@ cntrlEnd:
if (IS_ERR(pvBuffer))
return PTR_ERR(pvBuffer);
pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
pBulkBuffer = (struct bcm_bulk_wrm_buffer *)pvBuffer;
if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
((ULONG)pBulkBuffer->Register & 0x3)) {
@ -1180,7 +1181,7 @@ cntrlEnd:
}
case IOCTL_BCM_GET_NVM_SIZE:
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) {
@ -1194,7 +1195,7 @@ cntrlEnd:
case IOCTL_BCM_CAL_INIT: {
UINT uiSectorSize = 0 ;
if (Adapter->eNVMType == NVM_FLASH) {
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
@ -1231,7 +1232,7 @@ cntrlEnd:
USER_BCM_DBG_STATE sUserDebugState;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)))
@ -1262,7 +1263,7 @@ cntrlEnd:
case IOCTL_BCM_NVM_READ:
case IOCTL_BCM_NVM_WRITE: {
NVM_READWRITE stNVMReadWrite;
struct bcm_nvm_readwrite stNVMReadWrite;
PUCHAR pReadData = NULL;
ULONG ulDSDMagicNumInUsrBuff = 0;
struct timeval tv0, tv1;
@ -1284,12 +1285,12 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (copy_from_user(&stNVMReadWrite,
(IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
sizeof(NVM_READWRITE)))
sizeof(struct bcm_nvm_readwrite)))
return -EFAULT;
/*
@ -1404,7 +1405,7 @@ cntrlEnd:
}
case IOCTL_BCM_FLASH2X_SECTION_READ: {
FLASH2X_READWRITE sFlash2xRead = {0};
struct bcm_flash2x_readwrite sFlash2xRead = {0};
PUCHAR pReadBuff = NULL ;
UINT NOB = 0;
UINT BuffSize = 0;
@ -1418,11 +1419,11 @@ cntrlEnd:
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
/* Reading FLASH 2.x READ structure */
if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_readwrite)))
return -EFAULT;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xRead.Section);
@ -1495,7 +1496,7 @@ cntrlEnd:
break;
case IOCTL_BCM_FLASH2X_SECTION_WRITE: {
FLASH2X_READWRITE sFlash2xWrite = {0};
struct bcm_flash2x_readwrite sFlash2xWrite = {0};
PUCHAR pWriteBuff;
void __user *InputAddr;
UINT NOB = 0;
@ -1513,11 +1514,11 @@ cntrlEnd:
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
/* Reading FLASH 2.x READ structure */
if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_readwrite)))
return -EFAULT;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xWrite.Section);
@ -1604,16 +1605,16 @@ cntrlEnd:
break;
case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: {
PFLASH2X_BITMAP psFlash2xBitMap;
struct bcm_flash2x_bitmap *psFlash2xBitMap;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
return -EINVAL;
psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
psFlash2xBitMap = kzalloc(sizeof(struct bcm_flash2x_bitmap), GFP_KERNEL);
if (psFlash2xBitMap == NULL) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory is not available");
return -ENOMEM;
@ -1634,7 +1635,7 @@ cntrlEnd:
BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
up(&Adapter->NVMRdmWrmLock);
if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) {
if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(struct bcm_flash2x_bitmap))) {
kfree(psFlash2xBitMap);
return -EFAULT;
}
@ -1644,7 +1645,7 @@ cntrlEnd:
break;
case IOCTL_BCM_SET_ACTIVE_SECTION: {
FLASH2X_SECTION_VAL eFlash2xSectionVal = 0;
enum bcm_flash2x_section_val eFlash2xSectionVal = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called");
if (IsFlash2x(Adapter) != TRUE) {
@ -1652,7 +1653,7 @@ cntrlEnd:
return -EINVAL;
}
Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
return -EFAULT;
@ -1692,7 +1693,7 @@ cntrlEnd:
break;
case IOCTL_BCM_COPY_SECTION: {
FLASH2X_COPY_SECTION sCopySectStrut = {0};
struct bcm_flash2x_copy_section sCopySectStrut = {0};
Status = STATUS_SUCCESS;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called");
@ -1702,13 +1703,13 @@ cntrlEnd:
return -EINVAL;
}
Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
return -EFAULT;
}
Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_copy_section));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
return -EFAULT;
@ -1769,7 +1770,7 @@ cntrlEnd:
Status = STATUS_SUCCESS;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
return -EFAULT;
@ -1799,7 +1800,7 @@ cntrlEnd:
case IOCTL_BCM_SELECT_DSD: {
UINT SectOfset = 0;
FLASH2X_SECTION_VAL eFlash2xSectionVal;
enum bcm_flash2x_section_val eFlash2xSectionVal;
eFlash2xSectionVal = NO_SECTION_VAL;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SELECT_DSD Called");
@ -1808,7 +1809,7 @@ cntrlEnd:
return -EINVAL;
}
Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
return -EFAULT;
@ -1842,7 +1843,7 @@ cntrlEnd:
break;
case IOCTL_BCM_NVM_RAW_READ: {
NVM_READWRITE stNVMRead;
struct bcm_nvm_readwrite stNVMRead;
INT NOB ;
INT BuffSize ;
INT ReadOffset = 0;
@ -1856,12 +1857,12 @@ cntrlEnd:
}
/* Copy Ioctl Buffer structure */
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
return -EFAULT;
}
if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(NVM_READWRITE)))
if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(struct bcm_nvm_readwrite)))
return -EFAULT;
NOB = stNVMRead.uiNumBytes;
@ -1933,7 +1934,7 @@ cntrlEnd:
ULONG RxCntrlMsgBitMask = 0;
/* Copy Ioctl Buffer structure */
Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of Ioctl buffer is failed from user space");
return -EFAULT;
@ -1955,7 +1956,7 @@ cntrlEnd:
break;
case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: {
DEVICE_DRIVER_INFO DevInfo;
struct bcm_driver_info DevInfo;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
@ -1965,7 +1966,7 @@ cntrlEnd:
DevInfo.u32NVMType = Adapter->eNVMType;
DevInfo.u32InterfaceType = BCM_USB;
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.OutputLength < sizeof(DevInfo))
@ -1977,19 +1978,19 @@ cntrlEnd:
break;
case IOCTL_BCM_TIME_SINCE_NET_ENTRY: {
ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
return -EFAULT;
if (IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
return -EINVAL;
stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(struct bcm_time_elapsed)))
return -EFAULT;
}
break;

View File

@ -142,7 +142,7 @@ static void bcm_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
struct bcm_interface_adapter *psIntfAdapter = Adapter->pvInterfaceAdapter;
struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
strcpy(info->driver, DRV_NAME);
@ -186,7 +186,7 @@ static const struct ethtool_ops bcm_ethtool_ops = {
int register_networkdev(struct bcm_mini_adapter *Adapter)
{
struct net_device *net = Adapter->dev;
PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
struct usb_interface *udev = IntfAdapter->interface;
struct usb_device *xdev = IntfAdapter->udev;
@ -227,7 +227,7 @@ int register_networkdev(struct bcm_mini_adapter *Adapter)
void unregister_networkdev(struct bcm_mini_adapter *Adapter)
{
struct net_device *net = Adapter->dev;
PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
struct usb_interface *udev = IntfAdapter->interface;
struct usb_device *xdev = IntfAdapter->udev;

View File

@ -107,7 +107,7 @@ static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIn
DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex);
/* Resetting only MIBS related entries in the SF */
memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(S_MIBS_SERVICEFLOW_TABLE));
memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(struct bcm_mibs_table));
}
static inline VOID
@ -431,7 +431,7 @@ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* <Pointer
register struct bcm_connect_mgr_params *psfLocalSet, /* Pointer to the connection manager parameters structure */
register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */
register UCHAR ucDsxType,
stLocalSFAddIndicationAlt *pstAddIndication) {
struct bcm_add_indication_alt *pstAddIndication) {
/* UCHAR ucProtocolLength = 0; */
ULONG ulSFID;
@ -833,11 +833,11 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
{
int uiLoopIndex;
int nIndex;
stLocalSFAddIndicationAlt *pstAddIndication;
struct bcm_add_indication_alt *pstAddIndication;
UINT nCurClassifierCnt;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
pstAddIndication = (stLocalSFAddIndicationAlt *)pvBuffer;
pstAddIndication = (struct bcm_add_indication_alt *)pvBuffer;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>");
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction);
@ -1333,13 +1333,13 @@ static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer,
ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength)
{
stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL;
struct bcm_add_indication_alt *pstAddIndicationAlt = NULL;
struct bcm_add_indication *pstAddIndication = NULL;
struct bcm_del_request *pstDeletionRequest;
UINT uiSearchRuleIndex;
ULONG ulSFID;
pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer);
pstAddIndicationAlt = (struct bcm_add_indication_alt *)(pvBuffer);
/*
* In case of DSD Req By MS, we should immediately delete this SF so that
@ -1445,29 +1445,29 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu
return 1;
}
static inline stLocalSFAddIndicationAlt
static inline struct bcm_add_indication_alt
*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer)
{
ULONG ulStatus = 0;
struct bcm_add_indication *pstAddIndication = NULL;
stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL;
struct bcm_add_indication_alt *pstAddIndicationDest = NULL;
pstAddIndication = (struct bcm_add_indication *)(pvBuffer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>");
if ((pstAddIndication->u8Type == DSD_REQ) ||
(pstAddIndication->u8Type == DSD_RSP) ||
(pstAddIndication->u8Type == DSD_ACK))
return (stLocalSFAddIndicationAlt *)pvBuffer;
return (struct bcm_add_indication_alt *)pvBuffer;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage ");
/*
* Need to Allocate memory to contain the SUPER Large structures
* Our driver can't create these structures on Stack :(
*/
pstAddIndicationDest = kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL);
pstAddIndicationDest = kmalloc(sizeof(struct bcm_add_indication_alt), GFP_KERNEL);
if (pstAddIndicationDest) {
memset(pstAddIndicationDest, 0, sizeof(stLocalSFAddIndicationAlt));
memset(pstAddIndicationDest, 0, sizeof(struct bcm_add_indication_alt));
} else {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure ");
return NULL;
@ -1573,36 +1573,36 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter)
static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UINT16 tid)
{
ULONG ulTargetDSXBufferAddress;
ULONG ulTargetDsxBufferIndexToUse, ulMaxTry;
ULONG dsx_buf;
ULONG idx, max_try;
if ((Adapter->ulTotalTargetBuffersAvailable == 0) || (Adapter->ulFreeTargetBufferCnt == 0)) {
ClearTargetDSXBuffer(Adapter, tid, FALSE);
return 0;
}
ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer;
ulMaxTry = Adapter->ulTotalTargetBuffersAvailable;
while ((ulMaxTry) && (Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) {
ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1) % Adapter->ulTotalTargetBuffersAvailable;
ulMaxTry--;
idx = Adapter->ulCurrentTargetBuffer;
max_try = Adapter->ulTotalTargetBuffersAvailable;
while ((max_try) && (Adapter->astTargetDsxBuffer[idx].valid != 1)) {
idx = (idx+1) % Adapter->ulTotalTargetBuffersAvailable;
max_try--;
}
if (ulMaxTry == 0) {
if (max_try == 0) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", Adapter->ulFreeTargetBufferCnt);
ClearTargetDSXBuffer(Adapter, tid, FALSE);
return 0;
}
ulTargetDSXBufferAddress = Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer;
Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid = 0;
Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid = tid;
dsx_buf = Adapter->astTargetDsxBuffer[idx].ulTargetDsxBuffer;
Adapter->astTargetDsxBuffer[idx].valid = 0;
Adapter->astTargetDsxBuffer[idx].tid = tid;
Adapter->ulFreeTargetBufferCnt--;
ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable;
Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", ulTargetDSXBufferAddress, tid);
idx = (idx+1)%Adapter->ulTotalTargetBuffersAvailable;
Adapter->ulCurrentTargetBuffer = idx;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", dsx_buf, tid);
return ulTargetDSXBufferAddress;
return dsx_buf;
}
int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter)
@ -1611,7 +1611,7 @@ int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter)
* Need to Allocate memory to contain the SUPER Large structures
* Our driver can't create these structures on Stack
*/
Adapter->caDsxReqResp = kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL);
Adapter->caDsxReqResp = kmalloc(sizeof(struct bcm_add_indication_alt)+LEADER_SIZE, GFP_KERNEL);
if (!Adapter->caDsxReqResp)
return -ENOMEM;
@ -1634,8 +1634,8 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */)
{
struct bcm_connect_mgr_params *psfLocalSet = NULL;
stLocalSFAddIndicationAlt *pstAddIndication = NULL;
stLocalSFChangeIndicationAlt *pstChangeIndication = NULL;
struct bcm_add_indication_alt *pstAddIndication = NULL;
struct bcm_change_indication *pstChangeIndication = NULL;
struct bcm_leader *pLeader = NULL;
/*
@ -1661,12 +1661,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
switch (pstAddIndication->u8Type) {
case DSA_REQ:
{
pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
pLeader->PLength = sizeof(struct bcm_add_indication_alt);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n");
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength);
*((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
*((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
= *pstAddIndication;
((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
@ -1675,12 +1675,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
break;
case DSA_RSP:
{
pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
pLeader->PLength = sizeof(struct bcm_add_indication_alt);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d",
pLeader->PLength);
*((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
*((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
= *pstAddIndication;
((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
} /* no break here..we should go down. */
case DSA_ACK:
@ -1773,12 +1773,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
break;
case DSC_REQ:
{
pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
pLeader->PLength = sizeof(struct bcm_change_indication);
pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength);
*((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
*((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
kfree(pstAddIndication);
@ -1786,17 +1786,17 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* <Pointer
break;
case DSC_RSP:
{
pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
pLeader->PLength = sizeof(struct bcm_change_indication);
pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength);
*((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
*((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
}
case DSC_ACK:
{
UINT uiSearchRuleIndex = 0;
pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID));
if (uiSearchRuleIndex > NO_OF_QUEUES-1)
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received");
@ -1902,7 +1902,7 @@ int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d", status);
psSfInfo = &Adapter->PackInfo[status];
if (psSfInfo->pstSFIndication && copy_to_user(user_buffer,
psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) {
psSfInfo->pstSFIndication, sizeof(struct bcm_add_indication_alt))) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId);
status = -EFAULT;
return status;

View File

@ -1,147 +1,66 @@
/// **************************************************************************
/// (c) Beceem Communications Inc.
/// All Rights Reserved
///
/// \file : CmHost.h
/// \author : Rajeev Tirumala
/// \date : September 8 , 2006
/// \brief : Definitions for Connection Management Requests structure
/// which we will use to setup our connection structures.Its high
/// time we had a header file for CmHost.cpp to isolate the way
/// f/w sends DSx messages and the way we interpret them in code.
/// Revision History
///
/// Date Author Version Description
/// 08-Sep-06 Rajeev 0.1 Created
/// **************************************************************************
/***************************************************************************
* (c) Beceem Communications Inc.
* All Rights Reserved
*
* file : CmHost.h
* author: Rajeev Tirumala
* date : September 8 , 2006
* brief : Definitions for Connection Management Requests structure
* which we will use to setup our connection structures.Its high
* time we had a header file for CmHost.cpp to isolate the way
* f/w sends DSx messages and the way we interpret them in code.
* Revision History
*
* Date Author Version Description
* 08-Sep-06 Rajeev 0.1 Created
***************************************************************************/
#ifndef _CM_HOST_H
#define _CM_HOST_H
#pragma once
#pragma pack (push,4)
#pragma pack(push, 4)
#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 // This contains the pointer
#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 // 24 K Bytes
#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */
#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */
/// \brief structure stLocalSFAddRequest
typedef struct stLocalSFAddRequestAlt{
B_UINT8 u8Type;
B_UINT8 u8Direction;
B_UINT16 u16TID;
/// \brief 16bitCID
B_UINT16 u16CID;
/// \brief 16bitVCID
B_UINT16 u16VCID;
struct bcm_connect_mgr_params sfParameterSet;
//USE_MEMORY_MANAGER();
}stLocalSFAddRequestAlt;
/// \brief structure stLocalSFAddIndication
typedef struct stLocalSFAddIndicationAlt{
B_UINT8 u8Type;
B_UINT8 u8Direction;
B_UINT16 u16TID;
/// \brief 16bitCID
B_UINT16 u16CID;
/// \brief 16bitVCID
B_UINT16 u16VCID;
struct bcm_add_indication_alt {
u8 u8Type;
u8 u8Direction;
u16 u16TID;
/* brief 16bitCID */
u16 u16CID;
/* brief 16bitVCID */
u16 u16VCID;
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
u8 u8CC; /* < Confirmation Code */
u8 u8Padd; /* < 8-bit Padding */
u16 u16Padd; /* < 16 bit Padding */
};
B_UINT8 u8CC; /**< Confirmation Code*/
B_UINT8 u8Padd; /**< 8-bit Padding */
B_UINT16 u16Padd; /**< 16 bit Padding */
// USE_MEMORY_MANAGER();
}stLocalSFAddIndicationAlt;
/// \brief structure stLocalSFAddConfirmation
typedef struct stLocalSFAddConfirmationAlt{
B_UINT8 u8Type;
B_UINT8 u8Direction;
B_UINT16 u16TID;
/// \brief 16bitCID
B_UINT16 u16CID;
/// \brief 16bitVCID
B_UINT16 u16VCID;
struct bcm_change_indication {
u8 u8Type;
u8 u8Direction;
u16 u16TID;
/* brief 16bitCID */
u16 u16CID;
/* brief 16bitVCID */
u16 u16VCID;
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
}stLocalSFAddConfirmationAlt;
u8 u8CC; /* < Confirmation Code */
u8 u8Padd; /* < 8-bit Padding */
u16 u16Padd; /* < 16 bit */
};
unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer, unsigned int *puBufferLength);
int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter);
BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer);
/// \brief structure stLocalSFChangeRequest
typedef struct stLocalSFChangeRequestAlt{
B_UINT8 u8Type;
B_UINT8 u8Direction;
B_UINT16 u16TID;
/// \brief 16bitCID
B_UINT16 u16CID;
/// \brief 16bitVCID
B_UINT16 u16VCID;
/*
//Pointer location at which following connection manager param Structure can be read
//from the target. We only get the address location and we need to read out the
//entire connection manager param structure at the given location on target
*/
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
B_UINT8 u8CC; /**< Confirmation Code*/
B_UINT8 u8Padd; /**< 8-bit Padding */
B_UINT16 u16Padd; /**< 16 bit */
}stLocalSFChangeRequestAlt;
/// \brief structure stLocalSFChangeConfirmation
typedef struct stLocalSFChangeConfirmationAlt{
B_UINT8 u8Type;
B_UINT8 u8Direction;
B_UINT16 u16TID;
/// \brief 16bitCID
B_UINT16 u16CID;
/// \brief 16bitVCID
B_UINT16 u16VCID;
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
}stLocalSFChangeConfirmationAlt;
/// \brief structure stLocalSFChangeIndication
typedef struct stLocalSFChangeIndicationAlt{
B_UINT8 u8Type;
B_UINT8 u8Direction;
B_UINT16 u16TID;
/// \brief 16bitCID
B_UINT16 u16CID;
/// \brief 16bitVCID
B_UINT16 u16VCID;
struct bcm_connect_mgr_params sfAuthorizedSet;
struct bcm_connect_mgr_params sfAdmittedSet;
struct bcm_connect_mgr_params sfActiveSet;
B_UINT8 u8CC; /**< Confirmation Code*/
B_UINT8 u8Padd; /**< 8-bit Padding */
B_UINT16 u16Padd; /**< 16 bit */
}stLocalSFChangeIndicationAlt;
ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer,UINT *puBufferLength);
INT AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
INT FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter);
BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer);
#pragma pack (pop)
#pragma pack(pop)
#endif

View File

@ -226,7 +226,7 @@ INT flushAllAppQ(void)
pTarang->AppCtrlQueueLen = 0;
/* dropped contrl packet statistics also should be reset. */
memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0,
sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
sizeof(struct bcm_mibs_dropped_cntrl_msg));
}
return STATUS_SUCCESS;

View File

@ -1,5 +1,3 @@
#ifndef _HOST_MIBSINTERFACE_H
#define _HOST_MIBSINTERFACE_H
@ -10,221 +8,185 @@
* statistics used for the MIBS.
*/
#define MIBS_MAX_CLASSIFIERS 100
#define MIBS_MAX_PHSRULES 100
#define MIBS_MAX_SERVICEFLOWS 17
#define MIBS_MAX_IP_RANGE_LENGTH 4
#define MIBS_MAX_PORT_RANGE 4
#define MIBS_MAX_PROTOCOL_LENGTH 32
#define MIBS_MAX_PHS_LENGTHS 255
#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10
#define MIBS_MAX_CLASSIFIERS 100
#define MIBS_MAX_PHSRULES 100
#define MIBS_MAX_SERVICEFLOWS 17
#define MIBS_MAX_IP_RANGE_LENGTH 4
#define MIBS_MAX_PORT_RANGE 4
#define MIBS_MAX_PROTOCOL_LENGTH 32
#define MIBS_MAX_PHS_LENGTHS 255
#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10
#define MIBS_IP_LENGTH_OF_ADDRESS 4
#define MIBS_MAX_HIST_ENTRIES 12
#define MIBS_PKTSIZEHIST_RANGE 128
#define MIBS_MAX_HIST_ENTRIES 12
#define MIBS_PKTSIZEHIST_RANGE 128
typedef union _U_MIBS_IP_ADDRESS
{
struct
{
//Source Ip Address Range
ULONG ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH];
//Source Ip Mask Address Range
ULONG ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH];
union bcm_mibs_ip_addr {
struct {
/* Source Ip Address Range */
unsigned long ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH];
/* Source Ip Mask Address Range */
unsigned long ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH];
};
struct
{
//Source Ip Address Range
ULONG ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4];
//Source Ip Mask Address Range
ULONG ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4];
struct {
/* Source Ip Address Range */
unsigned long ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4];
/* Source Ip Mask Address Range */
unsigned long ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4];
};
struct
{
UCHAR ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH *
MIBS_IP_LENGTH_OF_ADDRESS];
UCHAR ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH *
MIBS_IP_LENGTH_OF_ADDRESS];
struct {
unsigned char ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS];
unsigned char ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS];
};
struct
{
UCHAR ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
UCHAR ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
struct {
unsigned char ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
unsigned char ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
};
}U_MIBS_IP_ADDRESS;
typedef struct _S_MIBS_HOST_INFO
{
ULONG64 GoodTransmits;
ULONG64 GoodReceives;
// this to keep track of the Tx and Rx MailBox Registers.
ULONG NumDesUsed;
ULONG CurrNumFreeDesc;
ULONG PrevNumFreeDesc;
// to keep track the no of byte received
ULONG PrevNumRcevBytes;
ULONG CurrNumRcevBytes;
};
struct bcm_mibs_host_info {
u64 GoodTransmits;
u64 GoodReceives;
/* this to keep track of the Tx and Rx MailBox Registers. */
unsigned long NumDesUsed;
unsigned long CurrNumFreeDesc;
unsigned long PrevNumFreeDesc;
/* to keep track the no of byte received */
unsigned long PrevNumRcevBytes;
unsigned long CurrNumRcevBytes;
/* QOS Related */
ULONG BEBucketSize;
ULONG rtPSBucketSize;
ULONG LastTxQueueIndex;
BOOLEAN TxOutofDescriptors;
BOOLEAN TimerActive;
UINT32 u32TotalDSD;
UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
}S_MIBS_HOST_INFO;
unsigned long BEBucketSize;
unsigned long rtPSBucketSize;
unsigned long LastTxQueueIndex;
bool TxOutofDescriptors;
bool TimerActive;
u32 u32TotalDSD;
u32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
u32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
};
typedef struct _S_MIBS_CLASSIFIER_RULE
{
ULONG ulSFID;
UCHAR ucReserved[2];
B_UINT16 uiClassifierRuleIndex;
BOOLEAN bUsed;
USHORT usVCID_Value;
// This field detemines the Classifier Priority
B_UINT8 u8ClassifierRulePriority;
U_MIBS_IP_ADDRESS stSrcIpAddress;
/*IP Source Address Length*/
UCHAR ucIPSourceAddressLength;
U_MIBS_IP_ADDRESS stDestIpAddress;
struct bcm_mibs_classifier_rule {
unsigned long ulSFID;
unsigned char ucReserved[2];
u16 uiClassifierRuleIndex;
bool bUsed;
unsigned short usVCID_Value;
u8 u8ClassifierRulePriority;
union bcm_mibs_ip_addr stSrcIpAddress;
/* IP Source Address Length */
unsigned char ucIPSourceAddressLength;
union bcm_mibs_ip_addr stDestIpAddress;
/* IP Destination Address Length */
UCHAR ucIPDestinationAddressLength;
UCHAR ucIPTypeOfServiceLength;//Type of service Length
UCHAR ucTosLow;//Tos Low
UCHAR ucTosHigh;//Tos High
UCHAR ucTosMask;//Tos Mask
UCHAR ucProtocolLength;//protocol Length
UCHAR ucProtocol[MIBS_MAX_PROTOCOL_LENGTH];//protocol Length
USHORT usSrcPortRangeLo[MIBS_MAX_PORT_RANGE];
USHORT usSrcPortRangeHi[MIBS_MAX_PORT_RANGE];
UCHAR ucSrcPortRangeLength;
USHORT usDestPortRangeLo[MIBS_MAX_PORT_RANGE];
USHORT usDestPortRangeHi[MIBS_MAX_PORT_RANGE];
UCHAR ucDestPortRangeLength;
BOOLEAN bProtocolValid;
BOOLEAN bTOSValid;
BOOLEAN bDestIpValid;
BOOLEAN bSrcIpValid;
UCHAR ucDirection;
BOOLEAN bIpv6Protocol;
UINT32 u32PHSRuleID;
}S_MIBS_CLASSIFIER_RULE;
unsigned char ucIPDestinationAddressLength;
unsigned char ucIPTypeOfServiceLength;
unsigned char ucTosLow;
unsigned char ucTosHigh;
unsigned char ucTosMask;
unsigned char ucProtocolLength;
unsigned char ucProtocol[MIBS_MAX_PROTOCOL_LENGTH];
unsigned short usSrcPortRangeLo[MIBS_MAX_PORT_RANGE];
unsigned short usSrcPortRangeHi[MIBS_MAX_PORT_RANGE];
unsigned char ucSrcPortRangeLength;
unsigned short usDestPortRangeLo[MIBS_MAX_PORT_RANGE];
unsigned short usDestPortRangeHi[MIBS_MAX_PORT_RANGE];
unsigned char ucDestPortRangeLength;
bool bProtocolValid;
bool bTOSValid;
bool bDestIpValid;
bool bSrcIpValid;
unsigned char ucDirection;
bool bIpv6Protocol;
u32 u32PHSRuleID;
};
struct bcm_mibs_phs_rule {
unsigned long ulSFID;
u8 u8PHSI;
u8 u8PHSFLength;
u8 u8PHSF[MIBS_MAX_PHS_LENGTHS];
u8 u8PHSMLength;
u8 u8PHSM[MIBS_MAX_PHS_LENGTHS];
u8 u8PHSS;
u8 u8PHSV;
u8 reserved[5];
long PHSModifiedBytes;
unsigned long PHSModifiedNumPackets;
unsigned long PHSErrorNumPackets;
};
typedef struct _S_MIBS_PHS_RULE
{
ULONG ulSFID;
/// brief 8bit PHSI Of The Service Flow
B_UINT8 u8PHSI;
/// brief PHSF Of The Service Flow
B_UINT8 u8PHSFLength;
B_UINT8 u8PHSF[MIBS_MAX_PHS_LENGTHS];
/// brief PHSM Of The Service Flow
B_UINT8 u8PHSMLength;
B_UINT8 u8PHSM[MIBS_MAX_PHS_LENGTHS];
/// brief 8bit PHSS Of The Service Flow
B_UINT8 u8PHSS;
/// brief 8bit PHSV Of The Service Flow
B_UINT8 u8PHSV;
// Reserved bytes are 5, so that it is similar to S_PHS_RULE structure.
B_UINT8 reserved[5];
struct bcm_mibs_parameters {
u32 wmanIfSfid;
u32 wmanIfCmnCpsSfState;
u32 wmanIfCmnCpsMaxSustainedRate;
u32 wmanIfCmnCpsMaxTrafficBurst;
u32 wmanIfCmnCpsMinReservedRate;
u32 wmanIfCmnCpsToleratedJitter;
u32 wmanIfCmnCpsMaxLatency;
u32 wmanIfCmnCpsFixedVsVariableSduInd;
u32 wmanIfCmnCpsSduSize;
u32 wmanIfCmnCpsSfSchedulingType;
u32 wmanIfCmnCpsArqEnable;
u32 wmanIfCmnCpsArqWindowSize;
u32 wmanIfCmnCpsArqBlockLifetime;
u32 wmanIfCmnCpsArqSyncLossTimeout;
u32 wmanIfCmnCpsArqDeliverInOrder;
u32 wmanIfCmnCpsArqRxPurgeTimeout;
u32 wmanIfCmnCpsArqBlockSize;
u32 wmanIfCmnCpsMinRsvdTolerableRate;
u32 wmanIfCmnCpsReqTxPolicy;
u32 wmanIfCmnSfCsSpecification;
u32 wmanIfCmnCpsTargetSaid;
};
LONG PHSModifiedBytes;
ULONG PHSModifiedNumPackets;
ULONG PHSErrorNumPackets;
}S_MIBS_PHS_RULE;
struct bcm_mibs_table {
unsigned long ulSFID;
unsigned short usVCID_Value;
unsigned int uiThreshold;
u8 u8TrafficPriority;
bool bValid;
bool bActive;
bool bActivateRequestSent;
u8 u8QueueType;
unsigned int uiMaxBucketSize;
unsigned int uiCurrentQueueDepthOnTarget;
unsigned int uiCurrentBytesOnHost;
unsigned int uiCurrentPacketsOnHost;
unsigned int uiDroppedCountBytes;
unsigned int uiDroppedCountPackets;
unsigned int uiSentBytes;
unsigned int uiSentPackets;
unsigned int uiCurrentDrainRate;
unsigned int uiThisPeriodSentBytes;
u64 liDrainCalculated;
unsigned int uiCurrentTokenCount;
u64 liLastUpdateTokenAt;
unsigned int uiMaxAllowedRate;
unsigned int NumOfPacketsSent;
unsigned char ucDirection;
unsigned short usCID;
struct bcm_mibs_parameters stMibsExtServiceFlowTable;
unsigned int uiCurrentRxRate;
unsigned int uiThisPeriodRxBytes;
unsigned int uiTotalRxBytes;
unsigned int uiTotalTxBytes;
};
typedef struct _S_MIBS_EXTSERVICEFLOW_PARAMETERS
{
UINT32 wmanIfSfid;
UINT32 wmanIfCmnCpsSfState;
UINT32 wmanIfCmnCpsMaxSustainedRate;
UINT32 wmanIfCmnCpsMaxTrafficBurst;
UINT32 wmanIfCmnCpsMinReservedRate;
UINT32 wmanIfCmnCpsToleratedJitter;
UINT32 wmanIfCmnCpsMaxLatency;
UINT32 wmanIfCmnCpsFixedVsVariableSduInd;
UINT32 wmanIfCmnCpsSduSize;
UINT32 wmanIfCmnCpsSfSchedulingType;
UINT32 wmanIfCmnCpsArqEnable;
UINT32 wmanIfCmnCpsArqWindowSize;
UINT32 wmanIfCmnCpsArqBlockLifetime;
UINT32 wmanIfCmnCpsArqSyncLossTimeout;
UINT32 wmanIfCmnCpsArqDeliverInOrder;
UINT32 wmanIfCmnCpsArqRxPurgeTimeout;
UINT32 wmanIfCmnCpsArqBlockSize;
UINT32 wmanIfCmnCpsMinRsvdTolerableRate;
UINT32 wmanIfCmnCpsReqTxPolicy;
UINT32 wmanIfCmnSfCsSpecification;
UINT32 wmanIfCmnCpsTargetSaid;
struct bcm_mibs_dropped_cntrl_msg {
unsigned long cm_responses;
unsigned long cm_control_newdsx_multiclassifier_resp;
unsigned long link_control_resp;
unsigned long status_rsp;
unsigned long stats_pointer_resp;
unsigned long idle_mode_status;
unsigned long auth_ss_host_msg;
unsigned long low_priority_message;
};
}S_MIBS_EXTSERVICEFLOW_PARAMETERS;
struct bcm_host_stats_mibs {
struct bcm_mibs_host_info stHostInfo;
struct bcm_mibs_classifier_rule astClassifierTable[MIBS_MAX_CLASSIFIERS];
struct bcm_mibs_table astSFtable[MIBS_MAX_SERVICEFLOWS];
struct bcm_mibs_phs_rule astPhsRulesTable[MIBS_MAX_PHSRULES];
struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs;
};
typedef struct _S_MIBS_SERVICEFLOW_TABLE
{
//classification extension Rule
ULONG ulSFID;
USHORT usVCID_Value;
UINT uiThreshold;
// This field determines the priority of the SF Queues
B_UINT8 u8TrafficPriority;
BOOLEAN bValid;
BOOLEAN bActive;
BOOLEAN bActivateRequestSent;
//BE or rtPS
B_UINT8 u8QueueType;
//maximum size of the bucket for the queue
UINT uiMaxBucketSize;
UINT uiCurrentQueueDepthOnTarget;
UINT uiCurrentBytesOnHost;
UINT uiCurrentPacketsOnHost;
UINT uiDroppedCountBytes;
UINT uiDroppedCountPackets;
UINT uiSentBytes;
UINT uiSentPackets;
UINT uiCurrentDrainRate;
UINT uiThisPeriodSentBytes;
LARGE_INTEGER liDrainCalculated;
UINT uiCurrentTokenCount;
LARGE_INTEGER liLastUpdateTokenAt;
UINT uiMaxAllowedRate;
UINT NumOfPacketsSent;
UCHAR ucDirection;
USHORT usCID;
S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable;
UINT uiCurrentRxRate;
UINT uiThisPeriodRxBytes;
UINT uiTotalRxBytes;
UINT uiTotalTxBytes;
}S_MIBS_SERVICEFLOW_TABLE;
typedef struct _S_MIBS_DROPPED_APP_CNTRL_MESSAGES
{
ULONG cm_responses;
ULONG cm_control_newdsx_multiclassifier_resp;
ULONG link_control_resp;
ULONG status_rsp;
ULONG stats_pointer_resp;
ULONG idle_mode_status;
ULONG auth_ss_host_msg;
ULONG low_priority_message;
}S_MIBS_DROPPED_APP_CNTRL_MESSAGES;
typedef struct _S_MIBS_HOST_STATS_MIBS
{
S_MIBS_HOST_INFO stHostInfo;
S_MIBS_CLASSIFIER_RULE astClassifierTable[MIBS_MAX_CLASSIFIERS];
S_MIBS_SERVICEFLOW_TABLE astSFtable[MIBS_MAX_SERVICEFLOWS];
S_MIBS_PHS_RULE astPhsRulesTable[MIBS_MAX_PHSRULES];
S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs;
}S_MIBS_HOST_STATS_MIBS;
#endif

View File

@ -1,97 +1,79 @@
#ifndef _INTERFACE_ADAPTER_H
#define _INTERFACE_ADAPTER_H
typedef struct _BULK_ENDP_IN
{
PCHAR bulk_in_buffer;
size_t bulk_in_size;
UCHAR bulk_in_endpointAddr;
UINT bulk_in_pipe;
}BULK_ENDP_IN, *PBULK_ENDP_IN;
struct bcm_bulk_endpoint_in {
char *bulk_in_buffer;
size_t bulk_in_size;
unsigned char bulk_in_endpointAddr;
unsigned int bulk_in_pipe;
};
struct bcm_bulk_endpoint_out {
unsigned char bulk_out_buffer;
size_t bulk_out_size;
unsigned char bulk_out_endpointAddr;
unsigned int bulk_out_pipe;
/* this is used when int out endpoint is used as bulk out end point */
unsigned char int_out_interval;
};
typedef struct _BULK_ENDP_OUT
{
UCHAR bulk_out_buffer;
size_t bulk_out_size;
UCHAR bulk_out_endpointAddr;
UINT bulk_out_pipe;
//this is used when int out endpoint is used as bulk out end point
UCHAR int_out_interval;
}BULK_ENDP_OUT, *PBULK_ENDP_OUT;
struct bcm_intr_endpoint_in {
char *int_in_buffer;
size_t int_in_size;
unsigned char int_in_endpointAddr;
unsigned char int_in_interval;
unsigned int int_in_pipe;
};
typedef struct _INTR_ENDP_IN
{
PCHAR int_in_buffer;
size_t int_in_size;
UCHAR int_in_endpointAddr;
UCHAR int_in_interval;
UINT int_in_pipe;
}INTR_ENDP_IN, *PINTR_ENDP_IN;
struct bcm_intr_endpoint_out {
char *int_out_buffer;
size_t int_out_size;
unsigned char int_out_endpointAddr;
unsigned char int_out_interval;
unsigned int int_out_pipe;
};
typedef struct _INTR_ENDP_OUT
{
PCHAR int_out_buffer;
size_t int_out_size;
UCHAR int_out_endpointAddr;
UCHAR int_out_interval;
UINT int_out_pipe;
}INTR_ENDP_OUT, *PINTR_ENDP_OUT;
typedef struct _USB_TCB
{
struct bcm_usb_tcb {
struct urb *urb;
PVOID psIntfAdapter;
BOOLEAN bUsed;
}USB_TCB, *PUSB_TCB;
void *psIntfAdapter;
bool bUsed;
};
typedef struct _USB_RCB
{
struct bcm_usb_rcb {
struct urb *urb;
PVOID psIntfAdapter;
BOOLEAN bUsed;
}USB_RCB, *PUSB_RCB;
void *psIntfAdapter;
bool bUsed;
};
/*
//This is the interface specific Sub-Adapter
//Structure.
*/
typedef struct _S_INTERFACE_ADAPTER
{
struct usb_device * udev;
struct usb_interface * interface;
* This is the interface specific Sub-Adapter
* Structure.
*/
struct bcm_interface_adapter {
struct usb_device *udev;
struct usb_interface *interface;
/* Bulk endpoint in info */
BULK_ENDP_IN sBulkIn;
struct bcm_bulk_endpoint_in sBulkIn;
/* Bulk endpoint out info */
BULK_ENDP_OUT sBulkOut;
struct bcm_bulk_endpoint_out sBulkOut;
/* Interrupt endpoint in info */
INTR_ENDP_IN sIntrIn;
struct bcm_intr_endpoint_in sIntrIn;
/* Interrupt endpoint out info */
INTR_ENDP_OUT sIntrOut;
ULONG ulInterruptData[2];
struct bcm_intr_endpoint_out sIntrOut;
unsigned long ulInterruptData[2];
struct urb *psInterruptUrb;
USB_TCB asUsbTcb[MAXIMUM_USB_TCB];
USB_RCB asUsbRcb[MAXIMUM_USB_RCB];
atomic_t uNumTcbUsed;
atomic_t uCurrTcb;
atomic_t uNumRcbUsed;
atomic_t uCurrRcb;
struct bcm_usb_tcb asUsbTcb[MAXIMUM_USB_TCB];
struct bcm_usb_rcb asUsbRcb[MAXIMUM_USB_RCB];
atomic_t uNumTcbUsed;
atomic_t uCurrTcb;
atomic_t uNumRcbUsed;
atomic_t uCurrRcb;
struct bcm_mini_adapter *psAdapter;
BOOLEAN bFlashBoot;
BOOLEAN bHighSpeedDevice ;
BOOLEAN bSuspended;
BOOLEAN bPreparingForBusSuspend;
bool bFlashBoot;
bool bHighSpeedDevice;
bool bSuspended;
bool bPreparingForBusSuspend;
struct work_struct usbSuspendWork;
}S_INTERFACE_ADAPTER,*PS_INTERFACE_ADAPTER;
};
#endif

View File

@ -6,7 +6,7 @@ int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
mm_segment_t oldfs = {0};
int errno = 0, len = 0; /* ,is_config_file = 0 */
loff_t pos = 0;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
/* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
@ -61,7 +61,7 @@ int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_c
loff_t pos = 0;
static int fw_down;
INT Status = STATUS_SUCCESS;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
int bytes;
buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);

View File

@ -156,7 +156,7 @@ static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, unsigned int
int lenwritten = 0;
unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter;
struct bcm_interface_adapter *psInterfaceAdapter = Adapter->pvInterfaceAdapter;
//Abort Bus suspend if its already suspended
if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend))

View File

@ -3,11 +3,12 @@
INT InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter);
INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer);
INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter,
unsigned int *puiBuffer);
VOID InterfaceWriteIdleModeWakePattern(struct bcm_mini_adapter *Adapter);
INT InterfaceWakeUp(struct bcm_mini_adapter * Adapter);
INT InterfaceWakeUp(struct bcm_mini_adapter *Adapter);
VOID InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter);
#endif

View File

@ -4,11 +4,12 @@ static struct usb_device_id InterfaceUsbtable[] = {
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SM250) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SYM) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) },
{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) },
{ }
};
MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);
@ -22,9 +23,9 @@ static const u32 default_msg =
| NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
| NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter);
static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter)
static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter)
{
int i = 0;
@ -79,7 +80,7 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter
ulReg = ntohl(EP2_CFG_REG);
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE);
if (((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) {
if (((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) {
ulReg = ntohl(EP2_CFG_INT);
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
} else {
@ -145,7 +146,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi
struct usb_device *udev = interface_to_usbdev(intf);
int retval;
struct bcm_mini_adapter *psAdapter;
PS_INTERFACE_ADAPTER psIntfAdapter;
struct bcm_interface_adapter *psIntfAdapter;
struct net_device *ndev;
/* Reserve one extra queue for the bit-bucket */
@ -189,7 +190,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi
}
/* Allocate interface adapter structure */
psIntfAdapter = kzalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL);
psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter), GFP_KERNEL);
if (psIntfAdapter == NULL) {
dev_err(&udev->dev, DRV_NAME ": no memory for Interface adapter\n");
AdapterFree(psAdapter);
@ -257,7 +258,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi
static void usbbcm_disconnect(struct usb_interface *intf)
{
PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
struct bcm_mini_adapter *psAdapter;
struct usb_device *udev = interface_to_usbdev(intf);
@ -276,7 +277,7 @@ static void usbbcm_disconnect(struct usb_interface *intf)
usb_put_dev(udev);
}
static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter)
{
int i = 0;
@ -311,7 +312,7 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
return 0;
}
static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter)
static int device_run(struct bcm_interface_adapter *psIntfAdapter)
{
int value = 0;
UINT status = STATUS_SUCCESS;
@ -421,7 +422,7 @@ static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descrip
return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd);
}
static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
{
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
@ -619,7 +620,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
{
PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
psIntfAdapter->bSuspended = TRUE;
@ -646,7 +647,7 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
static int InterfaceResume(struct usb_interface *intf)
{
PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf);
mdelay(100);
psIntfAdapter->bSuspended = FALSE;

View File

@ -8,11 +8,11 @@
#define BCM_USB_PRODUCT_ID_T3 0x0300
#define BCM_USB_PRODUCT_ID_T3B 0x0210
#define BCM_USB_PRODUCT_ID_T3L 0x0220
#define BCM_USB_PRODUCT_ID_SM250 0xbccd
#define BCM_USB_PRODUCT_ID_SYM 0x15E
#define BCM_USB_PRODUCT_ID_1901 0xe017
#define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */
#define BCM_USB_PRODUCT_ID_ZTE_226 0x172
#define BCM_USB_PRODUCT_ID_ZTE_326 0x173 /* ZTE AX326 */
#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007
#define BCM_USB_MINOR_BASE 192
@ -21,6 +21,6 @@ int InterfaceInitialize(void);
int InterfaceExit(void);
int usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
int usbbcm_worker_thread(struct bcm_interface_adapter *psIntfAdapter);
#endif

View File

@ -4,7 +4,7 @@
static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
{
int status = urb->status;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context;
struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)urb->context;
struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter ;
if (netif_msg_intr(Adapter))
@ -114,7 +114,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
}
int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
{
psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL);
if (!psIntfAdapter->psInterruptUrb)
@ -143,7 +143,7 @@ int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
}
INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
{
INT status = 0;

View File

@ -1,10 +1,10 @@
#ifndef _INTERFACE_ISR_H
#define _INTERFACE_ISR_H
int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter);
int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter);
INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter);
INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter);
VOID InterfaceEnableInterrupt(struct bcm_mini_adapter *Adapter);

View File

@ -1,17 +1,14 @@
#include "headers.h"
INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
UINT addr,
PVOID buff,
INT len)
int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
unsigned int addr,
void *buff,
int len)
{
int bytes;
USHORT usRetries = 0;
if (psIntfAdapter == NULL) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
if (!psIntfAdapter)
return -EINVAL;
}
if (psIntfAdapter->psAdapter->device_removed == TRUE) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
@ -29,27 +26,21 @@ INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
}
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
do {
bytes = usb_control_msg(psIntfAdapter->udev,
usb_rcvctrlpipe(psIntfAdapter->udev, 0),
0x02,
0xC2,
(addr & 0xFFFF),
((addr >> 16) & 0xFFFF),
buff,
len,
5000);
bytes = usb_control_msg(psIntfAdapter->udev,
usb_rcvctrlpipe(psIntfAdapter->udev, 0),
0x02,
0xC2,
(addr & 0xFFFF),
((addr >> 16) & 0xFFFF),
buff,
len,
5000);
usRetries++;
if (-ENODEV == bytes) {
psIntfAdapter->psAdapter->device_removed = TRUE;
break;
}
} while ((bytes < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
if (-ENODEV == bytes)
psIntfAdapter->psAdapter->device_removed = TRUE;
if (bytes < 0)
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", bytes, usRetries);
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d", bytes);
else
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes);
@ -57,18 +48,15 @@ INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
return bytes;
}
INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
UINT addr,
PVOID buff,
INT len)
int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
unsigned int addr,
void *buff,
int len)
{
int retval = 0;
USHORT usRetries = 0;
if (psIntfAdapter == NULL) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
if (!psIntfAdapter)
return -EINVAL;
}
if (psIntfAdapter->psAdapter->device_removed == TRUE) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
@ -87,27 +75,21 @@ INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
do {
retval = usb_control_msg(psIntfAdapter->udev,
usb_sndctrlpipe(psIntfAdapter->udev, 0),
0x01,
0x42,
(addr & 0xFFFF),
((addr >> 16) & 0xFFFF),
buff,
len,
5000);
retval = usb_control_msg(psIntfAdapter->udev,
usb_sndctrlpipe(psIntfAdapter->udev, 0),
0x01,
0x42,
(addr & 0xFFFF),
((addr >> 16) & 0xFFFF),
buff,
len,
5000);
usRetries++;
if (-ENODEV == retval) {
psIntfAdapter->psAdapter->device_removed = TRUE;
break;
}
} while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
if (-ENODEV == retval)
psIntfAdapter->psAdapter->device_removed = TRUE;
if (retval < 0) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d", retval);
psIntfAdapter->psAdapter->DeviceAccess = FALSE;
return retval;
} else {
@ -117,26 +99,26 @@ INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
}
}
INT BcmRDM(PVOID arg,
UINT addr,
PVOID buff,
INT len)
int BcmRDM(void *arg,
unsigned int addr,
void *buff,
int len)
{
return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
return InterfaceRDM((struct bcm_interface_adapter*)arg, addr, buff, len);
}
INT BcmWRM(PVOID arg,
UINT addr,
PVOID buff,
INT len)
int BcmWRM(void *arg,
unsigned int addr,
void *buff,
int len)
{
return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, len);
}
INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
{
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
INT status = STATUS_SUCCESS;
struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter);
int status = STATUS_SUCCESS;
/*
* usb_clear_halt - tells device to clear endpoint halt/stall condition
@ -172,10 +154,10 @@ INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
return status;
}
VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter)
{
struct urb *tempUrb = NULL;
UINT i;
unsigned int i;
/*
* usb_kill_urb - cancel a transfer request and wait for it to finish
@ -193,7 +175,7 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
*/
/* Cancel submitted Interrupt-URB's */
if (psIntfAdapter->psInterruptUrb != NULL) {
if (psIntfAdapter->psInterruptUrb) {
if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
usb_kill_urb(psIntfAdapter->psInterruptUrb);
}
@ -222,11 +204,11 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
atomic_set(&psIntfAdapter->uCurrRcb, 0);
}
VOID putUsbSuspend(struct work_struct *work)
void putUsbSuspend(struct work_struct *work)
{
PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
struct bcm_interface_adapter *psIntfAdapter = NULL;
struct usb_interface *intf = NULL;
psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER, usbSuspendWork);
psIntfAdapter = container_of(work, struct bcm_interface_adapter, usbSuspendWork);
intf = psIntfAdapter->interface;
if (psIntfAdapter->bSuspended == FALSE)

View File

@ -2,13 +2,13 @@
#define __INTERFACE_MISC_H
INT
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
UINT addr,
PVOID buff,
INT len);
INT
InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
UINT addr,
PVOID buff,
INT len);
@ -35,7 +35,7 @@ int BcmWRM(PVOID arg,
INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter);
VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter);
VOID Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter);
#define DISABLE_USB_ZERO_LEN_INT 0x0F011878

View File

@ -12,10 +12,10 @@ static int SearchVcid(struct bcm_mini_adapter *Adapter,unsigned short usVcid)
}
static PUSB_RCB
GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter)
static struct bcm_usb_rcb *
GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter)
{
PUSB_RCB pRcb = NULL;
struct bcm_usb_rcb *pRcb = NULL;
UINT index = 0;
if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
@ -43,8 +43,8 @@ static void read_bulk_callback(struct urb *urb)
UINT uiIndex=0;
int process_done = 1;
//int idleflag = 0 ;
PUSB_RCB pRcb = (PUSB_RCB)urb->context;
PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter;
struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context;
struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter;
struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
struct bcm_leader *pLeader = urb->transfer_buffer;
@ -196,7 +196,7 @@ static void read_bulk_callback(struct urb *urb)
atomic_dec(&psIntfAdapter->uNumRcbUsed);
}
static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_rcb *pRcb)
{
struct urb *urb = pRcb->urb;
int retval = 0;
@ -240,10 +240,10 @@ Return: TRUE - If Rx was successful.
Other - If an error occurred.
*/
BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter)
BOOLEAN InterfaceRx (struct bcm_interface_adapter *psIntfAdapter)
{
USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
PUSB_RCB pRcb = NULL;
struct bcm_usb_rcb *pRcb = NULL;
// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs -
// psIntfAdapter->psAdapter->PrevNumRecvDescs;

View File

@ -1,7 +1,7 @@
#ifndef _INTERFACE_RX_H
#define _INTERFACE_RX_H
BOOLEAN InterfaceRx(PS_INTERFACE_ADAPTER Adapter);
BOOLEAN InterfaceRx(struct bcm_interface_adapter *Adapter);
#endif

View File

@ -3,8 +3,8 @@
/*this is transmit call-back(BULK OUT)*/
static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
{
PUSB_TCB pTcb= (PUSB_TCB)urb->context;
PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter;
struct bcm_usb_tcb *pTcb= (struct bcm_usb_tcb *)urb->context;
struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter;
struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer;
struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ;
BOOLEAN bpowerDownMsg = FALSE ;
@ -107,9 +107,9 @@ err_exit :
}
static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter)
{
PUSB_TCB pTcb = NULL;
struct bcm_usb_tcb *pTcb = NULL;
UINT index = 0;
if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
@ -128,7 +128,7 @@ static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
return pTcb;
}
static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_tcb *pTcb, PVOID data, int len)
{
struct urb *urb = pTcb->urb;
@ -182,9 +182,9 @@ static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID
int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
{
PUSB_TCB pTcb= NULL;
struct bcm_usb_tcb *pTcb= NULL;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
pTcb= GetBulkOutTcb(psIntfAdapter);
if(pTcb == NULL)
{

View File

@ -1,247 +1,136 @@
#ifndef _IOCTL_H_
#define _IOCTL_H_
typedef struct rdmbuffer
{
ULONG Register;
ULONG Length;
}__attribute__((packed)) RDM_BUFFER, *PRDM_BUFFER;
struct bcm_rdm_buffer {
unsigned long Register;
unsigned long Length;
} __packed;
struct bcm_wrm_buffer {
unsigned long Register;
unsigned long Length;
unsigned char Data[4];
} __packed;
typedef struct wrmbuffer
{
ULONG Register;
ULONG Length;
UCHAR Data[4];
}__attribute__((packed)) WRM_BUFFER, *PWRM_BUFFER;
typedef struct ioctlbuffer
{
struct bcm_ioctl_buffer {
void __user *InputBuffer;
ULONG InputLength;
unsigned long InputLength;
void __user *OutputBuffer;
ULONG OutputLength;
}__attribute__((packed)) IOCTL_BUFFER, *PIOCTL_BUFFER;
unsigned long OutputLength;
} __packed;
struct bcm_gpio_info {
unsigned int uiGpioNumber; /* valid numbers 0-15 */
unsigned int uiGpioValue; /* 1 set ; 0 not set */
} __packed;
struct bcm_user_thread_req {
/* 0->Inactivate LED thread. */
/* 1->Activate the LED thread */
unsigned int ThreadState;
} __packed;
typedef struct stGPIOInfo
{
UINT uiGpioNumber ; /* valid numbers 0-15 */
UINT uiGpioValue; /* 1 set ; 0 not set */
}__attribute__((packed))GPIO_INFO,*PGPIO_INFO;
typedef struct stUserThreadReq
{
//0->Inactivate LED thread.
//1->Activate the LED thread
UINT ThreadState;
}__attribute__((packed))USER_THREAD_REQ,*PUSER_THREAD_REQ;
#define LED_THREAD_ACTIVATION_REQ 1
////********** ioctl codes ***********////
#define BCM_IOCTL 'k'
//1.Control code for CONTROL MESSAGES
#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801,int)
//2.Control code to write a particular value to a particular register
#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int) //
//3.
#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int) //
//4.Control code to write x number of bytes to common memory
//starting from address y
#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int)//
//5.Control code to write x number of bytes to common memory
//starting from address y
#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int)//
//6.Control code for CONTROL MESSAGES
#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int)//
//7.Control code for FIRMWARE DOWNLOAD
#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int)//
#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int)
//9.Control code for TRANSFER MODE SWITCHING
#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int)
//10.Control code for LINK UP
#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int)
//11.Control code for RSSI Level Request
#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int)
//12.Control code for IDLE MODE CONTROL
#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int)
//13.Control code for SS/BS info
#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int)
#define BCM_IOCTL 'k'
#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801, int)
#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int)
#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int)
#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int)
#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int)
#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int)
#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int)
#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int)
#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int)
#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int)
#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int)
#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int)
#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int)
#define IOCTL_GET_STATISTICS_POINTER _IOW(BCM_IOCTL, 0x80E, int)
#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int)
#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int)
#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int)
#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int)
#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char)
#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int)
#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int)
#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int)
#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int)
#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char)
#define IOCTL_CLOSE_NOTIFICATION _IO(BCM_IOCTL, 0x814)
#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815)
#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, IOCTL_BUFFER)
#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816)
#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815)
#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, struct bcm_ioctl_buffer)
#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816)
#define IOCTL_CINR_LEVEL_REQ _IOW(BCM_IOCTL, 0x817, char)
#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817,char)
#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817, char)
#define IOCTL_BE_BUCKET_SIZE _IOW(BCM_IOCTL, 0x818, unsigned long)
#define IOCTL_RTPS_BUCKET_SIZE _IOW(BCM_IOCTL, 0x819, unsigned long)
#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long)
#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821)
#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int)
#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long)
#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821)
#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int)
#define IOCTL_BCM_GET_DRIVER_VERSION _IOR(BCM_IOCTL, 0x829, int)
#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int)
#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int)
#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int)
#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int)
#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int)
#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int)
#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int)
#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char)
#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int)
#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int)
#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int)
#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int)
#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int)
#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int)
#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int)
#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char)
#define IOCTL_BCM_REGISTER_READ_PRIVATE _IOW(BCM_IOCTL, 0x827, char)
#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, IOCTL_BUFFER)
#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int)
#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int)
#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, struct bcm_ioctl_buffer)
#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int)
#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int)
#define IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE _IOR(BCM_IOCTL, 0x860, int)
#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int)
#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int)
#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int)
#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int)
#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int)
#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int)
#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int)
#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int)
#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int)
#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int)
#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int)
#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int)
#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int)
#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int)
#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int)
#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int)
#define IOCTL_BCM_FLASH2X_SECTION_WRITE _IOW(BCM_IOCTL, 0x866, int)
#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL, 0x867, int)
#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL, 0x868, int)
#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL, 0x869)
#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870, int)
#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int)
#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int)
#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int)
#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int)
#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int)
#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int)
#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int)
#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, struct bcm_ioctl_buffer)
#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, struct bcm_ioctl_buffer)
#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL,0x867, int)
enum bcm_interface_type {
BCM_MII,
BCM_CARDBUS,
BCM_USB,
BCM_SDIO,
BCM_PCMCIA
};
#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL,0x868, int)
#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL,0x869)
#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870,int)
#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int)
#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int)
#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int)
#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int)
#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int)
#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int)
#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int)
#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, IOCTL_BUFFER)
#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, IOCTL_BUFFER)
typedef enum _BCM_INTERFACE_TYPE
{
BCM_MII,
BCM_CARDBUS,
BCM_USB,
BCM_SDIO,
BCM_PCMCIA
}BCM_INTERFACE_TYPE;
typedef struct _DEVICE_DRIVER_INFO
{
NVM_TYPE u32NVMType;
UINT MaxRDMBufferSize;
BCM_INTERFACE_TYPE u32InterfaceType;
UINT u32DSDStartOffset;
UINT u32RxAlignmentCorrection;
UINT u32Reserved[10];
} DEVICE_DRIVER_INFO;
typedef struct _NVM_READWRITE
{
struct bcm_driver_info {
NVM_TYPE u32NVMType;
unsigned int MaxRDMBufferSize;
enum bcm_interface_type u32InterfaceType;
unsigned int u32DSDStartOffset;
unsigned int u32RxAlignmentCorrection;
unsigned int u32Reserved[10];
};
struct bcm_nvm_readwrite {
void __user *pBuffer;
// Data to be written from|read to. Memory should be allocated by the caller.
uint32_t uiOffset;
// offset at which data should be written to or read from.
uint32_t uiNumBytes;
bool bVerify;
};
uint32_t uiNumBytes;
// No. of bytes to be written or read.
struct bcm_bulk_wrm_buffer {
unsigned long Register;
unsigned long SwapEndian;
unsigned long Values[1];
};
bool bVerify;
// Applicable only for write. If set verification of written data will be done.
} NVM_READWRITE,*PNVM_READWRITE;
typedef struct bulkwrmbuffer
{
ULONG Register;
ULONG SwapEndian;
ULONG Values[1];
}BULKWRM_BUFFER,*PBULKWRM_BUFFER;
/***********Structure used for FlashMap2.x *******************************/
/*
* These are Sction present inside the Flash.
* There is sectional RD/WR for flash Map 2.x.
* hence these section will be used in read/write API.
*/
typedef enum _FLASH2X_SECTION_VAL
{
NO_SECTION_VAL = 0, //no section is chosen when absolute offset is given for RD/WR
enum bcm_flash2x_section_val {
NO_SECTION_VAL = 0, /* no section is chosen when absolute offset is given for RD/WR */
ISO_IMAGE1,
ISO_IMAGE2,
DSD0,
@ -257,104 +146,81 @@ typedef enum _FLASH2X_SECTION_VAL
ISO_IMAGE2_PART2,
ISO_IMAGE2_PART3,
TOTAL_SECTIONS
}FLASH2X_SECTION_VAL;
};
/*
* Structure used for READ/WRITE Flash Map2.x
*/
typedef struct _FLASH2X_READWRITE
{
FLASH2X_SECTION_VAL Section; //which section has to be read/written
B_UINT32 offset; //Offset within Section.
B_UINT32 numOfBytes; //NOB from the offset
B_UINT32 bVerify;
void __user *pDataBuff; //Buffer for reading/writing
}FLASH2X_READWRITE, *PFLASH2X_READWRITE;
/*
* This structure is used for coping one section to other.
* there are two ways to copy one section to other.
* it NOB =0, complete section will be copied on to other.
* if NOB !=0, only NOB will be copied from the given offset.
*/
typedef struct _FLASH2X_COPY_SECTION
{
//Src Section from which Data has to be copied to DstSection
FLASH2X_SECTION_VAL SrcSection;
//Destination Section from where Data has to be coppied.
FLASH2X_SECTION_VAL DstSection;
//Offset within Section. if NOB =0 it will be ignored and data will be coped from offset 0.
B_UINT32 offset;
//NOB from the offset. if NOB = 0 complete src section will be copied to Destination section.
B_UINT32 numOfBytes;
} FLASH2X_COPY_SECTION, *PFLASH2X_COPY_SECTION;
typedef enum _SECTION_TYPE
{
ISO = 0,
VSA = 1,
DSD = 2
} SECTION_TYPE, *PSECTION_TYPE;
* Structure used for READ/WRITE Flash Map2.x
*/
struct bcm_flash2x_readwrite {
enum bcm_flash2x_section_val Section; /* which section has to be read/written */
u32 offset; /* Offset within Section. */
u32 numOfBytes; /* NOB from the offset */
u32 bVerify;
void __user *pDataBuff; /* Buffer for reading/writing */
};
/*
* This section provide the complete bitmap of the Flash.
* using this map lib/APP will isssue read/write command.
Fields are defined as :
Bit [0] = section is present //1:present, 0: Not present
* Bit [1] = section is valid //1: valid, 0: not valid
* Bit [2] = Section is R/W //0: RW, 1: RO
* Bit [3] = Section is Active or not 1 means Active, 0->inactive
* Bit [7...3] = Reserved
*/
* This structure is used for coping one section to other.
* there are two ways to copy one section to other.
* it NOB =0, complete section will be copied on to other.
* if NOB !=0, only NOB will be copied from the given offset.
*/
typedef struct _FLASH2X_BITMAP
{
UCHAR ISO_IMAGE1;
UCHAR ISO_IMAGE2;
UCHAR DSD0;
UCHAR DSD1;
UCHAR DSD2;
UCHAR VSA0;
UCHAR VSA1;
UCHAR VSA2;
UCHAR SCSI;
UCHAR CONTROL_SECTION;
//Reserved for future use
UCHAR Reserved0;
UCHAR Reserved1;
UCHAR Reserved2;
}FLASH2X_BITMAP, *PFLASH2X_BITMAP;
struct bcm_flash2x_copy_section {
enum bcm_flash2x_section_val SrcSection;
enum bcm_flash2x_section_val DstSection;
u32 offset;
u32 numOfBytes;
};
//for net entry time check
typedef struct _ST_TIME_ELAPSED_
{
ULONG64 ul64TimeElapsedSinceNetEntry;
UINT32 uiReserved[4]; //By chance if required for future proofing
}ST_TIME_ELAPSED,*PST_TIME_ELAPSED;
/*
* This section provide the complete bitmap of the Flash.
* using this map lib/APP will isssue read/write command.
* Fields are defined as :
* Bit [0] = section is present //1:present, 0: Not present
* Bit [1] = section is valid //1: valid, 0: not valid
* Bit [2] = Section is R/W //0: RW, 1: RO
* Bit [3] = Section is Active or not 1 means Active, 0->inactive
* Bit [7...3] = Reserved
*/
struct bcm_flash2x_bitmap {
unsigned char ISO_IMAGE1;
unsigned char ISO_IMAGE2;
unsigned char DSD0;
unsigned char DSD1;
unsigned char DSD2;
unsigned char VSA0;
unsigned char VSA1;
unsigned char VSA2;
unsigned char SCSI;
unsigned char CONTROL_SECTION;
/* Reserved for future use */
unsigned char Reserved0;
unsigned char Reserved1;
unsigned char Reserved2;
};
struct bcm_time_elapsed {
unsigned long long ul64TimeElapsedSinceNetEntry;
u32 uiReserved[4];
};
enum {
WIMAX_IDX=0, /*To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/
HOST_IDX, /*To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/
MAX_IDX
WIMAX_IDX = 0, /* To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */
HOST_IDX, /* To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */
MAX_IDX
};
typedef struct stGPIOMultiInfo
{
UINT uiGPIOCommand; /* 1 for set and 0 for get*/
UINT uiGPIOMask; /* set the correspondig bit to 1 to access GPIO*/
UINT uiGPIOValue; /* 0 or 1; value to be set when command is 1.*/
}__attribute__((packed))GPIO_MULTI_INFO , *PGPIO_MULTI_INFO;
typedef struct stGPIOMultiMode
{
UINT uiGPIOMode; /* 1 for OUT mode, 0 for IN mode*/
UINT uiGPIOMask; /* GPIO mask to set mode*/
}__attribute__((packed))GPIO_MULTI_MODE, *PGPIO_MULTI_MODE;
struct bcm_gpio_multi_info {
unsigned int uiGPIOCommand; /* 1 for set and 0 for get */
unsigned int uiGPIOMask; /* set the correspondig bit to 1 to access GPIO */
unsigned int uiGPIOValue; /* 0 or 1; value to be set when command is 1. */
} __packed;
struct bcm_gpio_multi_mode {
unsigned int uiGPIOMode; /* 1 for OUT mode, 0 for IN mode */
unsigned int uiGPIOMask; /* GPIO mask to set mode */
} __packed;
#endif

View File

@ -21,10 +21,12 @@ static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
INT i = 0;
struct timeval tv;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
"=====>\n");
if(NULL == Adapter)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS,
DBG_LVL_ALL, "Adapter found NULL!\n");
return;
}

View File

@ -1,14 +1,14 @@
#include "headers.h"
static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc);
static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter);
static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter);
static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer);
static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter);
static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter);
static VOID default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
{
UINT uiLoopIndex;
unsigned int uiLoopIndex;
for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) {
Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD;
@ -24,10 +24,10 @@ static VOID default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
return;
}
INT InitAdapter(struct bcm_mini_adapter *psAdapter)
int InitAdapter(struct bcm_mini_adapter *psAdapter)
{
int i = 0;
INT Status = STATUS_SUCCESS;
int Status = STATUS_SUCCESS;
BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter);
if (psAdapter == NULL) {
@ -93,7 +93,7 @@ INT InitAdapter(struct bcm_mini_adapter *psAdapter)
return STATUS_SUCCESS;
}
VOID AdapterFree(struct bcm_mini_adapter *Adapter)
void AdapterFree(struct bcm_mini_adapter *Adapter)
{
int count;
beceem_protocol_reset(Adapter);
@ -216,12 +216,12 @@ exit_download:
* Logical Adapter
* Control Packet Buffer
*/
INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
{
struct bcm_leader *pLeader = NULL;
INT Status = 0;
unsigned char *ctrl_buff = NULL;
UINT pktlen = 0;
int Status = 0;
unsigned char *ctrl_buff;
unsigned int pktlen = 0;
struct bcm_link_request *pLinkReq = NULL;
PUCHAR pucAddIndication = NULL;
@ -253,7 +253,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
return STATUS_FAILURE;
}
if (TRUE == Adapter->bShutStatus) {
if (Adapter->bShutStatus == TRUE) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n");
if (Adapter->bTriedToWakeUpFromlowPowerMode == FALSE) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n");
@ -275,7 +275,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
}
}
if (TRUE == Adapter->IdleMode) {
if (Adapter->IdleMode == TRUE) {
/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */
if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 ||
pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) {
@ -325,64 +325,66 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
pktlen = pLeader->PLength;
ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS];
if (!ctrl_buff) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
return -ENOMEM;
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x",
atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen);
if (ctrl_buff) {
if (pLeader) {
if ((pLeader->Status == 0x80) ||
(pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) {
/*
* Restructure the DSX message to handle Multiple classifier Support
* Write the Service Flow param Structures directly to the target
* and embed the pointers in the DSX messages sent to target.
*/
/* Lets store the current length of the control packet we are transmitting */
pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
pktlen = pLeader->PLength;
Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen);
if (Status != 1) {
ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly ");
return STATUS_FAILURE;
}
/*
* update the leader to use the new length
* The length of the control packet is length of message being sent + Leader length
*/
pLeader->PLength = pktlen;
if (pLeader) {
if ((pLeader->Status == 0x80) ||
(pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) {
/*
* Restructure the DSX message to handle Multiple classifier Support
* Write the Service Flow param Structures directly to the target
* and embed the pointers in the DSX messages sent to target.
*/
/* Lets store the current length of the control packet we are transmitting */
pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
pktlen = pLeader->PLength;
Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen);
if (Status != 1) {
ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, FALSE);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly ");
return STATUS_FAILURE;
}
/*
* update the leader to use the new length
* The length of the control packet is length of message being sent + Leader length
*/
pLeader->PLength = pktlen;
}
if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE)
return -EINVAL;
memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
*(struct bcm_leader *)ctrl_buff = *pLeader;
memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");
/* Update the statistics counters */
spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength;
Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
atomic_inc(&Adapter->TotalPacketCount);
spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
Adapter->PackInfo[HiPriority].bValid = TRUE;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
Adapter->PackInfo[HiPriority].bValid);
Status = STATUS_SUCCESS;
/*Queue the packet for transmission */
atomic_inc(&Adapter->index_wr_txcntrlpkt);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets");
atomic_set(&Adapter->TxPktAvail, 1);
wake_up(&Adapter->tx_packet_wait_queue);
} else {
Status = -ENOMEM;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
}
if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE)
return -EINVAL;
memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
*(struct bcm_leader *)ctrl_buff = *pLeader;
memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");
/* Update the statistics counters */
spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength;
Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
atomic_inc(&Adapter->TotalPacketCount);
spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
Adapter->PackInfo[HiPriority].bValid = TRUE;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
Adapter->PackInfo[HiPriority].bValid);
Status = STATUS_SUCCESS;
/*Queue the packet for transmission */
atomic_inc(&Adapter->index_wr_txcntrlpkt);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets");
atomic_set(&Adapter->TxPktAvail, 1);
wake_up(&Adapter->tx_packet_wait_queue);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<====");
return Status;
}
@ -397,7 +399,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer)
*
* Returns - None.
*******************************************************************/
VOID LinkMessage(struct bcm_mini_adapter *Adapter)
void LinkMessage(struct bcm_mini_adapter *Adapter)
{
struct bcm_link_request *pstLinkRequest = NULL;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
@ -448,11 +450,11 @@ VOID LinkMessage(struct bcm_mini_adapter *Adapter)
*
* Returns - None.
************************************************************************/
VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer)
void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer)
{
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__);
Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__);
return;
}
@ -467,7 +469,7 @@ VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer)
*
* Returns - None.
***********************************************************************/
VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
{
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>");
@ -543,7 +545,7 @@ VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuff
void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
{
INT status = 0, NVMAccess = 0, lowPwrAbortMsg = 0;
int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0;
struct timeval tv;
struct bcm_link_request stIdleResponse = {{0} };
memset(&tv, 0, sizeof(tv));
@ -583,7 +585,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
/* Wait for the LED to TURN OFF before sending ACK response */
if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
INT iRetVal = 0;
int iRetVal = 0;
/* Wake the LED Thread with IDLEMODE_ENTER State */
Adapter->DriverState = LOWPOWER_MODE_ENTER;
@ -609,7 +611,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
up(&Adapter->rdmwrmsync);
/* Killing all URBS. */
if (Adapter->bDoSuspend == TRUE)
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
} else {
Adapter->bPreparingForLowPowerMode = FALSE;
}
@ -625,7 +627,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
if ((status != STATUS_SUCCESS)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n");
Adapter->bPreparingForLowPowerMode = FALSE;
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
}
do_gettimeofday(&tv);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec * 1000 + tv.tv_usec / 1000);
@ -640,11 +642,11 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
*
* Returns - None.
*******************************************************************/
VOID DumpPackInfo(struct bcm_mini_adapter *Adapter)
void DumpPackInfo(struct bcm_mini_adapter *Adapter)
{
UINT uiLoopIndex = 0;
UINT uiIndex = 0;
UINT uiClsfrIndex = 0;
unsigned int uiLoopIndex = 0;
unsigned int uiIndex = 0;
unsigned int uiClsfrIndex = 0;
struct bcm_classifier_rule *pstClassifierEntry = NULL;
for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
@ -776,11 +778,11 @@ int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
{
int retval = STATUS_SUCCESS;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
struct bcm_interface_adapter *psIntfAdapter = NULL;
unsigned int value = 0, uiResetValue = 0;
int bytes;
psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter));
psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter));
ps_adapter->bDDRInitDone = FALSE;
if (ps_adapter->chip_id >= T3LPB) {
@ -920,7 +922,7 @@ int run_card_proc(struct bcm_mini_adapter *ps_adapter)
int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter)
{
int status;
UINT value = 0;
unsigned int value = 0;
/*
* Create the threads first and then download the
* Firm/DDR Settings..
@ -1088,7 +1090,7 @@ static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
{
UINT uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0;
unsigned int uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0;
if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) {
pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
@ -1144,9 +1146,9 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
doPowerAutoCorrection(Adapter);
}
static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
{
UINT reporting_mode;
unsigned int reporting_mode;
reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02;
psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
@ -1175,26 +1177,26 @@ static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
}
}
static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, unsigned int uiByteCount)
{
UINT uiIndex = 0;
unsigned int uiIndex = 0;
if (RWM_WRITE == rwFlag) {
for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++)
for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++)
puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]);
} else {
for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++)
for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++)
puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]);
}
}
int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
int rdm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
return Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
uiAddress, pucBuff, sSize);
}
int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
int wrm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
int iRetVal;
@ -1203,25 +1205,25 @@ int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t
return iRetVal;
}
int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
convertEndian(RWM_WRITE, pucBuff, size);
return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
}
int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
INT uiRetVal = 0;
int uiRetVal = 0;
uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
convertEndian(RWM_READ, (PUINT)pucBuff, size);
convertEndian(RWM_READ, (unsigned int *)pucBuff, size);
return uiRetVal;
}
int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
INT status = STATUS_SUCCESS;
int status = STATUS_SUCCESS;
down(&Adapter->rdmwrmsync);
if ((Adapter->IdleMode == TRUE) ||
@ -1238,7 +1240,7 @@ exit:
return status;
}
int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
int wrmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
int iRetVal = STATUS_SUCCESS;
@ -1258,9 +1260,9 @@ exit:
return iRetVal;
}
int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
{
INT uiRetVal = STATUS_SUCCESS;
int uiRetVal = STATUS_SUCCESS;
down(&Adapter->rdmwrmsync);
if ((Adapter->IdleMode == TRUE) ||
@ -1277,13 +1279,13 @@ exit:
return uiRetVal;
}
static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
{
int clear_abort_pattern = 0, Status = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
/* target has woken up From Shut Down */
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n");
Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern));
Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (unsigned int *)&clear_abort_pattern, sizeof(clear_abort_pattern));
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status);
return;
@ -1306,11 +1308,11 @@ static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
}
static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
{
struct bcm_link_request stShutdownResponse;
UINT NVMAccess = 0, lowPwrAbortMsg = 0;
UINT Status = 0;
unsigned int NVMAccess = 0, lowPwrAbortMsg = 0;
unsigned int Status = 0;
memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request));
stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ;
@ -1346,7 +1348,7 @@ static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
/* Wait for the LED to TURN OFF before sending ACK response */
if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
INT iRetVal = 0;
int iRetVal = 0;
/* Wake the LED Thread with LOWPOWER_MODE_ENTER State */
Adapter->DriverState = LOWPOWER_MODE_ENTER;
@ -1370,7 +1372,7 @@ static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
up(&Adapter->rdmwrmsync);
/* Killing all URBS. */
if (Adapter->bDoSuspend == TRUE)
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
} else {
Adapter->bPreparingForLowPowerMode = FALSE;
}
@ -1386,13 +1388,13 @@ static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter)
if ((Status != STATUS_SUCCESS)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n");
Adapter->bPreparingForLowPowerMode = FALSE;
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
}
}
static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
{
B_UINT32 uiResetValue = 0;
unsigned int uiResetValue = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
@ -1412,14 +1414,14 @@ static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR p
}
SendShutModeResponse(Adapter);
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
return;
}
VOID ResetCounters(struct bcm_mini_adapter *Adapter)
void ResetCounters(struct bcm_mini_adapter *Adapter)
{
beceem_protocol_reset(Adapter);
Adapter->CurrNumRecvDescs = 0;
@ -1437,7 +1439,7 @@ VOID ResetCounters(struct bcm_mini_adapter *Adapter)
struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP)
{
UINT uiIndex = 0;
unsigned int uiIndex = 0;
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
@ -1451,7 +1453,7 @@ struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter,
void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo)
{
UINT uiIndex = 0;
unsigned int uiIndex = 0;
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) {
memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info));
@ -1462,7 +1464,7 @@ void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_p
void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp)
{
UINT uiIndex = 0;
unsigned int uiIndex = 0;
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
@ -1474,7 +1476,7 @@ void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentificati
void update_per_cid_rx(struct bcm_mini_adapter *Adapter)
{
UINT qindex = 0;
unsigned int qindex = 0;
if ((jiffies - Adapter->liDrainCalculated) < XSECONDS)
return;
@ -1498,14 +1500,14 @@ void update_per_cid_rx(struct bcm_mini_adapter *Adapter)
void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter)
{
INT iIndex = 0;
int iIndex = 0;
u32 uibuff[MAX_TARGET_DSX_BUFFERS];
int bytes;
if (!atomic_read(&Adapter->uiMBupdate))
return;
bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS);
bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(unsigned int) * MAX_TARGET_DSX_BUFFERS);
if (bytes < 0) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
return;
@ -1522,7 +1524,7 @@ void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter)
atomic_set(&Adapter->uiMBupdate, FALSE);
}
void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex)
void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex)
{
struct sk_buff *PacketToDrop = NULL;
struct net_device_stats *netstats = &Adapter->dev->stats;
@ -1573,6 +1575,6 @@ static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter)
for (i = 0; i < HiPriority; i++) {
/* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */
/* It is same between MIBs and SF. */
memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS));
memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(struct bcm_mibs_parameters));
}
}

View File

@ -79,17 +79,17 @@ int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t
int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId, void __user * user_buffer);
void SendIdleModeResponse(struct bcm_mini_adapter *Adapter);
int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS *buf);
void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, struct bcm_tarang_data *pTarang);
int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *buf);
void GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *ioBuffer, struct bcm_tarang_data *pTarang);
void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter);
int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo);
@ -161,14 +161,14 @@ INT BeceemNVMWrite(
INT BcmInitNVM(struct bcm_mini_adapter *Adapter);
INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize);
BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section);
BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap);
INT BcmFlash2xBulkWrite(
struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
FLASH2X_SECTION_VAL eFlashSectionVal,
enum bcm_flash2x_section_val eFlashSectionVal,
UINT uiOffset,
UINT uiNumBytes,
UINT bVerify);
@ -176,24 +176,24 @@ INT BcmFlash2xBulkWrite(
INT BcmFlash2xBulkRead(
struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
FLASH2X_SECTION_VAL eFlashSectionVal,
enum bcm_flash2x_section_val eFlashSectionVal,
UINT uiOffsetWithinSectionVal,
UINT uiNumBytes);
INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal);
INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal);
INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal);
INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter);
INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter);
INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut);
INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
INT BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut);
INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal);
INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite);
INT IsFlash2x(struct bcm_mini_adapter *Adapter);
INT BcmCopySection(struct bcm_mini_adapter *Adapter,
FLASH2X_SECTION_VAL SrcSection,
FLASH2X_SECTION_VAL DstSection,
enum bcm_flash2x_section_val SrcSection,
enum bcm_flash2x_section_val DstSection,
UINT offset,
UINT numOfBytes);
@ -203,8 +203,8 @@ BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter);
VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter,PUINT puiBuffer);
int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,

View File

@ -205,7 +205,7 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje
if (Adapter->bEndPointHalted == TRUE) {
Bcm_clear_halt_of_endpoints(Adapter);
Adapter->bEndPointHalted = FALSE;
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
}
if (Adapter->LinkUpStatus && !Adapter->IdleMode) {

View File

@ -36,91 +36,91 @@
struct bcm_packet_class_rules {
/* 16bit UserPriority Of The Service Flow */
B_UINT16 u16UserPriority;
u16 u16UserPriority;
/* 16bit VLANID Of The Service Flow */
B_UINT16 u16VLANID;
u16 u16VLANID;
/* 16bit Packet Classification RuleIndex Of The Service Flow */
B_UINT16 u16PacketClassificationRuleIndex;
u16 u16PacketClassificationRuleIndex;
/* 8bit Classifier Rule Priority Of The Service Flow */
B_UINT8 u8ClassifierRulePriority;
u8 u8ClassifierRulePriority;
/* Length of IP TypeOfService field */
B_UINT8 u8IPTypeOfServiceLength;
u8 u8IPTypeOfServiceLength;
/* 3bytes IP TypeOfService */
B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
u8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
/* Protocol used in classification of Service Flow */
B_UINT8 u8Protocol;
u8 u8Protocol;
/* Length of IP Masked Source Address */
B_UINT8 u8IPMaskedSourceAddressLength;
u8 u8IPMaskedSourceAddressLength;
/* IP Masked Source Address used in classification for the Service Flow */
B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
u8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
/* Length of IP Destination Address */
B_UINT8 u8IPDestinationAddressLength;
u8 u8IPDestinationAddressLength;
/* IP Destination Address used in classification for the Service Flow */
B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
u8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
/* Length of Protocol Source Port Range */
B_UINT8 u8ProtocolSourcePortRangeLength;
u8 u8ProtocolSourcePortRangeLength;
/* Protocol Source Port Range used in the Service Flow */
B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
u8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
/* Length of Protocol Dest Port Range */
B_UINT8 u8ProtocolDestPortRangeLength;
u8 u8ProtocolDestPortRangeLength;
/* Protocol Dest Port Range used in the Service Flow */
B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
u8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
/* Length of Ethernet Destination MAC Address */
B_UINT8 u8EthernetDestMacAddressLength;
u8 u8EthernetDestMacAddressLength;
/* Ethernet Destination MAC Address used in classification of the Service Flow */
B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
u8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
/* Length of Ethernet Source MAC Address */
B_UINT8 u8EthernetSourceMACAddressLength;
u8 u8EthernetSourceMACAddressLength;
/* Ethernet Source MAC Address used in classification of the Service Flow */
B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
u8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
/* Length of Ethertype */
B_UINT8 u8EthertypeLength;
u8 u8EthertypeLength;
/* 3bytes Ethertype Of The Service Flow */
B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES];
u8 u8Ethertype[NUM_ETHERTYPE_BYTES];
/* 8bit Associated PHSI Of The Service Flow */
B_UINT8 u8AssociatedPHSI;
u8 u8AssociatedPHSI;
/* Length of Vendor Specific Classifier Param length Of The Service Flow */
B_UINT8 u8VendorSpecificClassifierParamLength;
u8 u8VendorSpecificClassifierParamLength;
/* Vendor Specific Classifier Param Of The Service Flow */
B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
u8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
/* Length Of IPv6 Flow Lable of the Service Flow */
B_UINT8 u8IPv6FlowLableLength;
u8 u8IPv6FlowLableLength;
/* IPv6 Flow Lable Of The Service Flow */
B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
u8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
/* Action associated with the classifier rule */
B_UINT8 u8ClassifierActionRule;
B_UINT16 u16ValidityBitMap;
u8 u8ClassifierActionRule;
u16 u16ValidityBitMap;
};
struct bcm_phs_rules {
/* 8bit PHS Index Of The Service Flow */
B_UINT8 u8PHSI;
u8 u8PHSI;
/* PHSF Length Of The Service Flow */
B_UINT8 u8PHSFLength;
u8 u8PHSFLength;
/* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */
B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
u8 u8PHSF[MAX_PHS_LENGTHS];
/* PHSM Length Of The Service Flow */
B_UINT8 u8PHSMLength;
u8 u8PHSMLength;
/* PHS Mask for the SF */
B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
u8 u8PHSM[MAX_PHS_LENGTHS];
/* 8bit Total number of bytes to be suppressed for the Service Flow */
B_UINT8 u8PHSS;
u8 u8PHSS;
/* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */
B_UINT8 u8PHSV;
u8 u8PHSV;
/* Vendor Specific PHS param Length Of The Service Flow */
B_UINT8 u8VendorSpecificPHSParamsLength;
u8 u8VendorSpecificPHSParamsLength;
/* Vendor Specific PHS param Of The Service Flow */
B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
B_UINT8 u8Padding[2];
u8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
u8 u8Padding[2];
};
struct bcm_convergence_types {
/* 8bit Phs Classfier Action Of The Service Flow */
B_UINT8 u8ClassfierDSCAction;
u8 u8ClassfierDSCAction;
/* 8bit Phs DSC Action Of The Service Flow */
B_UINT8 u8PhsDSCAction;
u8 u8PhsDSCAction;
/* 16bit Padding */
B_UINT8 u8Padding[2];
u8 u8Padding[2];
/* Packet classification rules structure */
struct bcm_packet_class_rules cCPacketClassificationRule;
/* Payload header suppression rules structure */
@ -129,118 +129,118 @@ struct bcm_convergence_types {
struct bcm_connect_mgr_params {
/* 32bitSFID Of The Service Flow */
B_UINT32 u32SFID;
u32 u32SFID;
/* 32bit Maximum Sustained Traffic Rate of the Service Flow */
B_UINT32 u32MaxSustainedTrafficRate;
u32 u32MaxSustainedTrafficRate;
/* 32bit Maximum Traffic Burst allowed for the Service Flow */
B_UINT32 u32MaxTrafficBurst;
u32 u32MaxTrafficBurst;
/* 32bit Minimum Reserved Traffic Rate of the Service Flow */
B_UINT32 u32MinReservedTrafficRate;
u32 u32MinReservedTrafficRate;
/* 32bit Tolerated Jitter of the Service Flow */
B_UINT32 u32ToleratedJitter;
u32 u32ToleratedJitter;
/* 32bit Maximum Latency of the Service Flow */
B_UINT32 u32MaximumLatency;
u32 u32MaximumLatency;
/* 16bitCID Of The Service Flow */
B_UINT16 u16CID;
u16 u16CID;
/* 16bit SAID on which the service flow being set up shall be mapped */
B_UINT16 u16TargetSAID;
u16 u16TargetSAID;
/* 16bit ARQ window size negotiated */
B_UINT16 u16ARQWindowSize;
u16 u16ARQWindowSize;
/* 16bit Total Tx delay incl sending, receiving & processing delays */
B_UINT16 u16ARQRetryTxTimeOut;
u16 u16ARQRetryTxTimeOut;
/* 16bit Total Rx delay incl sending, receiving & processing delays */
B_UINT16 u16ARQRetryRxTimeOut;
u16 u16ARQRetryRxTimeOut;
/* 16bit ARQ block lifetime */
B_UINT16 u16ARQBlockLifeTime;
u16 u16ARQBlockLifeTime;
/* 16bit ARQ Sync loss timeout */
B_UINT16 u16ARQSyncLossTimeOut;
u16 u16ARQSyncLossTimeOut;
/* 16bit ARQ Purge timeout */
B_UINT16 u16ARQRxPurgeTimeOut;
u16 u16ARQRxPurgeTimeOut;
/* TODO::Remove this once we move to a new CORR2 driver
* brief Size of an ARQ block
*/
B_UINT16 u16ARQBlockSize;
u16 u16ARQBlockSize;
/* #endif */
/* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */
B_UINT16 u16SDUInterArrivalTime;
u16 u16SDUInterArrivalTime;
/* 16bit Specifies the time base for rate measurement */
B_UINT16 u16TimeBase;
u16 u16TimeBase;
/* 16bit Interval b/w Successive Grant oppurtunities */
B_UINT16 u16UnsolicitedGrantInterval;
u16 u16UnsolicitedGrantInterval;
/* 16bit Interval b/w Successive Polling grant oppurtunities */
B_UINT16 u16UnsolicitedPollingInterval;
u16 u16UnsolicitedPollingInterval;
/* internal var to get the overhead */
B_UINT16 u16MacOverhead;
u16 u16MacOverhead;
/* MBS contents Identifier */
B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
u16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
/* MBS contents Identifier length */
B_UINT8 u8MBSContentsIDLength;
u8 u8MBSContentsIDLength;
/* ServiceClassName Length Of The Service Flow */
B_UINT8 u8ServiceClassNameLength;
u8 u8ServiceClassNameLength;
/* 32bytes ServiceClassName Of The Service Flow */
B_UINT8 u8ServiceClassName[32];
u8 u8ServiceClassName[32];
/* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */
B_UINT8 u8MBSService;
u8 u8MBSService;
/* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */
B_UINT8 u8QosParamSet;
u8 u8QosParamSet;
/* 8bit Traffic Priority Of the Service Flow */
B_UINT8 u8TrafficPriority;
u8 u8TrafficPriority;
/* 8bit Uplink Grant Scheduling Type of The Service Flow */
B_UINT8 u8ServiceFlowSchedulingType;
u8 u8ServiceFlowSchedulingType;
/* 8bit Request transmission Policy of the Service Flow */
B_UINT8 u8RequesttransmissionPolicy;
u8 u8RequesttransmissionPolicy;
/* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator;
u8 u8FixedLengthVSVariableLengthSDUIndicator;
/* 8bit Length of the SDU for a fixed length SDU service flow */
B_UINT8 u8SDUSize;
u8 u8SDUSize;
/* 8bit Indicates whether or not ARQ is requested for this connection */
B_UINT8 u8ARQEnable;
u8 u8ARQEnable;
/* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */
B_UINT8 u8ARQDeliverInOrder;
u8 u8ARQDeliverInOrder;
/* 8bit Receiver ARQ ACK processing time */
B_UINT8 u8RxARQAckProcessingTime;
u8 u8RxARQAckProcessingTime;
/* 8bit Convergence Sublayer Specification Of The Service Flow */
B_UINT8 u8CSSpecification;
u8 u8CSSpecification;
/* 8 bit Type of data delivery service */
B_UINT8 u8TypeOfDataDeliveryService;
u8 u8TypeOfDataDeliveryService;
/* 8bit Specifies whether a service flow may generate Paging */
B_UINT8 u8PagingPreference;
u8 u8PagingPreference;
/* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */
B_UINT8 u8MBSZoneIdentifierassignment;
u8 u8MBSZoneIdentifierassignment;
/* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */
B_UINT8 u8TrafficIndicationPreference;
u8 u8TrafficIndicationPreference;
/* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */
B_UINT8 u8GlobalServicesClassNameLength;
u8 u8GlobalServicesClassNameLength;
/* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */
B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
u8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
/* 8bit Indicates whether or not SN feedback is enabled for the conn */
B_UINT8 u8SNFeedbackEnabled;
u8 u8SNFeedbackEnabled;
/* Indicates the size of the Fragment Sequence Number for the connection */
B_UINT8 u8FSNSize;
u8 u8FSNSize;
/* 8bit Number of CIDs in active BS list */
B_UINT8 u8CIDAllocation4activeBSsLength;
u8 u8CIDAllocation4activeBSsLength;
/* CIDs of BS in the active list */
B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
u8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
/* Specifies if PDU extended subheader should be applied on every PDU on this conn */
B_UINT8 u8PDUSNExtendedSubheader4HarqReordering;
u8 u8PDUSNExtendedSubheader4HarqReordering;
/* 8bit Specifies whether the connection uses HARQ or not */
B_UINT8 u8HARQServiceFlows;
u8 u8HARQServiceFlows;
/* Specifies the length of Authorization token */
B_UINT8 u8AuthTokenLength;
u8 u8AuthTokenLength;
/* Specifies the Authorization token */
B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH];
u8 u8AuthToken[AUTH_TOKEN_LENGTH];
/* specifes Number of HARQ channels used to carry data length */
B_UINT8 u8HarqChannelMappingLength;
u8 u8HarqChannelMappingLength;
/* specifes HARQ channels used to carry data */
B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
u8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
/* 8bit Length of Vendor Specific QoS Params */
B_UINT8 u8VendorSpecificQoSParamLength;
u8 u8VendorSpecificQoSParamLength;
/* 1byte Vendor Specific QoS Param Of The Service Flow */
B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
u8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
/* indicates total classifiers in the SF */
B_UINT8 u8TotalClassifiers; /* < Total number of valid classifiers */
B_UINT8 bValid; /* < Validity flag */
B_UINT8 u8Padding; /* < Padding byte */
u8 u8TotalClassifiers; /* < Total number of valid classifiers */
u8 bValid; /* < Validity flag */
u8 u8Padding; /* < Padding byte */
/*
* Structure for Convergence SubLayer Types with a maximum of 4 classifiers
*/
@ -248,64 +248,64 @@ struct bcm_connect_mgr_params {
};
struct bcm_add_request {
B_UINT8 u8Type; /* < Type */
B_UINT8 eConnectionDir; /* < Connection direction */
u8 u8Type; /* < Type */
u8 eConnectionDir; /* < Connection direction */
/* brief 16 bit TID */
B_UINT16 u16TID; /* < 16bit TID */
u16 u16TID; /* < 16bit TID */
/* brief 16bitCID */
B_UINT16 u16CID; /* < 16bit CID */
u16 u16CID; /* < 16bit CID */
/* brief 16bitVCID */
B_UINT16 u16VCID; /* < 16bit VCID */
u16 u16VCID; /* < 16bit VCID */
struct bcm_connect_mgr_params *psfParameterSet; /* < connection manager parameters */
};
struct bcm_add_indication {
B_UINT8 u8Type; /* < Type */
B_UINT8 eConnectionDir; /* < Connection Direction */
u8 u8Type; /* < Type */
u8 eConnectionDir; /* < Connection Direction */
/* brief 16 bit TID */
B_UINT16 u16TID; /* < TID */
u16 u16TID; /* < TID */
/* brief 16bitCID */
B_UINT16 u16CID; /* < 16bitCID */
u16 u16CID; /* < 16bitCID */
/* brief 16bitVCID */
B_UINT16 u16VCID; /* < 16bitVCID */
u16 u16VCID; /* < 16bitVCID */
struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */
struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */
struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */
B_UINT8 u8CC; /* <Confirmation Code */
B_UINT8 u8Padd; /* < 8-bit Padding */
B_UINT16 u16Padd; /* < 16 bit Padding */
u8 u8CC; /* <Confirmation Code */
u8 u8Padd; /* < 8-bit Padding */
u16 u16Padd; /* < 16 bit Padding */
};
struct bcm_del_request {
B_UINT8 u8Type; /* < Type */
B_UINT8 u8Padding; /* < Padding byte */
B_UINT16 u16TID; /* < TID */
u8 u8Type; /* < Type */
u8 u8Padding; /* < Padding byte */
u16 u16TID; /* < TID */
/* brief 32bitSFID */
B_UINT32 u32SFID; /* < SFID */
u32 u32SFID; /* < SFID */
};
struct bcm_del_indication {
B_UINT8 u8Type; /* < Type */
B_UINT8 u8Padding; /* < Padding */
B_UINT16 u16TID; /* < TID */
u8 u8Type; /* < Type */
u8 u8Padding; /* < Padding */
u16 u16TID; /* < TID */
/* brief 16bitCID */
B_UINT16 u16CID; /* < CID */
u16 u16CID; /* < CID */
/* brief 16bitVCID */
B_UINT16 u16VCID; /* < VCID */
u16 u16VCID; /* < VCID */
/* brief 32bitSFID */
B_UINT32 u32SFID; /* < SFID */
u32 u32SFID; /* < SFID */
/* brief 8bit Confirmation code */
B_UINT8 u8ConfirmationCode; /* < Confirmation code */
B_UINT8 u8Padding1[3]; /* < 3 byte Padding */
u8 u8ConfirmationCode; /* < Confirmation code */
u8 u8Padding1[3]; /* < 3 byte Padding */
};
struct bcm_stim_sfhostnotify {
B_UINT32 SFID; /* SFID of the service flow */
B_UINT16 newCID; /* the new/changed CID */
B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */
B_UINT8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */
B_UINT8 QoSParamSet; /* QoS paramset of the retained SF */
B_UINT16 u16reserved; /* For byte alignment */
u32 SFID; /* SFID of the service flow */
u16 newCID; /* the new/changed CID */
u16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */
u8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */
u8 QoSParamSet; /* QoS paramset of the retained SF */
u16 u16reserved; /* For byte alignment */
};
#endif

View File

@ -9,7 +9,7 @@
#include "headers.h"
INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *pstHostMibs)
{
S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
S_PHS_RULE *pstPhsRule = NULL;
@ -31,7 +31,7 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS
astClassifierTable[nClassifierIndex],
(PVOID) & Adapter->
astClassifierTable[nClassifierIndex],
sizeof(S_MIBS_CLASSIFIER_RULE));
sizeof(struct bcm_mibs_classifier_rule));
}
/* Copy the SF Table */
@ -39,7 +39,7 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS
if (Adapter->PackInfo[nSfIndex].bValid) {
memcpy((PVOID) & pstHostMibs->astSFtable[nSfIndex],
(PVOID) & Adapter->PackInfo[nSfIndex],
sizeof(S_MIBS_SERVICEFLOW_TABLE));
sizeof(struct bcm_mibs_table));
} else {
/* If index in not valid,
* don't process this for the PHS table.
@ -94,16 +94,16 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS
return STATUS_SUCCESS;
}
VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, struct bcm_tarang_data *pTarang)
VOID GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *pstHostMibs, struct bcm_tarang_data *pTarang)
{
memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
&(pTarang->stDroppedAppCntrlMsgs),
sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
sizeof(struct bcm_mibs_dropped_cntrl_msg));
}
VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, struct bcm_connect_mgr_params *psfLocalSet, UINT uiSearchRuleIndex)
{
S_MIBS_EXTSERVICEFLOW_PARAMETERS *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
struct bcm_mibs_parameters *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
t->wmanIfSfid = psfLocalSet->u32SFID;
t->wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate;

View File

@ -14,25 +14,25 @@ static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter);
static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset);
static int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section);
static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section);
static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section);
static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd);
static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd);
static int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso);
static int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso);
static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr);
static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff,
FLASH2X_SECTION_VAL eFlash2xSectionVal,
enum bcm_flash2x_section_val eFlash2xSectionVal,
unsigned int uiOffset, unsigned int uiNumBytes);
static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter);
static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter);
static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);
static int BeceemFlashBulkRead(
struct bcm_mini_adapter *Adapter,
@ -2413,7 +2413,7 @@ static int ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
return STATUS_SUCCESS;
}
static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section)
static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
{
return (Adapter->uiVendorExtnFlag &&
(Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
@ -2660,14 +2660,14 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter)
/*
* BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
* @Adapter : Drivers Private Data structure
* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
* @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
*
* Return value:-
* On success it return the start offset of the provided section val
* On Failure -returns STATUS_FAILURE
*/
int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
{
/*
* Considering all the section for which end offset can be calculated or directly given
@ -2752,14 +2752,14 @@ int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO
/*
* BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
* @Adapter : Drivers Private Data structure
* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
* @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
*
* Return value:-
* On success it return the end offset of the provided section val
* On Failure -returns STATUS_FAILURE
*/
int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
int SectEndOffset = 0;
@ -2837,7 +2837,7 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_
* BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
* @Adapter :Driver Private Data Structure
* @pBuffer : Buffer where data has to be put after reading
* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
* @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
* @uiOffsetWithinSectionVal :- Offset with in provided section
* @uiNumBytes : Number of Bytes for Read
*
@ -2847,7 +2847,7 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_
int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
FLASH2X_SECTION_VAL eFlash2xSectionVal,
enum bcm_flash2x_section_val eFlash2xSectionVal,
unsigned int uiOffsetWithinSectionVal,
unsigned int uiNumBytes)
{
@ -2898,7 +2898,7 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
* BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
* @Adapter :Driver Private Data Structure
* @pBuffer : Buffer From where data has to taken for writing
* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
* @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
* @uiOffsetWithinSectionVal :- Offset with in provided section
* @uiNumBytes : Number of Bytes for Write
*
@ -2909,7 +2909,7 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
FLASH2X_SECTION_VAL eFlash2xSectVal,
enum bcm_flash2x_section_val eFlash2xSectVal,
unsigned int uiOffset,
unsigned int uiNumBytes,
unsigned int bVerify)
@ -2971,7 +2971,7 @@ int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
{
FLASH2X_SECTION_VAL uiHighestPriDSD = 0;
enum bcm_flash2x_section_val uiHighestPriDSD = 0;
uiHighestPriDSD = getHighestPriDSD(Adapter);
Adapter->eActiveDSD = uiHighestPriDSD;
@ -3064,7 +3064,7 @@ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset
return FALSE;
}
static int BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
{
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@ -3099,11 +3099,11 @@ static int BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
* Failure:- negative error code
*/
int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
{
PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
FLASH2X_SECTION_VAL uiHighestPriDSD = 0;
FLASH2X_SECTION_VAL uiHighestPriISO = 0;
enum bcm_flash2x_section_val uiHighestPriDSD = 0;
enum bcm_flash2x_section_val uiHighestPriISO = 0;
BOOLEAN SetActiveDSDDone = FALSE;
BOOLEAN SetActiveISODone = FALSE;
@ -3349,7 +3349,7 @@ int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM
*
*/
int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
{
unsigned int SectImagePriority = 0;
int Status = STATUS_SUCCESS;
@ -3529,10 +3529,10 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF
*
*/
int BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
{
PCHAR Buff = NULL;
FLASH2X_SECTION_VAL eISOReadPart = 0, eISOWritePart = 0;
enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
unsigned int uiTotalDataToCopy = 0;
BOOLEAN IsThisHeaderSector = FALSE;
@ -3813,7 +3813,7 @@ out:
* Failure :-Return negative error code
*/
int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
int Status = STATUS_SUCCESS;
@ -3841,7 +3841,7 @@ int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e
* Failure :-Return negative error code
*/
int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
{
unsigned int uiSignature = 0;
unsigned int uiOffset = 0;
@ -3901,7 +3901,7 @@ int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl
* Return values:-Return TRUE is request is valid else FALSE.
*/
int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
{
unsigned int uiNumOfBytes = 0;
unsigned int uiSectStartOffset = 0;
@ -4021,8 +4021,8 @@ static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
*/
int BcmCopySection(struct bcm_mini_adapter *Adapter,
FLASH2X_SECTION_VAL SrcSection,
FLASH2X_SECTION_VAL DstSection,
enum bcm_flash2x_section_val SrcSection,
enum bcm_flash2x_section_val DstSection,
unsigned int offset,
unsigned int numOfBytes)
{
@ -4264,7 +4264,7 @@ static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset
return STATUS_SUCCESS;
}
int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
{
unsigned int uiDSDsig = 0;
/* unsigned int sigoffsetInMap = 0;
@ -4289,7 +4289,7 @@ int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
return uiDSDsig;
}
int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
{
/* unsigned int priOffsetInMap = 0 ; */
unsigned int uiDSDPri = STATUS_FAILURE;
@ -4312,11 +4312,11 @@ int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
return uiDSDPri;
}
FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter)
enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
{
int DSDHighestPri = STATUS_FAILURE;
int DsdPri = 0;
FLASH2X_SECTION_VAL HighestPriDSD = 0;
enum bcm_flash2x_section_val HighestPriDSD = 0;
if (IsSectionWritable(Adapter, DSD2)) {
DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
@ -4344,7 +4344,7 @@ FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter)
return HighestPriDSD;
}
int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
{
unsigned int uiISOsig = 0;
/* unsigned int sigoffsetInMap = 0;
@ -4367,7 +4367,7 @@ int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
return uiISOsig;
}
int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
{
unsigned int ISOPri = STATUS_FAILURE;
if (IsSectionWritable(Adapter, iso)) {
@ -4386,11 +4386,11 @@ int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
return ISOPri;
}
FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter)
enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
{
int ISOHighestPri = STATUS_FAILURE;
int ISOPri = 0;
FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL;
enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
@ -4412,7 +4412,7 @@ FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter)
int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
PUINT pBuff,
FLASH2X_SECTION_VAL eFlash2xSectionVal,
enum bcm_flash2x_section_val eFlash2xSectionVal,
unsigned int uiOffset,
unsigned int uiNumBytes)
{
@ -4468,7 +4468,7 @@ int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
return Status;
}
BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section)
BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
{
BOOLEAN SectionPresent = FALSE;
@ -4523,7 +4523,7 @@ BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_
return SectionPresent;
}
int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section)
int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
{
int offset = STATUS_FAILURE;
int Status = FALSE;
@ -4546,7 +4546,7 @@ int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Sect
return Status;
}
static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
PUCHAR pBuff = NULL;
unsigned int sig = 0;
@ -4608,7 +4608,7 @@ static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e
return STATUS_SUCCESS;
}
static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
PUCHAR pBuff = NULL;
unsigned int sig = 0;

View File

@ -89,7 +89,7 @@ INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg)
//
//------------------------------------------------------------------
INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes)
{
return STATUS_FAILURE;
@ -114,7 +114,7 @@ INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL S
// STATUS_SUCCESS/STATUS_FAILURE
//
//------------------------------------------------------------------
INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes, BOOLEAN bVerify)
{
return STATUS_FAILURE;
@ -138,7 +138,7 @@ INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL
// STATUS_SUCCESS/STATUS_FAILURE
//
//------------------------------------------------------------------
INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes)
{
return STATUS_FAILURE;

View File

@ -8,11 +8,11 @@ INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendo
INT vendorextnExit(struct bcm_mini_adapter *Adapter);
INT vendorextnInit(struct bcm_mini_adapter *Adapter);
INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg);
INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes);
INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes, BOOLEAN bVerify);
INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
UINT offset, UINT numOfBytes);
#endif /* */

View File

@ -1239,7 +1239,7 @@ static int ccg_create_device(struct ccg_dev *dev)
}
static int __init init(void)
static int __init ccg_init(void)
{
struct ccg_dev *dev;
int err;
@ -1280,13 +1280,13 @@ static int __init init(void)
return err;
}
module_init(init);
module_init(ccg_init);
static void __exit cleanup(void)
static void __exit ccg_exit(void)
{
usb_composite_unregister(&ccg_usb_driver);
class_destroy(ccg_class);
kfree(_ccg_dev);
_ccg_dev = NULL;
}
module_exit(cleanup);
module_exit(ccg_exit);

View File

@ -341,7 +341,7 @@ bool Is1401(DEVICE_EXTENSION * pdx)
}
if (iReturn == 0) // if all is OK...
iReturn = state == 0; // then sucess is that the state is 0
iReturn = state == 0; // then success is that the state is 0
} else
iReturn = 0; // we failed
pdx->bForceReset = false; // Clear forced reset flag now
@ -565,7 +565,7 @@ int LineCount(DEVICE_EXTENSION * pdx)
if (dwIndex >= INBUF_SZ) // see if we fall off buff
dwIndex = 0;
}
while (dwIndex != dwEnd); // go to last avaliable
while (dwIndex != dwEnd); // go to last available
}
spin_unlock_irq(&pdx->charInLock);
@ -697,8 +697,7 @@ static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf,
return -EFAULT; // ...then we are done
// Now allocate space to hold the page pointer and virtual address pointer tables
pPages =
(struct page **)kmalloc(len * sizeof(struct page *), GFP_KERNEL);
pPages = kmalloc(len * sizeof(struct page *), GFP_KERNEL);
if (!pPages) {
iReturn = U14ERR_NOMEMORY;
goto error;
@ -913,18 +912,24 @@ int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX)
iReturn = U14ERR_BADAREA;
else {
// Return the best information we have - we don't have physical addresses
TGET_TX_BLOCK tx;
memset(&tx, 0, sizeof(tx)); // clean out local work structure
tx.size = pdx->rTransDef[dwIdent].dwLength;
tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return
tx.used = 1; // number we actually return
tx.entries[0].physical =
(long long)(tx.linear + pdx->StagedOffset);
tx.entries[0].size = tx.size;
TGET_TX_BLOCK *tx;
if (copy_to_user(pTX, &tx, sizeof(tx)))
tx = kzalloc(sizeof(*tx), GFP_KERNEL);
if (!tx) {
mutex_unlock(&pdx->io_mutex);
return -ENOMEM;
}
tx->size = pdx->rTransDef[dwIdent].dwLength;
tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
tx->avail = GET_TX_MAXENTRIES; // how many blocks we could return
tx->used = 1; // number we actually return
tx->entries[0].physical =
(long long)(tx->linear + pdx->StagedOffset);
tx->entries[0].size = tx->size;
if (copy_to_user(pTX, tx, sizeof(*tx)))
iReturn = -EFAULT;
kfree(tx);
}
mutex_unlock(&pdx->io_mutex);
return iReturn;
@ -1508,7 +1513,7 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
iReturn = U14ERR_BADAREA;
if (copy_to_user(pCB, &cb, sizeof(cb)))
return -EFAULT;
iReturn = -EFAULT;
mutex_unlock(&pdx->io_mutex);
return iReturn;

View File

@ -89,14 +89,11 @@ synchronous non-Urb based transfers.
#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/version.h>
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) )
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/uaccess.h>
#endif
#include "usb1401.h"
@ -123,19 +120,6 @@ MODULE_DEVICE_TABLE(usb, ced_table);
#define WRITES_IN_FLIGHT 8
/* arbitrarily chosen */
/*
The cause for these errors is that the driver makes use of the functions usb_buffer_alloc() and usb_buffer_free() which got renamed in kernel 2.6.35. This is stated in the Changelog: USB: rename usb_buffer_alloc() and usb_buffer_free() users
For more clearance what the functions actually do,
usb_buffer_alloc() is renamed to usb_alloc_coherent()
usb_buffer_free() is renamed to usb_free_coherent()
This is needed on Debian 2.6.32-5-amd64
*/
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
#define usb_alloc_coherent usb_buffer_alloc
#define usb_free_coherent usb_buffer_free
#define noop_llseek NULL
#endif
static struct usb_driver ced_driver;
static void ced_delete(struct kref *kref)
@ -927,9 +911,9 @@ static bool ReadWord(unsigned short *pWord, char *pBuf, unsigned int *pdDone,
** ReadHuff
**
** Reads a coded number in and returns it, Code is:
** If data is in range 0..127 we recieve 1 byte. If data in range 128-16383
** we recieve two bytes, top bit of first indicates another on its way. If
** data in range 16383-4194303 we get three bytes, top two bits of first set
** If data is in range 0..127 we receive 1 byte. If data in range 128-16383
** we receive two bytes, top bit of first indicates another on its way. If
** data in range 16384-4194303 we get three bytes, top two bits of first set
** to indicate three byte total.
**
*****************************************************************************/
@ -1252,12 +1236,7 @@ int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback)
** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big
** enough for a 64-bit pointer.
*****************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
#else
static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd,
unsigned long ulArg)
#endif
{
int err = 0;
DEVICE_EXTENSION *pdx = file->private_data;
@ -1388,11 +1367,7 @@ static const struct file_operations ced_fops = {
.release = ced_release,
.flush = ced_flush,
.llseek = noop_llseek,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
.unlocked_ioctl = ced_ioctl,
#else
.ioctl = ced_ioctl,
#endif
};
/*
@ -1537,7 +1512,7 @@ error:
static void ced_disconnect(struct usb_interface *interface)
{
DEVICE_EXTENSION *pdx = usb_get_intfdata(interface);
int minor = interface->minor; // save for message at the end
int minor = interface->minor;
int i;
usb_set_intfdata(interface, NULL); // remove the pdx from the interface
@ -1572,8 +1547,7 @@ void ced_draw_down(DEVICE_EXTENSION * pdx)
pdx->bInDrawDown = true;
time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000);
if (!time) // if we timed out we kill the urbs
{
if (!time) { // if we timed out we kill the urbs
usb_kill_anchored_urbs(&pdx->submitted);
dev_err(&pdx->interface->dev, "%s timed out", __func__);
}

View File

@ -165,7 +165,7 @@ typedef struct _DEVICE_EXTENSION
// Parameters relating to a block read\write that is in progress. Some of these values
// are equivalent to values in rDMAInfo. The values here are those in use, while those
// in rDMAInfo are those recieved from the 1401 via an escape sequence. If another
// in rDMAInfo are those received from the 1401 via an escape sequence. If another
// escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these
// are used to finish off the current transfer.
volatile short StagedId; // The transfer area id for this transfer

View File

@ -145,7 +145,7 @@
** You should add a new one of these to keep things tidy for applications.
**
** DRIVERET_MAX (below) specifies the maximum allowed type code from the
** 1401 driver; I have set this high to accomodate as yet undesigned 1401
** 1401 driver; I have set this high to accommodate as yet undesigned 1401
** types. Similarly, as long as the command file names follow the ARM,
** ARN, ARO sequence, these are calculated by the ExtForType function, so
** you don't need to do anything here either.
@ -160,7 +160,7 @@
** have broken backwards compatibility. Minor number changes mean that we
** have added new functionality that does not break backwards compatibility.
** we starts at 0. Revision changes mean we have fixed something. Each index
** returns to 0 when a higer one changes.
** returns to 0 when a higher one changes.
*/
#define U14LIB_MAJOR 4
#define U14LIB_MINOR 0
@ -211,7 +211,7 @@
/*
** These are the 1401 type codes returned by the driver, they are a slightly
** odd sequence & start for reasons of compatability with the DOS driver.
** odd sequence & start for reasons of compatibility with the DOS driver.
** The maximum code value is the upper limit of 1401 device types.
*/
#define DRIVRET_STD 4 // Codes for 1401 types matching driver values
@ -2327,7 +2327,7 @@ U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff,
/****************************************************************************
** U14SetTransferEvent Sets an event for notification of application
** wArea The tranfer area index, from 0 to MAXAREAS-1
** wArea The transfer area index, from 0 to MAXAREAS-1
** bEvent True to create an event, false to remove it
** bToHost Set 0 for notification on to1401 tranfers, 1 for
** notification of transfers to the host PC

Some files were not shown because too many files have changed in this diff Show More