mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
Char/Misc/IIO driver changes for 7.0-rc1
Here is the big set of char/misc/iio and other smaller driver subsystem changes for 7.0-rc1. Lots of little things in here, including: - Loads of iio driver changes and updates and additions - gpib driver updates - interconnect driver updates - i3c driver updates - hwtracing (coresight and intel) driver updates - deletion of the obsolete mwave driver - binder driver updates (rust and c versions) - mhi driver updates (causing a merge conflict, see below) - mei driver updates - fsi driver updates - eeprom driver updates - lots of other small char and misc driver updates and cleanups All of these have been in linux-next for a while, with no reported issues except for a merge conflict with your tree due to the mhi driver changes in the drivers/net/wireless/ath/ath12k/mhi.c file. To fix that up, just delete the "auto_queue" structure fields being set, see this message for the full change needed: https://lore.kernel.org/r/aXD6X23btw8s-RZP@sirena.org.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaZRxOg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykIrACgs9S+A/GG9X0Kvc+ND/J1XYZpj3QAoKl0yXGj SV1SR/giEBc7iKV6Dn6O =jbok -----END PGP SIGNATURE----- Merge tag 'char-misc-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc/IIO driver updates from Greg KH: "Here is the big set of char/misc/iio and other smaller driver subsystem changes for 7.0-rc1. Lots of little things in here, including: - Loads of iio driver changes and updates and additions - gpib driver updates - interconnect driver updates - i3c driver updates - hwtracing (coresight and intel) driver updates - deletion of the obsolete mwave driver - binder driver updates (rust and c versions) - mhi driver updates (causing a merge conflict, see below) - mei driver updates - fsi driver updates - eeprom driver updates - lots of other small char and misc driver updates and cleanups All of these have been in linux-next for a while, with no reported issues" * tag 'char-misc-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (297 commits) mux: mmio: fix regmap leak on probe failure rust_binder: return p from rust_binder_transaction_target_node() drivers: android: binder: Update ARef imports from sync::aref rust_binder: fix needless borrow in context.rs iio: magn: mmc5633: Fix Kconfig for combination of I3C as module and driver builtin iio: sca3000: Fix a resource leak in sca3000_probe() iio: proximity: rfd77402: Add interrupt handling support iio: proximity: rfd77402: Document device private data structure iio: proximity: rfd77402: Use devm-managed mutex initialization iio: proximity: rfd77402: Use kernel helper for result polling iio: proximity: rfd77402: Align polling timeout with datasheet iio: cros_ec: Allow enabling/disabling calibration mode iio: frequency: ad9523: correct kernel-doc bad line warning iio: buffer: buffer_impl.h: fix kernel-doc warnings iio: gyro: itg3200: Fix unchecked return value in read_raw MAINTAINERS: add entry for ADE9000 driver iio: accel: sca3000: remove unused last_timestamp field iio: accel: adxl372: remove unused int2_bitmask field iio: adc: ad7766: Use iio_trigger_generic_data_rdy_poll() iio: magnetometer: Remove IRQF_ONESHOT ...
This commit is contained in:
commit
505d195b0f
273 changed files with 15801 additions and 5395 deletions
|
|
@ -23,8 +23,7 @@ What: /sys/accessibility/speakup/bleep_time
|
|||
KernelVersion: 2.6
|
||||
Contact: speakup@linux-speakup.org
|
||||
Description: This controls the duration of the PC speaker beeps speakup
|
||||
produces.
|
||||
TODO: What are the units? Jiffies?
|
||||
produces, in milliseconds.
|
||||
|
||||
What: /sys/accessibility/speakup/cursor_time
|
||||
KernelVersion: 2.6
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
What: /sys/bus/coresight/devices/dummy_source<N>/enable_source
|
||||
Date: Dec 2024
|
||||
KernelVersion: 6.14
|
||||
Contact: Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
Contact: Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
Description: (RW) Enable/disable tracing of dummy source. A sink should be activated
|
||||
before enabling the source. The path of coresight components linking
|
||||
the source to the sink is configured and managed automatically by the
|
||||
|
|
@ -10,7 +10,7 @@ Description: (RW) Enable/disable tracing of dummy source. A sink should be activ
|
|||
What: /sys/bus/coresight/devices/dummy_source<N>/traceid
|
||||
Date: Dec 2024
|
||||
KernelVersion: 6.14
|
||||
Contact: Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
Contact: Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
Description: (R) Show the trace ID that will appear in the trace stream
|
||||
coming from this trace entity.
|
||||
|
||||
|
|
|
|||
69
Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
Normal file
69
Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
What: /sys/bus/coresight/devices/<tpda-name>/trig_async_enable
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Enable/disable cross trigger synchronization sequence interface.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/trig_flag_ts_enable
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Enable/disable cross trigger FLAG packet request interface.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/trig_freq_enable
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Enable/disable cross trigger FREQ packet request interface.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/freq_ts_enable
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Enable/disable the timestamp for all FREQ packets.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/cmbchan_mode
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Configure the CMB/MCMB channel mode for all enabled ports.
|
||||
Value 0 means raw channel mapping mode. Value 1 means channel pair marking mode.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/global_flush_req
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set global (all ports) flush request bit. The bit remains set until a
|
||||
global flush request sequence completes.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/syncr_mode
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set mode the of the syncr counter.
|
||||
mode 0 - COUNT[11:0] value represents the approximate number of bytes moved between two ASYNC packet requests
|
||||
mode 1 - the bits COUNT[11:7] are used as a power of 2. for example, we could insert an async packet every 8K
|
||||
data by writing a value 13 to the COUNT[11:7] field.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/syncr_count
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set value the of the syncr counter.
|
||||
Range: 0-4095
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpda-name>/port_flush_req
|
||||
Date: December 2025
|
||||
KernelVersion: 6.20
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Configure the bit i to requests a flush operation of port i on the TPDA.
|
||||
The requested bit(s) remain set until the flush request completes.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/integration_test
|
||||
Date: January 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(Write) Run integration test for tpdm. Integration test
|
||||
will generate test data for tpdm. It can help to make
|
||||
|
|
@ -15,7 +15,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/reset_dataset
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(Write) Reset the dataset of the tpdm.
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_trig_type
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the trigger type of the DSB for tpdm.
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_trig_ts
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the trigger timestamp of the DSB for tpdm.
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_mode
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the programming mode of the DSB for tpdm.
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/ctrl_idx
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the index number of the edge detection for the DSB
|
||||
subunit TPDM. Since there are at most 256 edge detections, this
|
||||
|
|
@ -70,7 +70,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/ctrl_val
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
Write a data to control the edge detection corresponding to
|
||||
the index number. Before writing data to this sysfs file,
|
||||
|
|
@ -86,7 +86,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/ctrl_mask
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
Write a data to mask the edge detection corresponding to the index
|
||||
number. Before writing data to this sysfs file, "ctrl_idx" should
|
||||
|
|
@ -98,21 +98,21 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/edcr[0:15]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
Read a set of the edge control value of the DSB in TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/edcmr[0:7]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
Read a set of the edge control mask of the DSB in TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_trig_patt/xpr[0:7]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the value of the trigger pattern for the DSB
|
||||
subunit TPDM.
|
||||
|
|
@ -120,7 +120,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_trig_patt/xpmr[0:7]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the mask of the trigger pattern for the DSB
|
||||
subunit TPDM.
|
||||
|
|
@ -128,21 +128,21 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:7]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the value of the pattern for the DSB subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:7]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the mask of the pattern for the DSB subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/enable_ts
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(Write) Set the pattern timestamp of DSB tpdm. Read
|
||||
the pattern timestamp of DSB tpdm.
|
||||
|
|
@ -154,7 +154,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/set_type
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(Write) Set the pattern type of DSB tpdm. Read
|
||||
the pattern type of DSB tpdm.
|
||||
|
|
@ -166,7 +166,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_msr/msr[0:31]
|
||||
Date: March 2023
|
||||
KernelVersion: 6.7
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the MSR(mux select register) for the DSB subunit
|
||||
TPDM.
|
||||
|
|
@ -174,7 +174,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_mode
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description: (Write) Set the data collection mode of CMB tpdm. Continuous
|
||||
change creates CMB data set elements on every CMBCLK edge.
|
||||
Trace-on-change creates CMB data set elements only when a new
|
||||
|
|
@ -188,7 +188,7 @@ Description: (Write) Set the data collection mode of CMB tpdm. Continuous
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpr[0:1]
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the value of the trigger pattern for the CMB
|
||||
subunit TPDM.
|
||||
|
|
@ -196,7 +196,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpmr[0:1]
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the mask of the trigger pattern for the CMB
|
||||
subunit TPDM.
|
||||
|
|
@ -204,21 +204,21 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:1]
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the value of the pattern for the CMB subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:1]
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(Write) Set the pattern timestamp of CMB tpdm. Read
|
||||
the pattern timestamp of CMB tpdm.
|
||||
|
|
@ -230,7 +230,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the trigger timestamp of the CMB for tpdm.
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Read or write the status of timestamp upon all interface.
|
||||
Only value 0 and 1 can be written to this node. Set this node to 1 to request
|
||||
|
|
@ -253,7 +253,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
|
||||
Date: January 2024
|
||||
KernelVersion: 6.9
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the MSR(mux select register) for the CMB subunit
|
||||
TPDM.
|
||||
|
|
@ -261,7 +261,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/mcmb_trig_lane
|
||||
Date: Feb 2025
|
||||
KernelVersion 6.15
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get which lane participates in the output pattern
|
||||
match cross trigger mechanism for the MCMB subunit TPDM.
|
||||
|
|
@ -269,7 +269,7 @@ Description:
|
|||
What: /sys/bus/coresight/devices/<tpdm-name>/mcmb_lanes_select
|
||||
Date: Feb 2025
|
||||
KernelVersion 6.15
|
||||
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
|
||||
Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
Description:
|
||||
(RW) Set/Get the enablement of the individual lane.
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ Date: July 2015
|
|||
KernelVersion: 4.7
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Writing '1' will perform a FOC (Fast Online Calibration). The
|
||||
corresponding calibration offsets can be read from `*_calibbias`
|
||||
entries.
|
||||
Writing '1' either perform a FOC (Fast Online Calibration) or
|
||||
enter calibration mode.
|
||||
Writing '0` exits calibration mode. It is a NOP for FOC enabled
|
||||
sensors.
|
||||
The corresponding calibration offsets can be read from `*_calibbias`
|
||||
entries.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/id
|
||||
Date: September 2017
|
||||
|
|
|
|||
|
|
@ -17,3 +17,14 @@ Description:
|
|||
from the device.
|
||||
|
||||
This is a read-only attribute.
|
||||
|
||||
What: /sys/class/spi_master/spi<bus>/spi<bus>.<dev>/jedec_id
|
||||
Date: January 2026
|
||||
KernelVersion: 6.19
|
||||
Contact: Patrick Wicki <patrick.wicki@siemens.com>
|
||||
Description:
|
||||
Contains the raw JEDEC ID bytes returned by the RDID (0x9f) command. The
|
||||
bytes are exposed as a hex string in big-endian order as read from the
|
||||
device.
|
||||
|
||||
This is a read-only attribute.
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@
|
|||
216 = /dev/fujitsu/apanel Fujitsu/Siemens application panel
|
||||
217 = /dev/ni/natmotn National Instruments Motion
|
||||
218 = /dev/kchuid Inter-process chuid control
|
||||
219 = /dev/modems/mwave MWave modem firmware upload
|
||||
219 =
|
||||
220 = /dev/mptctl Message passing technology (MPT) control
|
||||
221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver
|
||||
222 = /dev/mvista/hasi Montavista PICMG high availability
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ maintainers:
|
|||
- Mike Leach <mike.leach@linaro.org>
|
||||
- Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
- James Clark <james.clark@linaro.org>
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
- Hao Zhang <quic_hazha@quicinc.com>
|
||||
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ maintainers:
|
|||
- Mike Leach <mike.leach@linaro.org>
|
||||
- Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
- James Clark <james.clark@linaro.org>
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
- Hao Zhang <quic_hazha@quicinc.com>
|
||||
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: CoreSight TMC Control Unit
|
||||
|
||||
maintainers:
|
||||
- Yuanfang Zhang <quic_yuanfang@quicinc.com>
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Jie Gan <quic_jiegan@quicinc.com>
|
||||
- Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com>
|
||||
- Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
- Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
The Trace Memory Controller(TMC) is used for Embedded Trace Buffer(ETB),
|
||||
|
|
@ -26,8 +26,13 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sa8775p-ctcu
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs8300-ctcu
|
||||
- const: qcom,sa8775p-ctcu
|
||||
- enum:
|
||||
- qcom,sa8775p-ctcu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/arm/qcom,coresight-itnoc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Interconnect Trace Network On Chip - ITNOC
|
||||
|
||||
maintainers:
|
||||
- Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
The Interconnect TNOC is a CoreSight graph link that forwards trace data
|
||||
from a subsystem to the Aggregator TNOC. Compared to Aggregator TNOC, it
|
||||
does not have aggregation and ATID functionality.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^itnoc(@[0-9a-f]+)?$"
|
||||
|
||||
compatible:
|
||||
const: qcom,coresight-itnoc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: apb
|
||||
|
||||
in-ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
patternProperties:
|
||||
'^port(@[0-9a-f]{1,2})?$':
|
||||
description: Input connections from CoreSight Trace Bus
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
out-ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
port:
|
||||
description: out connections to aggregator TNOC
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- in-ports
|
||||
- out-ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
itnoc@109ac000 {
|
||||
compatible = "qcom,coresight-itnoc";
|
||||
reg = <0x109ac000 0x1000>;
|
||||
|
||||
clocks = <&aoss_qmp>;
|
||||
clock-names = "apb";
|
||||
|
||||
in-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
tn_ic_in_tpdm_dcc: endpoint {
|
||||
remote-endpoint = <&tpdm_dcc_out_tn_ic>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
out-ports {
|
||||
port {
|
||||
tn_ic_out_tnoc_aggr: endpoint {
|
||||
/* to Aggregator TNOC input */
|
||||
remote-endpoint = <&tn_ag_in_tn_ic>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Qualcomm Coresight Remote ETM(Embedded Trace Macrocell)
|
||||
|
||||
maintainers:
|
||||
- Jinlong Mao <quic_jinlmao@quicinc.com>
|
||||
- Tao Zhang <quic_taozha@quicinc.com>
|
||||
- Jinlong Mao <jinlong.mao@oss.qualcomm.com>
|
||||
- Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
Support for ETM trace collection on remote processor using coresight
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Qualcomm Trace Network On Chip - TNOC
|
||||
|
||||
maintainers:
|
||||
- Yuanfang Zhang <quic_yuanfang@quicinc.com>
|
||||
- Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com>
|
||||
|
||||
description: >
|
||||
The Trace Network On Chip (TNOC) is an integration hierarchy hardware
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ description: |
|
|||
to sink.
|
||||
|
||||
maintainers:
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Tao Zhang <quic_taozha@quicinc.com>
|
||||
- Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
- Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
|
||||
# Need a custom select here or 'arm,primecell' will match on lots of nodes
|
||||
select:
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ description: |
|
|||
sources and send it to a TPDA for packetization, timestamping, and funneling.
|
||||
|
||||
maintainers:
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Tao Zhang <quic_taozha@quicinc.com>
|
||||
- Mao Jinlong <jinlong.mao@oss.qualcomm.com>
|
||||
- Tao Zhang <tao.zhang@oss.qualcomm.com>
|
||||
|
||||
# Need a custom select here or 'arm,primecell' will match on lots of nodes
|
||||
select:
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
Android Goldfish QEMU Pipe
|
||||
|
||||
Android pipe virtual device generated by android emulator.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should contain "google,android-pipe" to match emulator
|
||||
- reg : <registers mapping>
|
||||
- interrupts : <interrupt mapping>
|
||||
|
||||
Example:
|
||||
|
||||
android_pipe@a010000 {
|
||||
compatible = "google,android-pipe";
|
||||
reg = <ff018000 0x2000>;
|
||||
interrupts = <0x12>;
|
||||
};
|
||||
120
Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml
Normal file
120
Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright 2025 Analog Devices Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/adi,ad4062.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD4062 ADC family device driver
|
||||
|
||||
maintainers:
|
||||
- Jorge Marques <jorge.marques@analog.com>
|
||||
|
||||
description: |
|
||||
Analog Devices AD4062 Single Channel Precision SAR ADC family
|
||||
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4060.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4062.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad4060
|
||||
- adi,ad4062
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
Two pins are available that can be configured as either a general purpose
|
||||
digital output, device enable signal (used to synchronise other parts of
|
||||
the signal chain with ADC sampling), device ready (GP1 only) or various
|
||||
interrupt signals. If intended for use as a GPIO or device enable, will not
|
||||
present here.
|
||||
minItems: 1
|
||||
items:
|
||||
- description:
|
||||
GP0 pin, cannot be configured as DEV_RDY.
|
||||
- description:
|
||||
GP1 pin, can be configured to any setting.
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: gp0
|
||||
- const: gp1
|
||||
|
||||
gpio-controller:
|
||||
description:
|
||||
Marks the device node as a GPIO controller. GPs not listed as interrupts
|
||||
are exposed as a GPO.
|
||||
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
description:
|
||||
The first cell is the GPIO number and the second cell specifies
|
||||
GPIO flags, as defined in <dt-bindings/gpio/gpio.h>.
|
||||
|
||||
vdd-supply:
|
||||
description: Analog power supply.
|
||||
|
||||
vio-supply:
|
||||
description: Digital interface logic power supply.
|
||||
|
||||
ref-supply:
|
||||
description:
|
||||
Reference voltage to set the ADC full-scale range. If not present,
|
||||
vdd-supply is used as the reference voltage.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- vio-supply
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i3c/i3c.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i3c {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0,2ee007c0000 {
|
||||
reg = <0x0 0x2ee 0x7c0000>;
|
||||
vdd-supply = <&vdd>;
|
||||
vio-supply = <&vio>;
|
||||
ref-supply = <&ref>;
|
||||
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <0 0 IRQ_TYPE_EDGE_RISING>,
|
||||
<0 1 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-names = "gp0", "gp1";
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i3c {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0,2ee007c0000 {
|
||||
reg = <0x0 0x2ee 0x7c0000>;
|
||||
vdd-supply = <&vdd>;
|
||||
vio-supply = <&vio>;
|
||||
ref-supply = <&ref>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
191
Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml
Normal file
191
Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/adi,ad4134.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD4134 ADC
|
||||
|
||||
maintainers:
|
||||
- Marcelo Schmitt <marcelo.schmitt@analog.com>
|
||||
|
||||
description: |
|
||||
The AD4134 is a quad channel, low noise, simultaneous sampling, precision
|
||||
analog-to-digital converter (ADC).
|
||||
Specifications can be found at:
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4134.pdf
|
||||
|
||||
$ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad4134
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 50000000
|
||||
|
||||
avdd5-supply:
|
||||
description: A 5V supply that powers the chip's analog circuitry.
|
||||
|
||||
dvdd5-supply:
|
||||
description: A 5V supply that powers the chip's digital circuitry.
|
||||
|
||||
iovdd-supply:
|
||||
description:
|
||||
A 1.8V supply that sets the logic levels for the digital interface pins.
|
||||
|
||||
refin-supply:
|
||||
description:
|
||||
A 4.096V or 5V supply that serves as reference for ADC conversions.
|
||||
|
||||
avdd1v8-supply:
|
||||
description: A 1.8V supply used by the analog circuitry.
|
||||
|
||||
dvdd1v8-supply:
|
||||
description: A 1.8V supply used by the digital circuitry.
|
||||
|
||||
clkvdd-supply:
|
||||
description: A 1.8V supply for the chip's clock management circuit.
|
||||
|
||||
ldoin-supply:
|
||||
description:
|
||||
A 2.6V to 5.5V supply that generates 1.8V for AVDD1V8, DVDD1V8, and CLKVDD
|
||||
pins.
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description:
|
||||
Required external clock source. Can specify either a crystal or CMOS clock
|
||||
source. If an external crystal is set, connect the CLKSEL pin to IOVDD.
|
||||
Otherwise, connect the CLKSEL pin to IOGND and the external CMOS clock
|
||||
signal to the XTAL2/CLKIN pin.
|
||||
|
||||
clock-names:
|
||||
enum:
|
||||
- xtal
|
||||
- clkin
|
||||
default: clkin
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
description:
|
||||
list of regulators provided by this controller.
|
||||
|
||||
properties:
|
||||
vcm-output:
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
powerdown-gpios:
|
||||
description:
|
||||
Active low GPIO connected to the /PDN pin. Forces the device into full
|
||||
power-down mode when brought low. Pull this input to IOVDD for normal
|
||||
operation.
|
||||
maxItems: 1
|
||||
|
||||
odr-gpios:
|
||||
description:
|
||||
GPIO connected to ODR pin. Used to sample ADC data in minimum I/O mode.
|
||||
maxItems: 1
|
||||
|
||||
adi,asrc-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Asynchronous Sample Rate Converter (ASRC) operation mode control input.
|
||||
Describes whether the MODE pin is set to a high level (for master mode
|
||||
operation) or to a low level (for slave mode operation).
|
||||
enum: [ high, low ]
|
||||
default: low
|
||||
|
||||
adi,dclkio:
|
||||
description:
|
||||
DCLK pin I/O direction control for when the device operates in Pin Control
|
||||
Slave Mode or in SPI Control Mode. Describes if DEC0/DCLKIO pin is at a
|
||||
high level (which configures DCLK as an output) or to set to a low level
|
||||
(configuring DCLK for input).
|
||||
enum: [ out, in ]
|
||||
default: in
|
||||
|
||||
adi,dclkmode:
|
||||
description:
|
||||
DCLK mode control for when the device operates in Pin Control Slave Mode
|
||||
or in SPI Control Mode. Describes whether the DEC1/DCLKMODE pin is set to
|
||||
a high level (configuring the DCLK to operate in free running mode) or
|
||||
to a low level (to configure DCLK to operate in gated mode).
|
||||
enum: [ free-running, gated ]
|
||||
default: gated
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- avdd5-supply
|
||||
- dvdd5-supply
|
||||
- iovdd-supply
|
||||
- refin-supply
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- ldoin-supply
|
||||
- required:
|
||||
- avdd1v8-supply
|
||||
- dvdd1v8-supply
|
||||
- clkvdd-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "adi,ad4134";
|
||||
reg = <0>;
|
||||
|
||||
spi-max-frequency = <1000000>;
|
||||
|
||||
reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>;
|
||||
odr-gpios = <&gpio0 87 GPIO_ACTIVE_HIGH>;
|
||||
powerdown-gpios = <&gpio0 88 GPIO_ACTIVE_LOW>;
|
||||
|
||||
clocks = <&sys_clk>;
|
||||
clock-names = "clkin";
|
||||
|
||||
avdd5-supply = <&avdd5>;
|
||||
dvdd5-supply = <&dvdd5>;
|
||||
iovdd-supply = <&iovdd>;
|
||||
refin-supply = <&refin>;
|
||||
avdd1v8-supply = <&avdd1v8>;
|
||||
dvdd1v8-supply = <&dvdd1v8>;
|
||||
clkvdd-supply = <&clkvdd>;
|
||||
|
||||
regulators {
|
||||
vcm_reg: vcm-output {
|
||||
regulator-name = "ad4134-vcm";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -4,18 +4,26 @@
|
|||
$id: http://devicetree.org/schemas/iio/adc/adi,ad7768-1.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD7768-1 ADC device driver
|
||||
title: Analog Devices AD7768-1 ADC family
|
||||
|
||||
maintainers:
|
||||
- Michael Hennerich <michael.hennerich@analog.com>
|
||||
|
||||
description: |
|
||||
Datasheet at:
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf
|
||||
Analog Devices AD7768-1 24-Bit Single Channel Low Power sigma-delta ADC family
|
||||
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/adaq7767-1.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/adaq7768-1.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/adaq7769-1.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adi,ad7768-1
|
||||
enum:
|
||||
- adi,ad7768-1
|
||||
- adi,adaq7767-1
|
||||
- adi,adaq7768-1
|
||||
- adi,adaq7769-1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
@ -58,6 +66,25 @@ properties:
|
|||
description:
|
||||
ADC reference voltage supply
|
||||
|
||||
adi,aaf-gain-bp:
|
||||
description: |
|
||||
Specifies the gain applied by the Analog Anti-Aliasing Filter (AAF)
|
||||
to the ADC input in basis points (one hundredth of a percent).
|
||||
The hardware gain is determined by which input pin(s) the signal goes
|
||||
through into the AAF. The possible connections are:
|
||||
* For the ADAQ7767-1: Input connected to IN1±, IN2± or IN3±.
|
||||
* For the ADAQ7769-1: OUT_PGA pin connected to IN1_AAF+, IN2_AAF+,
|
||||
or IN3_AAF+.
|
||||
enum: [1430, 3640, 10000]
|
||||
default: 10000
|
||||
|
||||
pga-gpios:
|
||||
description:
|
||||
GAIN 0, GAIN1 and GAIN2 pins for gain selection. For devices that have
|
||||
PGA configuration input pins, pga-gpios must be defined.
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
adi,sync-in-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
|
|
@ -147,6 +174,35 @@ patternProperties:
|
|||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
# AAF Gain property only applies to ADAQ7767-1 and ADAQ7769-1 devices
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- adi,adaq7767-1
|
||||
- adi,adaq7769-1
|
||||
then:
|
||||
required:
|
||||
- adi,aaf-gain-bp
|
||||
else:
|
||||
properties:
|
||||
adi,aaf-gain-bp: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- adi,adaq7768-1
|
||||
- adi,adaq7769-1
|
||||
then:
|
||||
required:
|
||||
- pga-gpios
|
||||
else:
|
||||
properties:
|
||||
pga-gpios: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ description: |
|
|||
All the parts support the register map described by Application Note AN-877
|
||||
https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf
|
||||
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD9211.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD9265.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD9434.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD9467.pdf
|
||||
|
|
@ -25,6 +26,7 @@ description: |
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad9211
|
||||
- adi,ad9265
|
||||
- adi,ad9434
|
||||
- adi,ad9467
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ properties:
|
|||
Input clock used to derive the sample clock. Expected to be the
|
||||
SoC's APB clock.
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/nxp,s32g2-sar-adc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP Successive Approximation ADC
|
||||
|
||||
description:
|
||||
The NXP SAR ADC provides fast and accurate analog-to-digital
|
||||
conversion using the Successive Approximation Register (SAR) method.
|
||||
It has 12-bit resolution with 8 input channels. Conversions can be
|
||||
launched in software or using hardware triggers. It supports
|
||||
continuous and one-shot modes with separate registers.
|
||||
|
||||
maintainers:
|
||||
- Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nxp,s32g2-sar-adc
|
||||
- items:
|
||||
- const: nxp,s32g3-sar-adc
|
||||
- const: nxp,s32g2-sar-adc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
dmas:
|
||||
maxItems: 1
|
||||
|
||||
dma-names:
|
||||
const: rx
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- dmas
|
||||
- dma-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
adc@401f8000 {
|
||||
compatible = "nxp,s32g2-sar-adc";
|
||||
reg = <0x401f8000 0x1000>;
|
||||
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks 0x41>;
|
||||
dmas = <&edma0 0 32>;
|
||||
dma-names = "rx";
|
||||
};
|
||||
82
Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml
Normal file
82
Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/ti,ads1018.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI ADS1018/ADS1118 SPI analog to digital converter
|
||||
|
||||
maintainers:
|
||||
- Kurt Borja <kuurtb@gmail.com>
|
||||
|
||||
description: |
|
||||
The ADS1018/ADS1118 is a precision, low-power, 12-bit/16-bit, analog to
|
||||
digital converter (ADC). It integrates a programmable gain amplifier (PGA),
|
||||
internal voltage reference, oscillator and high-accuracy temperature sensor.
|
||||
|
||||
Datasheets:
|
||||
- ADS1018: https://www.ti.com/lit/ds/symlink/ads1018.pdf
|
||||
- ADS1118: https://www.ti.com/lit/ds/symlink/ads1118.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,ads1018
|
||||
- ti,ads1118
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply: true
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 4000000
|
||||
|
||||
spi-cpha: true
|
||||
|
||||
interrupts:
|
||||
description: DOUT/DRDY (Data Out/Data Ready) line.
|
||||
maxItems: 1
|
||||
|
||||
drdy-gpios:
|
||||
description:
|
||||
Extra GPIO line connected to DOUT/DRDY (Data Out/Data Ready). This allows
|
||||
distinguishing between interrupts triggered by the data-ready signal and
|
||||
interrupts triggered by an SPI transfer.
|
||||
maxItems: 1
|
||||
|
||||
'#io-channel-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "ti,ads1118";
|
||||
reg = <0>;
|
||||
|
||||
spi-max-frequency = <4000000>;
|
||||
spi-cpha;
|
||||
|
||||
vdd-supply = <&vdd_3v3_reg>;
|
||||
|
||||
interrupts-extended = <&gpio 14 IRQ_TYPE_EDGE_FALLING>;
|
||||
drdy-gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
208
Documentation/devicetree/bindings/iio/adc/ti,ads131m02.yaml
Normal file
208
Documentation/devicetree/bindings/iio/adc/ti,ads131m02.yaml
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/ti,ads131m02.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments ADS131M0x 2-, 3-, 4-, 6- and 8-Channel ADCs
|
||||
|
||||
maintainers:
|
||||
- Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
|
||||
description: |
|
||||
The ADS131M0x are a family of multichannel, simultaneous sampling,
|
||||
24-bit, delta-sigma, analog-to-digital converters (ADCs) with a
|
||||
built-in programmable gain amplifier (PGA) and internal reference.
|
||||
Communication with the ADC chip is via SPI.
|
||||
|
||||
Datasheets:
|
||||
- ADS131M02: https://www.ti.com/lit/ds/symlink/ads131m02.pdf
|
||||
- ADS131M03: https://www.ti.com/lit/ds/symlink/ads131m03.pdf
|
||||
- ADS131M04: https://www.ti.com/lit/ds/symlink/ads131m04.pdf
|
||||
- ADS131M06: https://www.ti.com/lit/ds/symlink/ads131m06.pdf
|
||||
- ADS131M08: https://www.ti.com/lit/ds/symlink/ads131m08.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,ads131m02
|
||||
- ti,ads131m03
|
||||
- ti,ads131m04
|
||||
- ti,ads131m06
|
||||
- ti,ads131m08
|
||||
|
||||
reg:
|
||||
description: SPI chip select number.
|
||||
|
||||
clocks:
|
||||
description:
|
||||
Phandle to the external clock source required by the ADC's CLKIN pin.
|
||||
The datasheet recommends specific frequencies based on the desired power
|
||||
mode (e.g., 8.192 MHz for High-Resolution mode).
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description: Analog power supply (AVDD).
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital power supply (DVDD).
|
||||
|
||||
interrupts:
|
||||
description: DRDY (Data Ready) output signal.
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
description: Optional RESET signal.
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
description:
|
||||
Indicates if a crystal oscillator (XTAL) or CMOS signal is connected
|
||||
(CLKIN). Note that XTAL mode is only supported on ADS131M06 and ADS131M08.
|
||||
enum: [xtal, clkin]
|
||||
|
||||
refin-supply:
|
||||
description: Optional external reference supply (REFIN).
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-7]$":
|
||||
type: object
|
||||
$ref: /schemas/iio/adc/adc.yaml#
|
||||
description: Properties for a single ADC channel.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: The channel index (0-7).
|
||||
minimum: 0
|
||||
maximum: 7 # Max channels on ADS131M08
|
||||
|
||||
label: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
- if:
|
||||
# 20-pin devices: M02, M03, M04
|
||||
# These do not support XTAL or REFIN.
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,ads131m02
|
||||
- ti,ads131m03
|
||||
- ti,ads131m04
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
const: clkin
|
||||
refin-supply: false
|
||||
|
||||
- if:
|
||||
# ADS131M02: 2 channels max (0-1)
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,ads131m02
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel@[0-1]$":
|
||||
properties:
|
||||
reg:
|
||||
maximum: 1
|
||||
"^channel@[2-7]$": false
|
||||
|
||||
- if:
|
||||
# ADS131M03: 3 channels max (0-2)
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,ads131m03
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel@[0-2]$":
|
||||
properties:
|
||||
reg:
|
||||
maximum: 2
|
||||
"^channel@[3-7]$": false
|
||||
|
||||
- if:
|
||||
# ADS131M04: 4 channels max (0-3)
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,ads131m04
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel@[0-3]$":
|
||||
properties:
|
||||
reg:
|
||||
maximum: 3
|
||||
"^channel@[4-7]$": false
|
||||
|
||||
- if:
|
||||
# ADS131M06: 6 channels max (0-5)
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,ads131m06
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel@[0-5]$":
|
||||
properties:
|
||||
reg:
|
||||
maximum: 5
|
||||
"^channel@[6-7]$": false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
|
||||
spi1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "ti,ads131m02";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8000000>;
|
||||
|
||||
clocks = <&rcc CK_MCO2>;
|
||||
clock-names = "clkin";
|
||||
|
||||
avdd-supply = <&vdd_ana>;
|
||||
dvdd-supply = <&vdd_dig>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
label = "input_voltage";
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
reg = <1>;
|
||||
label = "input_current";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/amplifiers/adi,adl8113.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADL8113 Low Noise Amplifier with integrated bypass switches
|
||||
|
||||
maintainers:
|
||||
- Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
|
||||
description: |
|
||||
The ADL8113 is a 10MHz to 12GHz Low Noise Amplifier with integrated bypass
|
||||
switches controlled by two GPIO pins (VA and VB). The device supports four
|
||||
operation modes:
|
||||
- Internal Amplifier: VA=0, VB=0 - Signal passes through the internal LNA
|
||||
- Internal Bypass: VA=1, VB=1 - Signal bypasses through internal path
|
||||
- External Bypass A: VA=0, VB=1 - Signal routes from RFIN to OUT_A and from IN_A to RFOUT
|
||||
- External Bypass B: VA=1, VB=0 - Signal routes from RFIN to OUT_B and from IN_B to RFOUT
|
||||
|
||||
https://www.analog.com/en/products/adl8113.html
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adi,adl8113
|
||||
|
||||
vdd1-supply: true
|
||||
|
||||
vdd2-supply: true
|
||||
|
||||
vss2-supply: true
|
||||
|
||||
ctrl-gpios:
|
||||
items:
|
||||
- description: VA control pin
|
||||
- description: VB control pin
|
||||
|
||||
adi,external-bypass-a-gain-db:
|
||||
description:
|
||||
Gain in dB of external amplifier connected to bypass path A (OUT_A/IN_A).
|
||||
When specified, this gain value becomes selectable via the hardwaregain
|
||||
attribute and automatically routes through the external A path.
|
||||
|
||||
adi,external-bypass-b-gain-db:
|
||||
description:
|
||||
Gain in dB of external amplifier connected to bypass path B (OUT_B/IN_B).
|
||||
When specified, this gain value becomes selectable via the hardwaregain
|
||||
attribute and automatically routes through the external B path.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ctrl-gpios
|
||||
- vdd1-supply
|
||||
- vdd2-supply
|
||||
- vss2-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/* Basic configuration with only internal paths */
|
||||
amplifier {
|
||||
compatible = "adi,adl8113";
|
||||
ctrl-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>,
|
||||
<&gpio 23 GPIO_ACTIVE_HIGH>;
|
||||
vdd1-supply = <&vdd1_5v>;
|
||||
vdd2-supply = <&vdd2_3v3>;
|
||||
vss2-supply = <&vss2_neg>;
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/* Configuration with external bypass amplifiers */
|
||||
amplifier {
|
||||
compatible = "adi,adl8113";
|
||||
ctrl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>,
|
||||
<&gpio 25 GPIO_ACTIVE_HIGH>;
|
||||
vdd1-supply = <&vdd1_5v>;
|
||||
vdd2-supply = <&vdd2_3v3>;
|
||||
vss2-supply = <&vss2_neg>;
|
||||
adi,external-bypass-a-gain-db = <20>; /* 20dB external amp on path A */
|
||||
adi,external-bypass-b-gain-db = <6>; /* 6dB external amp on path B */
|
||||
};
|
||||
...
|
||||
120
Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml
Normal file
120
Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/dac/adi,max22007.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices MAX22007 DAC
|
||||
|
||||
maintainers:
|
||||
- Janani Sunil <janani.sunil@analog.com>
|
||||
|
||||
description:
|
||||
The MAX22007 is a quad-channel, 12-bit digital-to-analog converter (DAC)
|
||||
with integrated precision output amplifiers and current output capability.
|
||||
Each channel can be independently configured for voltage or current output.
|
||||
Datasheet available at https://www.analog.com/en/products/max22007.html
|
||||
|
||||
$ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adi,max22007
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 500000
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
vdd-supply:
|
||||
description: Low-Voltage Power Supply from +2.7V to +5.5V.
|
||||
|
||||
hvdd-supply:
|
||||
description:
|
||||
Positive High-Voltage Power Supply from +8V to (HVSS +24V) for
|
||||
the Output Channels.
|
||||
|
||||
hvss-supply:
|
||||
description:
|
||||
Optional Negative High-Voltage Power Supply from -2V to 0V for the Output
|
||||
Channels. For most applications HVSS can be connected to GND (0V), but for
|
||||
applications requiring output down to true 0V or 0mA, connect to a -2V supply.
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Active low GPIO.
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-3]$":
|
||||
$ref: /schemas/iio/dac/dac.yaml#
|
||||
type: object
|
||||
description:
|
||||
Represents the external channels which are connected to the DAC.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: Channel number
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
|
||||
adi,ch-func:
|
||||
description:
|
||||
Channel output type. Use CH_FUNC_VOLTAGE_OUTPUT for voltage
|
||||
output or CH_FUNC_CURRENT_OUTPUT for current output.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [1, 2]
|
||||
|
||||
required:
|
||||
- reg
|
||||
- adi,ch-func
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- hvdd-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/iio/addac/adi,ad74413r.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dac@0 {
|
||||
compatible = "adi,max22007";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <500000>;
|
||||
reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>;
|
||||
vdd-supply = <&vdd_reg>;
|
||||
hvdd-supply = <&hvdd_reg>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
adi,ch-func = <CH_FUNC_VOLTAGE_OUTPUT>;
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
reg = <1>;
|
||||
adi,ch-func = <CH_FUNC_CURRENT_OUTPUT>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/dac/microchip,mcp47feb02.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip MCP47F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C Interface Families
|
||||
|
||||
maintainers:
|
||||
- Ariana Lazar <ariana.lazar@microchip.com>
|
||||
|
||||
description: |
|
||||
Datasheet for MCP47FEB01, MCP47FEB11, MCP47FEB21, MCP47FEB02, MCP47FEB12,
|
||||
MCP47FEB22 can be found here:
|
||||
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf
|
||||
Datasheet for MCP47FVB01, MCP47FVB11, MCP47FVB21, MCP47FVB02, MCP47FVB12,
|
||||
MCP47FVB22 can be found here:
|
||||
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf
|
||||
Datasheet for MCP47FEB04, MCP47FEB14, MCP47FEB24, MCP47FEB08, MCP47FEB18,
|
||||
MCP47FEB28, MCP47FVB04, MCP47FVB14, MCP47FVB24, MCP47FVB08, MCP47FVB18,
|
||||
MCP47FVB28 can be found here:
|
||||
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf
|
||||
|
||||
+------------+--------------+-------------+-------------+------------+
|
||||
| Device | Resolution | Channels | Vref number | Memory |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FEB01 | 8-bit | 1 | 1 | EEPROM |
|
||||
| MCP47FEB11 | 10-bit | 1 | 1 | EEPROM |
|
||||
| MCP47FEB21 | 12-bit | 1 | 1 | EEPROM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FEB02 | 8-bit | 2 | 1 | EEPROM |
|
||||
| MCP47FEB12 | 10-bit | 2 | 1 | EEPROM |
|
||||
| MCP47FEB22 | 12-bit | 2 | 1 | EEPROM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FVB01 | 8-bit | 1 | 1 | RAM |
|
||||
| MCP47FVB11 | 10-bit | 1 | 1 | RAM |
|
||||
| MCP47FVB21 | 12-bit | 1 | 1 | RAM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FVB02 | 8-bit | 2 | 1 | RAM |
|
||||
| MCP47FVB12 | 10-bit | 2 | 1 | RAM |
|
||||
| MCP47FVB22 | 12-bit | 2 | 1 | RAM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FVB04 | 8-bit | 4 | 2 | RAM |
|
||||
| MCP47FVB14 | 10-bit | 4 | 2 | RAM |
|
||||
| MCP47FVB24 | 12-bit | 4 | 2 | RAM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FVB08 | 8-bit | 8 | 2 | RAM |
|
||||
| MCP47FVB18 | 10-bit | 8 | 2 | RAM |
|
||||
| MCP47FVB28 | 12-bit | 8 | 2 | RAM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FEB04 | 8-bit | 4 | 2 | EEPROM |
|
||||
| MCP47FEB14 | 10-bit | 4 | 2 | EEPROM |
|
||||
| MCP47FEB24 | 12-bit | 4 | 2 | EEPROM |
|
||||
|------------|--------------|-------------|-------------|------------|
|
||||
| MCP47FEB08 | 8-bit | 8 | 2 | EEPROM |
|
||||
| MCP47FEB18 | 10-bit | 8 | 2 | EEPROM |
|
||||
| MCP47FEB28 | 12-bit | 8 | 2 | EEPROM |
|
||||
+------------+--------------+-------------+-------------+------------+
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- microchip,mcp47feb01
|
||||
- microchip,mcp47feb11
|
||||
- microchip,mcp47feb21
|
||||
- microchip,mcp47feb02
|
||||
- microchip,mcp47feb12
|
||||
- microchip,mcp47feb22
|
||||
- microchip,mcp47fvb01
|
||||
- microchip,mcp47fvb11
|
||||
- microchip,mcp47fvb21
|
||||
- microchip,mcp47fvb02
|
||||
- microchip,mcp47fvb12
|
||||
- microchip,mcp47fvb22
|
||||
- microchip,mcp47fvb04
|
||||
- microchip,mcp47fvb14
|
||||
- microchip,mcp47fvb24
|
||||
- microchip,mcp47fvb08
|
||||
- microchip,mcp47fvb18
|
||||
- microchip,mcp47fvb28
|
||||
- microchip,mcp47feb04
|
||||
- microchip,mcp47feb14
|
||||
- microchip,mcp47feb24
|
||||
- microchip,mcp47feb08
|
||||
- microchip,mcp47feb18
|
||||
- microchip,mcp47feb28
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
vdd-supply:
|
||||
description:
|
||||
Provides power to the chip and it could be used as reference voltage. The
|
||||
voltage is used to calculate scale. For parts without EEPROM at powerup
|
||||
this will be the selected as voltage reference.
|
||||
|
||||
vref-supply:
|
||||
description: |
|
||||
Vref pin (it could be found as Vref0 into the datasheet) may be used as a
|
||||
voltage reference when this supply is specified. The internal reference
|
||||
will be taken into account for voltage reference besides VDD if this supply
|
||||
does not exist.
|
||||
|
||||
This supply will be voltage reference for the following outputs:
|
||||
- for single-channel device: Vout0;
|
||||
- for dual-channel device: Vout0, Vout1;
|
||||
- for quad-channel device: Vout0, Vout2;
|
||||
- for octal-channel device: Vout0, Vout2, Vout6, Vout8;
|
||||
|
||||
vref1-supply:
|
||||
description: |
|
||||
Vref1 pin may be used as a voltage reference when this supply is specified.
|
||||
The internal reference will be taken into account for voltage reference
|
||||
beside VDD if this supply does not exist.
|
||||
|
||||
This supply will be voltage reference for the following outputs:
|
||||
- for quad-channel device: Vout1, Vout3;
|
||||
- for octal-channel device: Vout1, Vout3, Vout5, Vout7;
|
||||
|
||||
lat-gpios:
|
||||
description:
|
||||
LAT pin to be used as a hardware trigger to synchronously update the DAC
|
||||
channels. The pin is active Low. It could be also found as LAT0 in
|
||||
datasheet.
|
||||
maxItems: 1
|
||||
|
||||
lat1-gpios:
|
||||
description:
|
||||
LAT1 pin to be used as a hardware trigger to synchronously update the odd
|
||||
DAC channels on devices with 4 and 8 channels. The pin is active Low.
|
||||
maxItems: 1
|
||||
|
||||
microchip,vref-buffered:
|
||||
type: boolean
|
||||
description:
|
||||
Enable buffering of the external Vref/Vref0 pin in cases where the
|
||||
external reference voltage does not have sufficient current capability in
|
||||
order not to drop it’s voltage when connected to the internal resistor
|
||||
ladder circuit.
|
||||
|
||||
microchip,vref1-buffered:
|
||||
type: boolean
|
||||
description:
|
||||
Enable buffering of the external Vref1 pin in cases where the external
|
||||
reference voltage does not have sufficient current capability in order not
|
||||
to drop it’s voltage when connected to the internal resistor ladder
|
||||
circuit.
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-7]$":
|
||||
$ref: dac.yaml
|
||||
type: object
|
||||
description: Voltage output channel.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: The channel number.
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
|
||||
label:
|
||||
description: Unique name to identify which channel this is.
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- microchip,mcp47feb01
|
||||
- microchip,mcp47feb11
|
||||
- microchip,mcp47feb21
|
||||
- microchip,mcp47fvb01
|
||||
- microchip,mcp47fvb11
|
||||
- microchip,mcp47fvb21
|
||||
then:
|
||||
properties:
|
||||
lat1-gpios: false
|
||||
vref1-supply: false
|
||||
microchip,vref1-buffered: false
|
||||
channel@0:
|
||||
properties:
|
||||
reg:
|
||||
const: 0
|
||||
patternProperties:
|
||||
"^channel@[1-7]$": false
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- microchip,mcp47feb02
|
||||
- microchip,mcp47feb12
|
||||
- microchip,mcp47feb22
|
||||
- microchip,mcp47fvb02
|
||||
- microchip,mcp47fvb12
|
||||
- microchip,mcp47fvb22
|
||||
then:
|
||||
properties:
|
||||
lat1-gpios: false
|
||||
vref1-supply: false
|
||||
microchip,vref1-buffered: false
|
||||
patternProperties:
|
||||
"^channel@[0-1]$":
|
||||
properties:
|
||||
reg:
|
||||
enum: [0, 1]
|
||||
"^channel@[2-7]$": false
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- microchip,mcp47fvb04
|
||||
- microchip,mcp47fvb14
|
||||
- microchip,mcp47fvb24
|
||||
- microchip,mcp47feb04
|
||||
- microchip,mcp47feb14
|
||||
- microchip,mcp47feb24
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel@[0-3]$":
|
||||
properties:
|
||||
reg:
|
||||
enum: [0, 1, 2, 3]
|
||||
"^channel@[4-7]$": false
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- microchip,mcp47fvb08
|
||||
- microchip,mcp47fvb18
|
||||
- microchip,mcp47fvb28
|
||||
- microchip,mcp47feb08
|
||||
- microchip,mcp47feb18
|
||||
- microchip,mcp47feb28
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel@[0-7]$":
|
||||
properties:
|
||||
reg:
|
||||
enum: [0, 1, 2, 3, 4, 5, 6, 7]
|
||||
- if:
|
||||
not:
|
||||
required:
|
||||
- vref-supply
|
||||
then:
|
||||
properties:
|
||||
microchip,vref-buffered: false
|
||||
- if:
|
||||
not:
|
||||
required:
|
||||
- vref1-supply
|
||||
then:
|
||||
properties:
|
||||
microchip,vref1-buffered: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
dac@0 {
|
||||
compatible = "microchip,mcp47feb02";
|
||||
reg = <0>;
|
||||
vdd-supply = <&vdac_vdd>;
|
||||
vref-supply = <&vref_reg>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
label = "Adjustable_voltage_ch0";
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
reg = <0x1>;
|
||||
label = "Adjustable_voltage_ch1";
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -40,6 +40,12 @@ properties:
|
|||
items:
|
||||
- const: ref_in
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
chip-enable-gpios:
|
||||
description:
|
||||
GPIO that controls the Chip Enable Pin.
|
||||
|
|
@ -97,6 +103,8 @@ examples:
|
|||
spi-max-frequency = <10000000>;
|
||||
clocks = <&adf4377_ref_in>;
|
||||
clock-names = "ref_in";
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "adf4377";
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/pressure/honeywell,abp2030pa.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Honeywell abp2030pa pressure sensor
|
||||
|
||||
maintainers:
|
||||
- Petre Rodan <petre.rodan@subdimension.ro>
|
||||
|
||||
description: |
|
||||
Honeywell pressure sensor of model abp2030pa.
|
||||
|
||||
This sensor has an I2C and SPI interface.
|
||||
|
||||
There are many models with different pressure ranges available. The vendor
|
||||
calls them "ABP2 series". All of them have an identical programming model and
|
||||
differ in the pressure range and measurement unit.
|
||||
|
||||
To support different models one needs to specify its pressure triplet.
|
||||
|
||||
For custom silicon chips not covered by the Honeywell ABP2 series datasheet,
|
||||
the pressure values can be specified manually via honeywell,pmin-pascal and
|
||||
honeywell,pmax-pascal.
|
||||
|
||||
Specifications about the devices can be found at:
|
||||
https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/basic-abp2-series/documents/sps-siot-abp2-series-datasheet-32350268-en.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: honeywell,abp2030pa
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
Optional interrupt for indicating end of conversion.
|
||||
SPI variants of ABP2 chips do not provide this feature.
|
||||
maxItems: 1
|
||||
|
||||
honeywell,pressure-triplet:
|
||||
description: |
|
||||
Case-sensitive five character string that defines pressure range, unit
|
||||
and type as part of the device nomenclature. In the unlikely case of a
|
||||
custom chip, unset and provide pmin-pascal and pmax-pascal instead.
|
||||
enum: [001BA, 1.6BA, 2.5BA, 004BA, 006BA, 008BA, 010BA, 012BA, 001BD,
|
||||
1.6BD, 2.5BD, 004BD, 001BG, 1.6BG, 2.5BG, 004BG, 006BG, 008BG,
|
||||
010BG, 012BG, 001GG, 1.2GG, 100KA, 160KA, 250KA, 001KD, 1.6KD,
|
||||
2.5KD, 004KD, 006KD, 010KD, 016KD, 025KD, 040KD, 060KD, 100KD,
|
||||
160KD, 250KD, 400KD, 001KG, 1.6KG, 2.5KG, 004KG, 006KG, 010KG,
|
||||
016KG, 025KG, 040KG, 060KG, 100KG, 160KG, 250KG, 400KG, 600KG,
|
||||
800KG, 250LD, 600LD, 600LG, 2.5MD, 006MD, 010MD, 016MD, 025MD,
|
||||
040MD, 060MD, 100MD, 160MD, 250MD, 400MD, 600MD, 006MG, 010MG,
|
||||
016MG, 025MG, 040MG, 060MG, 100MG, 160MG, 250MG, 400MG, 600MG,
|
||||
001ND, 002ND, 004ND, 005ND, 010ND, 020ND, 030ND, 002NG, 004NG,
|
||||
005NG, 010NG, 020NG, 030NG, 015PA, 030PA, 060PA, 100PA, 150PA,
|
||||
175PA, 001PD, 005PD, 015PD, 030PD, 060PD, 001PG, 005PG, 015PG,
|
||||
030PG, 060PG, 100PG, 150PG, 175PG]
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
honeywell,pmin-pascal:
|
||||
description:
|
||||
Minimum pressure value the sensor can measure in pascal.
|
||||
|
||||
honeywell,pmax-pascal:
|
||||
description:
|
||||
Maximum pressure value the sensor can measure in pascal.
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 800000
|
||||
|
||||
vdd-supply: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- honeywell,pressure-triplet
|
||||
- required:
|
||||
- honeywell,pmin-pascal
|
||||
- honeywell,pmax-pascal
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml
|
||||
- if:
|
||||
required:
|
||||
- honeywell,pressure-triplet
|
||||
then:
|
||||
properties:
|
||||
honeywell,pmin-pascal: false
|
||||
honeywell,pmax-pascal: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pressure@18 {
|
||||
compatible = "honeywell,abp2030pa";
|
||||
reg = <0x18>;
|
||||
interrupt-parent = <&gpio3>;
|
||||
interrupts = <21 IRQ_TYPE_EDGE_RISING>;
|
||||
|
||||
honeywell,pressure-triplet = "001BA";
|
||||
vdd-supply = <&vcc_3v3>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pressure@0 {
|
||||
compatible = "honeywell,abp2030pa";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <800000>;
|
||||
|
||||
honeywell,pressure-triplet = "001PD";
|
||||
vdd-supply = <&vcc_3v3>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/proximity/rfdigital,rfd77402.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: RF Digital RFD77402 ToF sensor
|
||||
|
||||
maintainers:
|
||||
- Shrikant Raskar <raskar.shree97@gmail.com>
|
||||
|
||||
description:
|
||||
The RF Digital RFD77402 is a Time-of-Flight (ToF) proximity and distance
|
||||
sensor providing up to 200 mm range measurement over an I2C interface.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: rfdigital,rfd77402
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description:
|
||||
Interrupt asserted when a new distance measurement is available.
|
||||
|
||||
vdd-supply:
|
||||
description: Regulator that provides power to the sensor.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
proximity@4c {
|
||||
compatible = "rfdigital,rfd77402";
|
||||
reg = <0x4c>;
|
||||
vdd-supply = <&vdd_3v3>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -40,6 +40,7 @@ properties:
|
|||
enum:
|
||||
- mediatek,mt8183-emi
|
||||
- mediatek,mt8195-emi
|
||||
- mediatek,mt8196-emi
|
||||
|
||||
'#interconnect-cells':
|
||||
const: 1
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ properties:
|
|||
- const: qcom,msm8998-bwmon # BWMON v4
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,glymur-cpu-bwmon
|
||||
- qcom,kaanapali-cpu-bwmon
|
||||
- qcom,qcm2290-cpu-bwmon
|
||||
- qcom,qcs615-cpu-bwmon
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ properties:
|
|||
- qcom,qcs615-config-noc
|
||||
- qcom,qcs615-dc-noc
|
||||
- qcom,qcs615-gem-noc
|
||||
- qcom,qcs615-ipa-virt
|
||||
- qcom,qcs615-mc-virt
|
||||
- qcom,qcs615-mmss-noc
|
||||
- qcom,qcs615-system-noc
|
||||
|
|
@ -46,7 +45,6 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,qcs615-camnoc-virt
|
||||
- qcom,qcs615-ipa-virt
|
||||
- qcom,qcs615-mc-virt
|
||||
then:
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/misc/google,android-pipe.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Android Goldfish QEMU Pipe
|
||||
|
||||
maintainers:
|
||||
- Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
|
||||
description:
|
||||
Android QEMU pipe virtual device generated by Android emulator.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: google,android-pipe
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pipe@ff018000 {
|
||||
compatible = "google,android-pipe";
|
||||
reg = <0xff018000 0x2000>;
|
||||
interrupts = <18>;
|
||||
};
|
||||
|
|
@ -18,7 +18,9 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,fastrpc
|
||||
enum:
|
||||
- qcom,kaanapali-fastrpc
|
||||
- qcom,fastrpc
|
||||
|
||||
label:
|
||||
enum:
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ properties:
|
|||
- qcom,sm8450-qfprom
|
||||
- qcom,sm8550-qfprom
|
||||
- qcom,sm8650-qfprom
|
||||
- qcom,sm8750-qfprom
|
||||
- qcom,x1e80100-qfprom
|
||||
- const: qcom,qfprom
|
||||
|
||||
|
|
|
|||
138
Documentation/devicetree/bindings/spmi/mediatek,mt8196-spmi.yaml
Normal file
138
Documentation/devicetree/bindings/spmi/mediatek,mt8196-spmi.yaml
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/spmi/mediatek,mt8196-spmi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MT8196 SPMI 2.0 Controller
|
||||
|
||||
maintainers:
|
||||
- Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
|
||||
description:
|
||||
The MediaTek MT8196 SoC features a SPMI version 2.0 compliant controller,
|
||||
with internal wrapping arbitration logic to allow for multiple on-chip
|
||||
devices to control up to two SPMI buses.
|
||||
The main arbiter also acts as an interrupt controller, arbitering also
|
||||
the interrupts coming from SPMI-connected devices into each of the nested
|
||||
interrupt controllers from any of the present SPMI buses.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt8196-spmi
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6991-spmi
|
||||
- const: mediatek,mt8196-spmi
|
||||
|
||||
ranges: true
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 1
|
||||
|
||||
patternProperties:
|
||||
"^spmi@[a-f0-9]+$":
|
||||
type: object
|
||||
$ref: /schemas/spmi/spmi.yaml
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: controller interface registers
|
||||
- description: spmi master controller registers
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: pmif
|
||||
- const: spmimst
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: controller interface system clock
|
||||
- description: controller interface timer clock
|
||||
- description: spmi controller master clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pmif_sys_ck
|
||||
- const: pmif_tmr_ck
|
||||
- const: spmimst_clk_mux
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: rcs
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 3
|
||||
description: |
|
||||
cell 1: slave ID for the requested interrupt (0-15)
|
||||
cell 2: the requested peripheral interrupt (0-7)
|
||||
cell 3: interrupt flags indicating level-sense information,
|
||||
as defined in dt-bindings/interrupt-controller/irq.h
|
||||
required:
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- interrupt-controller
|
||||
- "#interrupt-cells"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ranges
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
spmi-arbiter@1c018000 {
|
||||
compatible = "mediatek,mt8196-spmi";
|
||||
ranges = <0 0 0x1c018000 0x4900>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
spmi@0 {
|
||||
reg = <0 0x900>, <0x4800 0x100>;
|
||||
reg-names = "pmif", "spmimst";
|
||||
interrupts-extended = <&pio 292 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "rcs";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
clocks = <&pmif_sys>, <&pmif_tmr>, <&spmi_mst>;
|
||||
clock-names = "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux";
|
||||
};
|
||||
|
||||
spmi@2000 {
|
||||
reg = <0x2000 0x900>, <0x4000 0x100>;
|
||||
reg-names = "pmif", "spmimst";
|
||||
interrupts-extended = <&pio 291 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "rcs";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
clocks = <&pmif_sys>, <&pmif_tmr>, <&spmi_mst>;
|
||||
clock-names = "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux";
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -26,6 +26,7 @@ properties:
|
|||
- enum:
|
||||
- mediatek,mt8186-spmi
|
||||
- mediatek,mt8188-spmi
|
||||
- mediatek,mt8189-spmi
|
||||
- const: mediatek,mt8195-spmi
|
||||
|
||||
reg:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/spmi/qcom,glymur-spmi-pmic-arb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. Glymur SPMI Controller (PMIC Arbiter v8)
|
||||
|
||||
maintainers:
|
||||
- David Collins <david.collins@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
The Glymur SPMI PMIC Arbiter implements HW version 8 and it's an SPMI
|
||||
controller with wrapping arbitration logic to allow for multiple on-chip
|
||||
devices to control up to 4 SPMI separate buses.
|
||||
|
||||
The PMIC Arbiter can also act as an interrupt controller, providing interrupts
|
||||
to slave devices.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spmi/qcom,spmi-pmic-arb-common.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,kaanapali-spmi-pmic-arb
|
||||
- const: qcom,glymur-spmi-pmic-arb
|
||||
- enum:
|
||||
- qcom,glymur-spmi-pmic-arb
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: core registers
|
||||
- description: tx-channel per virtual slave registers
|
||||
- description: rx-channel (called observer) per virtual slave registers
|
||||
- description: channel to PMIC peripheral mapping registers
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: chnls
|
||||
- const: obsrvr
|
||||
- const: chnl_map
|
||||
|
||||
ranges: true
|
||||
|
||||
'#address-cells':
|
||||
const: 2
|
||||
|
||||
'#size-cells':
|
||||
const: 2
|
||||
|
||||
patternProperties:
|
||||
"^spmi@[a-f0-9]+$":
|
||||
type: object
|
||||
$ref: /schemas/spmi/spmi.yaml
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: configuration registers
|
||||
- description: interrupt controller registers
|
||||
- description: channel owner EE mapping registers
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: cnfg
|
||||
- const: intr
|
||||
- const: chnl_owner
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: periph_irq
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 4
|
||||
description: |
|
||||
cell 1: slave ID for the requested interrupt (0-15)
|
||||
cell 2: peripheral ID for requested interrupt (0-255)
|
||||
cell 3: the requested peripheral interrupt (0-7)
|
||||
cell 4: interrupt flags indicating level-sense information,
|
||||
as defined in dt-bindings/interrupt-controller/irq.h
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
arbiter@c400000 {
|
||||
compatible = "qcom,glymur-spmi-pmic-arb";
|
||||
reg = <0x0 0xc400000 0x0 0x3000>,
|
||||
<0x0 0xc900000 0x0 0x400000>,
|
||||
<0x0 0xc4c0000 0x0 0x400000>,
|
||||
<0x0 0xc403000 0x0 0x8000>;
|
||||
reg-names = "core", "chnls", "obsrvr", "chnl_map";
|
||||
|
||||
qcom,ee = <0>;
|
||||
qcom,channel = <0>;
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
spmi@c426000 {
|
||||
reg = <0x0 0xc426000 0x0 0x4000>,
|
||||
<0x0 0xc8c0000 0x0 0x10000>,
|
||||
<0x0 0xc42a000 0x0 0x8000>;
|
||||
reg-names = "cnfg", "intr", "chnl_owner";
|
||||
|
||||
interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "periph_irq";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <4>;
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
spmi@c437000 {
|
||||
reg = <0x0 0xc437000 0x0 0x4000>,
|
||||
<0x0 0xc8d0000 0x0 0x10000>,
|
||||
<0x0 0xc43b000 0x0 0x8000>;
|
||||
reg-names = "cnfg", "intr", "chnl_owner";
|
||||
|
||||
interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "periph_irq";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <4>;
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. SPMI Controller (common)
|
||||
|
||||
maintainers:
|
||||
- David Collins <david.collins@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
This defines some common properties used to define Qualcomm SPMI controllers
|
||||
for PMIC arbiter.
|
||||
|
||||
properties:
|
||||
qcom,ee:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
description:
|
||||
indicates the active Execution Environment identifier
|
||||
|
||||
qcom,channel:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
description:
|
||||
which of the PMIC Arb provided channels to use for accesses
|
||||
|
||||
required:
|
||||
- qcom,ee
|
||||
- qcom,channel
|
||||
|
||||
additionalProperties: true
|
||||
|
|
@ -19,6 +19,7 @@ description: |
|
|||
|
||||
allOf:
|
||||
- $ref: spmi.yaml
|
||||
- $ref: qcom,spmi-pmic-arb-common.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -71,20 +72,6 @@ properties:
|
|||
|
||||
'#size-cells': true
|
||||
|
||||
qcom,ee:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
description: >
|
||||
indicates the active Execution Environment identifier
|
||||
|
||||
qcom,channel:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
description: >
|
||||
which of the PMIC Arb provided channels to use for accesses
|
||||
|
||||
qcom,bus-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
|
|
@ -97,8 +84,6 @@ properties:
|
|||
required:
|
||||
- compatible
|
||||
- reg-names
|
||||
- qcom,ee
|
||||
- qcom,channel
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ description: |
|
|||
The PMIC Arbiter can also act as an interrupt controller, providing interrupts
|
||||
to slave devices.
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,spmi-pmic-arb-common.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
|
|
@ -45,20 +48,6 @@ properties:
|
|||
'#size-cells':
|
||||
const: 2
|
||||
|
||||
qcom,ee:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
description: >
|
||||
indicates the active Execution Environment identifier
|
||||
|
||||
qcom,channel:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
description: >
|
||||
which of the PMIC Arb provided channels to use for accesses
|
||||
|
||||
patternProperties:
|
||||
"^spmi@[a-f0-9]+$":
|
||||
type: object
|
||||
|
|
@ -96,10 +85,8 @@ patternProperties:
|
|||
required:
|
||||
- compatible
|
||||
- reg-names
|
||||
- qcom,ee
|
||||
- qcom,channel
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ properties:
|
|||
- meas,tsys01
|
||||
# MEMSIC magnetometer
|
||||
- memsic,mmc35240
|
||||
# MEMSIC 3-axis magnetometer
|
||||
- memsic,mmc5603
|
||||
# MEMSIC 3-axis magnetometer (Support I3C HDR)
|
||||
- memsic,mmc5633
|
||||
# MEMSIC 3-axis accelerometer
|
||||
- memsic,mxc4005
|
||||
# MEMSIC 2-axis 8-bit digital accelerometer
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,8 @@ patternProperties:
|
|||
description: Revolution Robotics, Inc. (Revotics)
|
||||
"^rex,.*":
|
||||
description: iMX6 Rex Project
|
||||
"^rfdigital,.*":
|
||||
description: RF Digital Corporation
|
||||
"^richtek,.*":
|
||||
description: Richtek Technology Corporation
|
||||
"^ricoh,.*":
|
||||
|
|
|
|||
148
Documentation/iio/ad4062.rst
Normal file
148
Documentation/iio/ad4062.rst
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
=============
|
||||
AD4062 driver
|
||||
=============
|
||||
|
||||
ADC driver for Analog Devices Inc. AD4060/AD4062 devices. The module name is
|
||||
``ad4062``.
|
||||
|
||||
Supported devices
|
||||
=================
|
||||
|
||||
The following chips are supported by this driver:
|
||||
|
||||
* `AD4060 <https://www.analog.com/AD4060>`_
|
||||
* `AD4062 <https://www.analog.com/AD4062>`_
|
||||
|
||||
Wiring modes
|
||||
============
|
||||
|
||||
The ADC is interfaced through an I3C bus, and contains two programmable GPIOs.
|
||||
|
||||
The ADC convert-start happens on the SDA rising edge of the I3C stop (P) bit
|
||||
at the end of the read command.
|
||||
|
||||
The two programmable GPIOS are optional and have a role assigned if present in
|
||||
the devicetree ``interrupt-names`` property:
|
||||
|
||||
- GP0: Is assigned the role of Threshold Either signal.
|
||||
- GP1: Is assigned the role of Data Ready signal.
|
||||
|
||||
If the property ``gpio-controller`` is present in the devicetree, then the GPO
|
||||
not present in the ``interrupt-names`` is exposed as a GPO.
|
||||
|
||||
Device attributes
|
||||
=================
|
||||
|
||||
The ADC contains only one channel with following attributes:
|
||||
|
||||
.. list-table:: Channel attributes
|
||||
:header-rows: 1
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - ``in_voltage_calibscale``
|
||||
- Sets the gain scaling factor that the hardware applies to the sample,
|
||||
to compensate for system gain error.
|
||||
* - ``in_voltage_oversampling_ratio``
|
||||
- Sets device's burst averaging mode to over sample using the
|
||||
internal sample rate. Value 1 disable the burst averaging mode.
|
||||
* - ``in_voltage_oversampling_ratio_available``
|
||||
- List of available oversampling values.
|
||||
* - ``in_voltage_raw``
|
||||
- Returns the raw ADC voltage value.
|
||||
* - ``in_voltage_scale``
|
||||
- Returns the channel scale in reference to the reference voltage
|
||||
``ref-supply`` or ``vdd-supply`` if the former not present.
|
||||
|
||||
Also contain the following device attributes:
|
||||
|
||||
.. list-table:: Device attributes
|
||||
:header-rows: 1
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - ``sampling_frequency``
|
||||
- Sets the duration of a single scan, used in the burst averaging mode.
|
||||
The duration is described by ``(n_avg - 1) / fosc + tconv``, where
|
||||
``n_avg`` is the oversampling ratio, ``fosc`` is the internal sample
|
||||
rate and ``tconv`` is the ADC conversion time.
|
||||
* - ``sampling_frequency_available``
|
||||
- Lists the available sampling frequencies, computed on the current
|
||||
oversampling ratio. If the ratio is 1, the frequency is ``1/tconv``.
|
||||
|
||||
Interrupts
|
||||
==========
|
||||
|
||||
The interrupts are mapped through the ``interrupt-names`` and ``interrupts``
|
||||
properties.
|
||||
|
||||
The ``interrupt-names`` ``gp0`` entry sets the role of Threshold signal, and
|
||||
entry ``gp1`` the role of Data Ready signal.
|
||||
|
||||
If each is not present, the driver fallback to enabling the same role as an
|
||||
I3C IBI.
|
||||
|
||||
Low-power mode
|
||||
==============
|
||||
|
||||
The device enters low-power mode on idle to save power. Enabling an event puts
|
||||
the device out of the low-power since the ADC autonomously samples to assert
|
||||
the event condition.
|
||||
|
||||
IIO trigger support
|
||||
===================
|
||||
|
||||
An IIO trigger ``ad4062-devX`` is registered by the driver to be used by the
|
||||
same device, to capture samples to a software buffer. It is required to attach
|
||||
the trigger to the device by setting the ``current_trigger`` before enabling
|
||||
and reading the buffer.
|
||||
|
||||
The acquisition is sequential and bounded by the protocol timings, software
|
||||
latency and internal timings, the sample rate is not configurable. The burst
|
||||
averaging mode does impact the effective sample rate, since it increases the
|
||||
internal timing to output a single sample.
|
||||
|
||||
Threshold events
|
||||
================
|
||||
|
||||
The ADC supports a monitoring mode to raise threshold events. The driver
|
||||
supports a single interrupt for both rising and falling readings.
|
||||
|
||||
The feature is enabled/disabled by setting ``thresh_either_en``. During monitor
|
||||
mode, the device continuously operates in autonomous mode. Any register access
|
||||
puts the device back in configuration mode, due to this, any access disables
|
||||
monitor mode.
|
||||
|
||||
The following event attributes are available:
|
||||
|
||||
.. list-table:: Event attributes
|
||||
:header-rows: 1
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - ``sampling_frequency``
|
||||
- Frequency used in the monitoring mode, sets the device internal sample
|
||||
rate when the mode is activated.
|
||||
* - ``sampling_frequency_available``
|
||||
- List of available sample rates.
|
||||
* - ``thresh_either_en``
|
||||
- Enable monitoring mode.
|
||||
* - ``thresh_falling_hysteresis``
|
||||
- Set the hysteresis value for the minimum threshold.
|
||||
* - ``thresh_falling_value``
|
||||
- Set the minimum threshold value.
|
||||
* - ``thresh_rising_hysteresis``
|
||||
- Set the hysteresis value for the maximum threshold.
|
||||
* - ``thresh_rising_value``
|
||||
- Set the maximum threshold value.
|
||||
|
||||
GPO controller support
|
||||
======================
|
||||
|
||||
The device supports using GP0 and GP1 as GPOs. If the devicetree contains the
|
||||
node ``gpio-controller```, the device is marked as a GPIO controller and the
|
||||
GPs not listed in ``interrupt-names`` are exposed as a GPO. The GPIO index
|
||||
matches the pin name, so if GP0 is not exposed but GP1 is, index 0 is masked
|
||||
out and only index 1 can be set.
|
||||
|
|
@ -22,6 +22,7 @@ Industrial I/O Kernel Drivers
|
|||
ad3552r
|
||||
ad4000
|
||||
ad4030
|
||||
ad4062
|
||||
ad4695
|
||||
ad7191
|
||||
ad7380
|
||||
|
|
|
|||
|
|
@ -613,8 +613,20 @@ They are also listed in the folder /sys/bus/event_source/devices/cs_etm/format/
|
|||
- Session local version of the system wide setting: :ref:`ETM_MODE_RETURNSTACK
|
||||
<coresight-return-stack>`
|
||||
* - timestamp
|
||||
- Session local version of the system wide setting: :ref:`ETMv4_MODE_TIMESTAMP
|
||||
<coresight-timestamp>`
|
||||
- Controls generation and interval of timestamps.
|
||||
|
||||
0 = off, 1 = minimum interval .. 15 = maximum interval.
|
||||
|
||||
Values 1 - 14 use a counter that decrements every cycle to generate a
|
||||
timestamp on underflow. The reload value for the counter is 2 ^ (interval
|
||||
- 1). If the value is 1 then the reload value is 1, if the value is 11
|
||||
then the reload value is 1024 etc.
|
||||
|
||||
Setting the maximum interval (15) will disable the counter generated
|
||||
timestamps, freeing the counter resource, leaving only ones emitted when
|
||||
a SYNC packet is generated. The sync interval is controlled with
|
||||
TRCSYNCPR.PERIOD which is every 4096 bytes of trace by default.
|
||||
|
||||
* - cc_threshold
|
||||
- Cycle count threshold value. If nothing is provided here or the provided value is 0, then the
|
||||
default value i.e 0x100 will be used. If provided value is less than minimum cycles threshold
|
||||
|
|
|
|||
|
|
@ -397,7 +397,6 @@ Code Seq# Include File Comments
|
|||
0xCD 01 linux/reiserfs_fs.h Dead since 6.13
|
||||
0xCE 01-02 uapi/linux/cxl_mem.h Compute Express Link Memory Devices
|
||||
0xCF 02 fs/smb/client/cifs_ioctl.h
|
||||
0xDB 00-0F drivers/char/mwave/mwavepub.h
|
||||
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
|
||||
<mailto:aherrman@de.ibm.com>
|
||||
0xE5 00-3F linux/fuse.h
|
||||
|
|
|
|||
56
MAINTAINERS
56
MAINTAINERS
|
|
@ -1444,6 +1444,14 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad4030.yaml
|
|||
F: Documentation/iio/ad4030.rst
|
||||
F: drivers/iio/adc/ad4030.c
|
||||
|
||||
ANALOG DEVICES INC AD4062 DRIVER
|
||||
M: Jorge Marques <jorge.marques@analog.com>
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml
|
||||
F: Documentation/iio/ad4062.rst
|
||||
F: drivers/iio/adc/ad4062.c
|
||||
|
||||
ANALOG DEVICES INC AD4080 DRIVER
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
@ -1461,6 +1469,14 @@ F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130
|
|||
F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml
|
||||
F: drivers/iio/adc/ad4130.c
|
||||
|
||||
ANALOG DEVICES INC AD4134 DRIVER
|
||||
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml
|
||||
F: drivers/iio/adc/ad4134.c
|
||||
|
||||
ANALOG DEVICES INC AD4170-4 DRIVER
|
||||
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
@ -1605,6 +1621,14 @@ W: https://ez.analog.com/linux-software-drivers
|
|||
F: Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
|
||||
F: drivers/iio/dac/ad9739a.c
|
||||
|
||||
ANALOG DEVICES INC MAX22007 DRIVER
|
||||
M: Janani Sunil <janani.sunil@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml
|
||||
F: drivers/iio/dac/max22007.c
|
||||
|
||||
ANALOG DEVICES INC ADA4250 DRIVER
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
@ -1613,6 +1637,14 @@ W: https://ez.analog.com/linux-software-drivers
|
|||
F: Documentation/devicetree/bindings/iio/amplifiers/adi,ada4250.yaml
|
||||
F: drivers/iio/amplifiers/ada4250.c
|
||||
|
||||
ANALOG DEVICES INC ADE9000 DRIVER
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml
|
||||
F: drivers/iio/adc/ade9000.c
|
||||
|
||||
ANALOG DEVICES INC ADF4377 DRIVER
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
@ -11620,6 +11652,13 @@ F: lib/test_hmm*
|
|||
F: mm/hmm*
|
||||
F: tools/testing/selftests/mm/*hmm*
|
||||
|
||||
HONEYWELL ABP2030PA PRESSURE SENSOR SERIES IIO DRIVER
|
||||
M: Petre Rodan <petre.rodan@subdimension.ro>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml
|
||||
F: drivers/iio/pressure/abp2030pa*
|
||||
|
||||
HONEYWELL HSC030PA PRESSURE SENSOR SERIES IIO DRIVER
|
||||
M: Petre Rodan <petre.rodan@subdimension.ro>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
@ -13090,8 +13129,9 @@ S: Orphan
|
|||
F: drivers/ptp/ptp_dfl_tod.c
|
||||
|
||||
INTEL QUADRATURE ENCODER PERIPHERAL DRIVER
|
||||
M: Jarkko Nikula <jarkko.nikula@linux.intel.com>
|
||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/counter/intel-qep.c
|
||||
|
||||
INTEL SCU DRIVERS
|
||||
|
|
@ -15785,6 +15825,13 @@ F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531
|
|||
F: drivers/iio/potentiometer/mcp4018.c
|
||||
F: drivers/iio/potentiometer/mcp4531.c
|
||||
|
||||
MCP47FEB02 MICROCHIP DAC DRIVER
|
||||
M: Ariana Lazar <ariana.lazar@microchip.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml
|
||||
F: drivers/iio/dac/mcp47feb02.c
|
||||
|
||||
MCP4821 DAC DRIVER
|
||||
M: Anshul Dalal <anshulusr@gmail.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
@ -26287,6 +26334,13 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/iio/adc/ti,ads1119.yaml
|
||||
F: drivers/iio/adc/ti-ads1119.c
|
||||
|
||||
TI ADS1018 ADC DRIVER
|
||||
M: Kurt Borja <kuurtb@gmail.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml
|
||||
F: drivers/iio/adc/ti-ads1018.c
|
||||
|
||||
TI ADS7924 ADC DRIVER
|
||||
M: Hugo Villeneuve <hvilleneuve@dimonoff.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -55,7 +54,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -71,7 +69,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -87,7 +84,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -103,7 +99,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -119,7 +114,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -135,7 +129,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -151,7 +144,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -167,7 +159,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -183,7 +174,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -199,7 +189,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -215,7 +204,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -231,7 +219,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -247,7 +234,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -263,7 +249,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -279,7 +264,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -295,7 +279,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -311,7 +294,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -327,7 +309,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -343,7 +324,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -359,7 +339,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -375,7 +354,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -391,7 +369,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -407,7 +384,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -423,7 +399,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -439,7 +414,6 @@ static const struct mhi_channel_config aic100_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = true,
|
||||
.wake_capable = false,
|
||||
},
|
||||
};
|
||||
|
|
@ -458,7 +432,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -474,7 +447,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -490,7 +462,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -506,7 +477,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -522,7 +492,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -538,7 +507,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -554,7 +522,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -570,7 +537,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -586,7 +552,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -602,7 +567,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -618,7 +582,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -634,7 +597,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -650,7 +612,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -666,7 +627,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -682,7 +642,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -698,7 +657,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -714,7 +672,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
|
|
@ -730,7 +687,6 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.auto_queue = true,
|
||||
.wake_capable = false,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4523,7 +4523,7 @@ static int binder_thread_write(struct binder_proc *proc,
|
|||
}
|
||||
}
|
||||
binder_debug(BINDER_DEBUG_DEAD_BINDER,
|
||||
"%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n",
|
||||
"%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n",
|
||||
proc->pid, thread->pid, (u64)cookie,
|
||||
death);
|
||||
if (death == NULL) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
// Copyright (C) 2025 Google LLC.
|
||||
|
||||
use kernel::{
|
||||
error::Error,
|
||||
list::{List, ListArc, ListLinks},
|
||||
alloc::kvec::KVVec,
|
||||
error::code::*,
|
||||
prelude::*,
|
||||
security,
|
||||
str::{CStr, CString},
|
||||
|
|
@ -17,22 +17,19 @@ use crate::{error::BinderError, node::NodeRef, process::Process};
|
|||
kernel::sync::global_lock! {
|
||||
// SAFETY: We call `init` in the module initializer, so it's initialized before first use.
|
||||
pub(crate) unsafe(uninit) static CONTEXTS: Mutex<ContextList> = ContextList {
|
||||
list: List::new(),
|
||||
contexts: KVVec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) struct ContextList {
|
||||
list: List<Context>,
|
||||
contexts: KVVec<Arc<Context>>,
|
||||
}
|
||||
|
||||
pub(crate) fn get_all_contexts() -> Result<KVec<Arc<Context>>> {
|
||||
pub(crate) fn get_all_contexts() -> Result<KVVec<Arc<Context>>> {
|
||||
let lock = CONTEXTS.lock();
|
||||
|
||||
let count = lock.list.iter().count();
|
||||
|
||||
let mut ctxs = KVec::with_capacity(count, GFP_KERNEL)?;
|
||||
for ctx in &lock.list {
|
||||
ctxs.push(Arc::from(ctx), GFP_KERNEL)?;
|
||||
let mut ctxs = KVVec::with_capacity(lock.contexts.len(), GFP_KERNEL)?;
|
||||
for ctx in lock.contexts.iter() {
|
||||
ctxs.push(ctx.clone(), GFP_KERNEL)?;
|
||||
}
|
||||
Ok(ctxs)
|
||||
}
|
||||
|
|
@ -42,7 +39,7 @@ pub(crate) fn get_all_contexts() -> Result<KVec<Arc<Context>>> {
|
|||
struct Manager {
|
||||
node: Option<NodeRef>,
|
||||
uid: Option<Kuid>,
|
||||
all_procs: List<Process>,
|
||||
all_procs: KVVec<Arc<Process>>,
|
||||
}
|
||||
|
||||
/// There is one context per binder file (/dev/binder, /dev/hwbinder, etc)
|
||||
|
|
@ -51,28 +48,16 @@ pub(crate) struct Context {
|
|||
#[pin]
|
||||
manager: Mutex<Manager>,
|
||||
pub(crate) name: CString,
|
||||
#[pin]
|
||||
links: ListLinks,
|
||||
}
|
||||
|
||||
kernel::list::impl_list_arc_safe! {
|
||||
impl ListArcSafe<0> for Context { untracked; }
|
||||
}
|
||||
kernel::list::impl_list_item! {
|
||||
impl ListItem<0> for Context {
|
||||
using ListLinks { self.links };
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub(crate) fn new(name: &CStr) -> Result<Arc<Self>> {
|
||||
let name = CString::try_from(name)?;
|
||||
let list_ctx = ListArc::pin_init::<Error>(
|
||||
let ctx = Arc::pin_init(
|
||||
try_pin_init!(Context {
|
||||
name,
|
||||
links <- ListLinks::new(),
|
||||
manager <- kernel::new_mutex!(Manager {
|
||||
all_procs: List::new(),
|
||||
all_procs: KVVec::new(),
|
||||
node: None,
|
||||
uid: None,
|
||||
}, "Context::manager"),
|
||||
|
|
@ -80,8 +65,7 @@ impl Context {
|
|||
GFP_KERNEL,
|
||||
)?;
|
||||
|
||||
let ctx = list_ctx.clone_arc();
|
||||
CONTEXTS.lock().list.push_back(list_ctx);
|
||||
CONTEXTS.lock().contexts.push(ctx.clone(), GFP_KERNEL)?;
|
||||
|
||||
Ok(ctx)
|
||||
}
|
||||
|
|
@ -89,27 +73,27 @@ impl Context {
|
|||
/// Called when the file for this context is unlinked.
|
||||
///
|
||||
/// No-op if called twice.
|
||||
pub(crate) fn deregister(&self) {
|
||||
// SAFETY: We never add the context to any other linked list than this one, so it is either
|
||||
// in this list, or not in any list.
|
||||
unsafe { CONTEXTS.lock().list.remove(self) };
|
||||
pub(crate) fn deregister(self: &Arc<Self>) {
|
||||
// Safe removal using retain
|
||||
CONTEXTS.lock().contexts.retain(|c| !Arc::ptr_eq(c, self));
|
||||
}
|
||||
|
||||
pub(crate) fn register_process(self: &Arc<Self>, proc: ListArc<Process>) {
|
||||
pub(crate) fn register_process(self: &Arc<Self>, proc: Arc<Process>) -> Result {
|
||||
if !Arc::ptr_eq(self, &proc.ctx) {
|
||||
pr_err!("Context::register_process called on the wrong context.");
|
||||
return;
|
||||
return Err(EINVAL);
|
||||
}
|
||||
self.manager.lock().all_procs.push_back(proc);
|
||||
self.manager.lock().all_procs.push(proc, GFP_KERNEL)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Process) {
|
||||
pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Arc<Process>) {
|
||||
if !Arc::ptr_eq(self, &proc.ctx) {
|
||||
pr_err!("Context::deregister_process called on the wrong context.");
|
||||
return;
|
||||
}
|
||||
// SAFETY: We just checked that this is the right list.
|
||||
unsafe { self.manager.lock().all_procs.remove(proc) };
|
||||
let mut manager = self.manager.lock();
|
||||
manager.all_procs.retain(|p| !Arc::ptr_eq(p, proc));
|
||||
}
|
||||
|
||||
pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result {
|
||||
|
|
@ -154,27 +138,27 @@ impl Context {
|
|||
{
|
||||
let lock = self.manager.lock();
|
||||
for proc in &lock.all_procs {
|
||||
func(&proc);
|
||||
func(proc);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_all_procs(&self) -> Result<KVec<Arc<Process>>> {
|
||||
pub(crate) fn get_all_procs(&self) -> Result<KVVec<Arc<Process>>> {
|
||||
let lock = self.manager.lock();
|
||||
let count = lock.all_procs.iter().count();
|
||||
|
||||
let mut procs = KVec::with_capacity(count, GFP_KERNEL)?;
|
||||
for proc in &lock.all_procs {
|
||||
procs.push(Arc::from(proc), GFP_KERNEL)?;
|
||||
let mut procs = KVVec::with_capacity(lock.all_procs.len(), GFP_KERNEL)?;
|
||||
for proc in lock.all_procs.iter() {
|
||||
procs.push(Arc::clone(proc), GFP_KERNEL)?;
|
||||
}
|
||||
Ok(procs)
|
||||
}
|
||||
|
||||
pub(crate) fn get_procs_with_pid(&self, pid: i32) -> Result<KVec<Arc<Process>>> {
|
||||
let orig = self.get_all_procs()?;
|
||||
let mut backing = KVec::with_capacity(orig.len(), GFP_KERNEL)?;
|
||||
for proc in orig.into_iter().filter(|proc| proc.task.pid() == pid) {
|
||||
backing.push(proc, GFP_KERNEL)?;
|
||||
pub(crate) fn get_procs_with_pid(&self, pid: i32) -> Result<KVVec<Arc<Process>>> {
|
||||
let lock = self.manager.lock();
|
||||
let mut matching_procs = KVVec::new();
|
||||
for proc in lock.all_procs.iter() {
|
||||
if proc.task.pid() == pid {
|
||||
matching_procs.push(Arc::clone(proc), GFP_KERNEL)?;
|
||||
}
|
||||
}
|
||||
Ok(backing)
|
||||
Ok(matching_procs)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,14 @@ struct NodeInner {
|
|||
refs: List<NodeRefInfo, { NodeRefInfo::LIST_NODE }>,
|
||||
}
|
||||
|
||||
use kernel::bindings::rb_node_layout;
|
||||
use mem::offset_of;
|
||||
pub(crate) const NODE_LAYOUT: rb_node_layout = rb_node_layout {
|
||||
arc_offset: Arc::<Node>::DATA_OFFSET + offset_of!(DTRWrap<Node>, wrapped),
|
||||
debug_id: offset_of!(Node, debug_id),
|
||||
ptr: offset_of!(Node, ptr),
|
||||
};
|
||||
|
||||
#[pin_data]
|
||||
pub(crate) struct Node {
|
||||
pub(crate) debug_id: usize,
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ use kernel::{
|
|||
seq_print,
|
||||
sync::poll::PollTable,
|
||||
sync::{
|
||||
aref::ARef,
|
||||
lock::{spinlock::SpinLockBackend, Guard},
|
||||
Arc, ArcBorrow, CondVar, CondVarTimeoutResult, Mutex, SpinLock, UniqueArc,
|
||||
},
|
||||
task::Task,
|
||||
types::ARef,
|
||||
uaccess::{UserSlice, UserSliceReader},
|
||||
uapi,
|
||||
workqueue::{self, Work},
|
||||
|
|
@ -418,6 +418,13 @@ impl ProcessNodeRefs {
|
|||
}
|
||||
}
|
||||
|
||||
use core::mem::offset_of;
|
||||
use kernel::bindings::rb_process_layout;
|
||||
pub(crate) const PROCESS_LAYOUT: rb_process_layout = rb_process_layout {
|
||||
arc_offset: Arc::<Process>::DATA_OFFSET,
|
||||
task: offset_of!(Process, task),
|
||||
};
|
||||
|
||||
/// A process using binder.
|
||||
///
|
||||
/// Strictly speaking, there can be multiple of these per process. There is one for each binder fd
|
||||
|
|
@ -496,7 +503,7 @@ impl workqueue::WorkItem for Process {
|
|||
impl Process {
|
||||
fn new(ctx: Arc<Context>, cred: ARef<Credential>) -> Result<Arc<Self>> {
|
||||
let current = kernel::current!();
|
||||
let list_process = ListArc::pin_init::<Error>(
|
||||
let process = Arc::pin_init::<Error>(
|
||||
try_pin_init!(Process {
|
||||
ctx,
|
||||
cred,
|
||||
|
|
@ -512,8 +519,7 @@ impl Process {
|
|||
GFP_KERNEL,
|
||||
)?;
|
||||
|
||||
let process = list_process.clone_arc();
|
||||
process.ctx.register_process(list_process);
|
||||
process.ctx.register_process(process.clone())?;
|
||||
|
||||
Ok(process)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,4 +20,83 @@ struct inode;
|
|||
struct dentry *rust_binderfs_create_proc_file(struct inode *nodp, int pid);
|
||||
void rust_binderfs_remove_file(struct dentry *dentry);
|
||||
|
||||
/*
|
||||
* The internal data types in the Rust Binder driver are opaque to C, so we use
|
||||
* void pointer typedefs for these types.
|
||||
*/
|
||||
|
||||
typedef void *rust_binder_transaction;
|
||||
typedef void *rust_binder_process;
|
||||
typedef void *rust_binder_node;
|
||||
|
||||
struct rb_process_layout {
|
||||
size_t arc_offset;
|
||||
size_t task;
|
||||
};
|
||||
|
||||
struct rb_transaction_layout {
|
||||
size_t debug_id;
|
||||
size_t code;
|
||||
size_t flags;
|
||||
size_t from_thread;
|
||||
size_t to_proc;
|
||||
size_t target_node;
|
||||
};
|
||||
|
||||
struct rb_node_layout {
|
||||
size_t arc_offset;
|
||||
size_t debug_id;
|
||||
size_t ptr;
|
||||
};
|
||||
|
||||
struct rust_binder_layout {
|
||||
struct rb_transaction_layout t;
|
||||
struct rb_process_layout p;
|
||||
struct rb_node_layout n;
|
||||
};
|
||||
|
||||
extern const struct rust_binder_layout RUST_BINDER_LAYOUT;
|
||||
|
||||
static inline size_t rust_binder_transaction_debug_id(rust_binder_transaction t)
|
||||
{
|
||||
return *(size_t *) (t + RUST_BINDER_LAYOUT.t.debug_id);
|
||||
}
|
||||
|
||||
static inline u32 rust_binder_transaction_code(rust_binder_transaction t)
|
||||
{
|
||||
return *(u32 *) (t + RUST_BINDER_LAYOUT.t.code);
|
||||
}
|
||||
|
||||
static inline u32 rust_binder_transaction_flags(rust_binder_transaction t)
|
||||
{
|
||||
return *(u32 *) (t + RUST_BINDER_LAYOUT.t.flags);
|
||||
}
|
||||
|
||||
// Nullable!
|
||||
static inline rust_binder_node rust_binder_transaction_target_node(rust_binder_transaction t)
|
||||
{
|
||||
void *p = *(void **) (t + RUST_BINDER_LAYOUT.t.target_node);
|
||||
|
||||
if (p)
|
||||
p = p + RUST_BINDER_LAYOUT.n.arc_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline rust_binder_process rust_binder_transaction_to_proc(rust_binder_transaction t)
|
||||
{
|
||||
void *p = *(void **) (t + RUST_BINDER_LAYOUT.t.to_proc);
|
||||
|
||||
return p + RUST_BINDER_LAYOUT.p.arc_offset;
|
||||
}
|
||||
|
||||
static inline struct task_struct *rust_binder_process_task(rust_binder_process t)
|
||||
{
|
||||
return *(struct task_struct **) (t + RUST_BINDER_LAYOUT.p.task);
|
||||
}
|
||||
|
||||
static inline size_t rust_binder_node_debug_id(rust_binder_node t)
|
||||
{
|
||||
return *(size_t *) (t + RUST_BINDER_LAYOUT.n.debug_id);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,6 +30,36 @@ TRACE_EVENT(rust_binder_ioctl,
|
|||
TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rust_binder_transaction,
|
||||
TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread),
|
||||
TP_ARGS(reply, t, thread),
|
||||
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(
|
||||
rust_binder_process to = rust_binder_transaction_to_proc(t);
|
||||
rust_binder_node target_node = rust_binder_transaction_target_node(t);
|
||||
|
||||
__entry->debug_id = rust_binder_transaction_debug_id(t);
|
||||
__entry->target_node = target_node ? rust_binder_node_debug_id(target_node) : 0;
|
||||
__entry->to_proc = rust_binder_process_task(to)->pid;
|
||||
__entry->to_thread = thread ? thread->pid : 0;
|
||||
__entry->reply = reply;
|
||||
__entry->code = rust_binder_transaction_code(t);
|
||||
__entry->flags = rust_binder_transaction_flags(t);
|
||||
),
|
||||
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)
|
||||
);
|
||||
|
||||
#endif /* _RUST_BINDER_TRACE_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
|
|
|
|||
|
|
@ -87,6 +87,14 @@ module! {
|
|||
license: "GPL",
|
||||
}
|
||||
|
||||
use kernel::bindings::rust_binder_layout;
|
||||
#[no_mangle]
|
||||
static RUST_BINDER_LAYOUT: rust_binder_layout = rust_binder_layout {
|
||||
t: transaction::TRANSACTION_LAYOUT,
|
||||
p: process::PROCESS_LAYOUT,
|
||||
n: node::NODE_LAYOUT,
|
||||
};
|
||||
|
||||
fn next_debug_id() -> usize {
|
||||
static NEXT_DEBUG_ID: Atomic<usize> = Atomic::new(0);
|
||||
|
||||
|
|
@ -286,7 +294,7 @@ impl kernel::Module for BinderModule {
|
|||
|
||||
pr_warn!("Loaded Rust Binder.");
|
||||
|
||||
BINDER_SHRINKER.register(kernel::c_str!("android-binder"))?;
|
||||
BINDER_SHRINKER.register(c"android-binder")?;
|
||||
|
||||
// SAFETY: The module is being loaded, so we can initialize binderfs.
|
||||
unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? };
|
||||
|
|
@ -312,7 +320,7 @@ pub static rust_binder_fops: AssertSync<kernel::bindings::file_operations> = {
|
|||
owner: THIS_MODULE.as_ptr(),
|
||||
poll: Some(rust_binder_poll),
|
||||
unlocked_ioctl: Some(rust_binder_ioctl),
|
||||
compat_ioctl: Some(bindings::compat_ptr_ioctl),
|
||||
compat_ioctl: bindings::compat_ptr_ioctl,
|
||||
mmap: Some(rust_binder_mmap),
|
||||
open: Some(rust_binder_open),
|
||||
release: Some(rust_binder_release),
|
||||
|
|
|
|||
|
|
@ -17,9 +17,8 @@ use kernel::{
|
|||
seq_print,
|
||||
sync::atomic::{ordering::Relaxed, Atomic},
|
||||
sync::poll::{PollCondVar, PollTable},
|
||||
sync::{Arc, SpinLock},
|
||||
sync::{aref::ARef, Arc, SpinLock},
|
||||
task::Task,
|
||||
types::ARef,
|
||||
uaccess::UserSlice,
|
||||
uapi,
|
||||
};
|
||||
|
|
@ -1146,6 +1145,7 @@ impl Thread {
|
|||
transaction: &DArc<Transaction>,
|
||||
) -> bool {
|
||||
if let Ok(transaction) = &reply {
|
||||
crate::trace::trace_transaction(true, transaction, Some(&self.task));
|
||||
transaction.set_outstanding(&mut self.process.inner.lock());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,21 @@
|
|||
|
||||
// Copyright (C) 2025 Google LLC.
|
||||
|
||||
use crate::transaction::Transaction;
|
||||
|
||||
use kernel::bindings::{rust_binder_transaction, task_struct};
|
||||
use kernel::ffi::{c_uint, c_ulong};
|
||||
use kernel::task::Task;
|
||||
use kernel::tracepoint::declare_trace;
|
||||
|
||||
declare_trace! {
|
||||
unsafe fn rust_binder_ioctl(cmd: c_uint, arg: c_ulong);
|
||||
unsafe fn rust_binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn raw_transaction(t: &Transaction) -> rust_binder_transaction {
|
||||
t as *const Transaction as rust_binder_transaction
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -14,3 +24,14 @@ pub(crate) fn trace_ioctl(cmd: u32, arg: usize) {
|
|||
// SAFETY: Always safe to call.
|
||||
unsafe { rust_binder_ioctl(cmd, arg as c_ulong) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>) {
|
||||
let thread = match thread {
|
||||
Some(thread) => thread.as_ptr(),
|
||||
None => core::ptr::null_mut(),
|
||||
};
|
||||
// SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is
|
||||
// valid or null.
|
||||
unsafe { rust_binder_transaction(reply, raw_transaction(t), thread) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,17 @@ use crate::{
|
|||
BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead,
|
||||
};
|
||||
|
||||
use core::mem::offset_of;
|
||||
use kernel::bindings::rb_transaction_layout;
|
||||
pub(crate) const TRANSACTION_LAYOUT: rb_transaction_layout = rb_transaction_layout {
|
||||
debug_id: offset_of!(Transaction, debug_id),
|
||||
code: offset_of!(Transaction, code),
|
||||
flags: offset_of!(Transaction, flags),
|
||||
from_thread: offset_of!(Transaction, from),
|
||||
to_proc: offset_of!(Transaction, to),
|
||||
target_node: offset_of!(Transaction, target_node),
|
||||
};
|
||||
|
||||
#[pin_data(PinnedDrop)]
|
||||
pub(crate) struct Transaction {
|
||||
pub(crate) debug_id: usize,
|
||||
|
|
@ -249,6 +260,7 @@ impl Transaction {
|
|||
|
||||
if oneway {
|
||||
if let Some(target_node) = self.target_node.clone() {
|
||||
crate::trace::trace_transaction(false, &self, None);
|
||||
if process_inner.is_frozen.is_frozen() {
|
||||
process_inner.async_recv = true;
|
||||
if self.flags & TF_UPDATE_TXN != 0 {
|
||||
|
|
@ -286,11 +298,13 @@ impl Transaction {
|
|||
}
|
||||
|
||||
let res = if let Some(thread) = self.find_target_thread() {
|
||||
crate::trace::trace_transaction(false, &self, Some(&thread.task));
|
||||
match thread.push_work(self) {
|
||||
PushWorkRes::Ok => Ok(()),
|
||||
PushWorkRes::FailedDead(me) => Err((BinderError::new_dead(), me)),
|
||||
}
|
||||
} else {
|
||||
crate::trace::trace_transaction(false, &self, None);
|
||||
process_inner.push_work(self)
|
||||
};
|
||||
drop(process_inner);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ static void binder_insert_free_buffer(struct binder_alloc *alloc,
|
|||
new_buffer_size = binder_alloc_buffer_size(alloc, new_buffer);
|
||||
|
||||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
|
||||
"%d: add free buffer, size %zd, at %pK\n",
|
||||
"%d: add free buffer, size %zd, at %p\n",
|
||||
alloc->pid, new_buffer_size, new_buffer);
|
||||
|
||||
while (*p) {
|
||||
|
|
@ -572,7 +572,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
|
|||
}
|
||||
|
||||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
|
||||
"%d: binder_alloc_buf size %zd got buffer %pK size %zd\n",
|
||||
"%d: binder_alloc_buf size %zd got buffer %p size %zd\n",
|
||||
alloc->pid, size, buffer, buffer_size);
|
||||
|
||||
/*
|
||||
|
|
@ -748,7 +748,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc,
|
|||
ALIGN(buffer->extra_buffers_size, sizeof(void *));
|
||||
|
||||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
|
||||
"%d: binder_free_buf %pK size %zd buffer_size %zd\n",
|
||||
"%d: binder_free_buf %p size %zd buffer_size %zd\n",
|
||||
alloc->pid, buffer, size, buffer_size);
|
||||
|
||||
BUG_ON(buffer->free);
|
||||
|
|
|
|||
|
|
@ -432,10 +432,9 @@ const struct device_type fsl_mc_bus_dpdmai_type = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmai_type);
|
||||
|
||||
const struct device_type fsl_mc_bus_dpdbg_type = {
|
||||
static const struct device_type fsl_mc_bus_dpdbg_type = {
|
||||
.name = "fsl_mc_bus_dpdbg"
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdbg_type);
|
||||
|
||||
static const struct device_type *fsl_mc_get_device_type(const char *type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1596,7 +1596,7 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller);
|
||||
|
||||
static int mhi_ep_driver_probe(struct device *dev)
|
||||
static int mhi_ep_probe(struct device *dev)
|
||||
{
|
||||
struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
|
||||
struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver);
|
||||
|
|
@ -1609,7 +1609,7 @@ static int mhi_ep_driver_probe(struct device *dev)
|
|||
return mhi_drv->probe(mhi_dev, mhi_dev->id);
|
||||
}
|
||||
|
||||
static int mhi_ep_driver_remove(struct device *dev)
|
||||
static void mhi_ep_remove(struct device *dev)
|
||||
{
|
||||
struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
|
||||
struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver);
|
||||
|
|
@ -1619,7 +1619,7 @@ static int mhi_ep_driver_remove(struct device *dev)
|
|||
|
||||
/* Skip if it is a controller device */
|
||||
if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
/* Disconnect the channels associated with the driver */
|
||||
for (dir = 0; dir < 2; dir++) {
|
||||
|
|
@ -1643,8 +1643,6 @@ static int mhi_ep_driver_remove(struct device *dev)
|
|||
|
||||
/* Remove the client driver now */
|
||||
mhi_drv->remove(mhi_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner)
|
||||
|
|
@ -1660,8 +1658,6 @@ int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner
|
|||
|
||||
driver->bus = &mhi_ep_bus_type;
|
||||
driver->owner = owner;
|
||||
driver->probe = mhi_ep_driver_probe;
|
||||
driver->remove = mhi_ep_driver_remove;
|
||||
|
||||
return driver_register(driver);
|
||||
}
|
||||
|
|
@ -1708,6 +1704,8 @@ const struct bus_type mhi_ep_bus_type = {
|
|||
.dev_name = "mhi_ep",
|
||||
.match = mhi_ep_match,
|
||||
.uevent = mhi_ep_uevent,
|
||||
.probe = mhi_ep_probe,
|
||||
.remove = mhi_ep_remove,
|
||||
};
|
||||
|
||||
static int __init mhi_ep_init(void)
|
||||
|
|
|
|||
|
|
@ -584,6 +584,16 @@ skip_req_fw:
|
|||
* device transitioning into MHI READY state
|
||||
*/
|
||||
if (fw_load_type == MHI_FW_LOAD_FBC) {
|
||||
/*
|
||||
* Some FW combine two separate ELF images (SBL + WLAN FW) in a single
|
||||
* file. Hence, check for the existence of the second ELF header after
|
||||
* SBL. If present, load the second image separately.
|
||||
*/
|
||||
if (!memcmp(fw_data + mhi_cntrl->sbl_size, ELFMAG, SELFMAG)) {
|
||||
fw_data += mhi_cntrl->sbl_size;
|
||||
fw_sz -= mhi_cntrl->sbl_size;
|
||||
}
|
||||
|
||||
ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz);
|
||||
if (ret) {
|
||||
release_firmware(firmware);
|
||||
|
|
|
|||
|
|
@ -841,18 +841,8 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl,
|
|||
mhi_chan->lpm_notify = ch_cfg->lpm_notify;
|
||||
mhi_chan->offload_ch = ch_cfg->offload_channel;
|
||||
mhi_chan->db_cfg.reset_req = ch_cfg->doorbell_mode_switch;
|
||||
mhi_chan->pre_alloc = ch_cfg->auto_queue;
|
||||
mhi_chan->wake_capable = ch_cfg->wake_capable;
|
||||
|
||||
/*
|
||||
* If MHI host allocates buffers, then the channel direction
|
||||
* should be DMA_FROM_DEVICE
|
||||
*/
|
||||
if (mhi_chan->pre_alloc && mhi_chan->dir != DMA_FROM_DEVICE) {
|
||||
dev_err(dev, "Invalid channel configuration\n");
|
||||
goto error_chan_cfg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bi-directional and direction less channel must be an
|
||||
* offload channel
|
||||
|
|
@ -1265,7 +1255,7 @@ struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl)
|
|||
return mhi_dev;
|
||||
}
|
||||
|
||||
static int mhi_driver_probe(struct device *dev)
|
||||
static int mhi_probe(struct device *dev)
|
||||
{
|
||||
struct mhi_device *mhi_dev = to_mhi_device(dev);
|
||||
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
|
||||
|
|
@ -1341,7 +1331,7 @@ exit_probe:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mhi_driver_remove(struct device *dev)
|
||||
static void mhi_remove(struct device *dev)
|
||||
{
|
||||
struct mhi_device *mhi_dev = to_mhi_device(dev);
|
||||
struct mhi_driver *mhi_drv = to_mhi_driver(dev->driver);
|
||||
|
|
@ -1355,7 +1345,7 @@ static int mhi_driver_remove(struct device *dev)
|
|||
|
||||
/* Skip if it is a controller device */
|
||||
if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
/* Reset both channels */
|
||||
for (dir = 0; dir < 2; dir++) {
|
||||
|
|
@ -1407,8 +1397,6 @@ static int mhi_driver_remove(struct device *dev)
|
|||
|
||||
while (mhi_dev->dev_wake)
|
||||
mhi_device_put(mhi_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __mhi_driver_register(struct mhi_driver *mhi_drv, struct module *owner)
|
||||
|
|
@ -1420,8 +1408,6 @@ int __mhi_driver_register(struct mhi_driver *mhi_drv, struct module *owner)
|
|||
|
||||
driver->bus = &mhi_bus_type;
|
||||
driver->owner = owner;
|
||||
driver->probe = mhi_driver_probe;
|
||||
driver->remove = mhi_driver_remove;
|
||||
|
||||
return driver_register(driver);
|
||||
}
|
||||
|
|
@ -1468,6 +1454,8 @@ const struct bus_type mhi_bus_type = {
|
|||
.dev_name = "mhi",
|
||||
.match = mhi_match,
|
||||
.uevent = mhi_uevent,
|
||||
.probe = mhi_probe,
|
||||
.remove = mhi_remove,
|
||||
.dev_groups = mhi_dev_groups,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -286,7 +286,6 @@ struct mhi_chan {
|
|||
bool lpm_notify;
|
||||
bool configured;
|
||||
bool offload_ch;
|
||||
bool pre_alloc;
|
||||
bool wake_capable;
|
||||
};
|
||||
|
||||
|
|
@ -389,8 +388,6 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
|
|||
struct image_info *img_info);
|
||||
void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/* Automatically allocate and queue inbound buffers */
|
||||
#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0)
|
||||
int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_chan *mhi_chan);
|
||||
void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
|
||||
|
|
|
|||
|
|
@ -664,23 +664,6 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
|
|||
mhi_cntrl->runtime_put(mhi_cntrl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recycle the buffer if buffer is pre-allocated,
|
||||
* if there is an error, not much we can do apart
|
||||
* from dropping the packet
|
||||
*/
|
||||
if (mhi_chan->pre_alloc) {
|
||||
if (mhi_queue_buf(mhi_chan->mhi_dev,
|
||||
mhi_chan->dir,
|
||||
buf_info->cb_buf,
|
||||
buf_info->len, MHI_EOT)) {
|
||||
dev_err(dev,
|
||||
"Error recycling buffer for chan:%d\n",
|
||||
mhi_chan->chan);
|
||||
kfree(buf_info->cb_buf);
|
||||
}
|
||||
}
|
||||
|
||||
read_lock_bh(&mhi_chan->lock);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1177,17 +1160,12 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info,
|
|||
int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir,
|
||||
struct sk_buff *skb, size_t len, enum mhi_flags mflags)
|
||||
{
|
||||
struct mhi_chan *mhi_chan = (dir == DMA_TO_DEVICE) ? mhi_dev->ul_chan :
|
||||
mhi_dev->dl_chan;
|
||||
struct mhi_buf_info buf_info = { };
|
||||
|
||||
buf_info.v_addr = skb->data;
|
||||
buf_info.cb_buf = skb;
|
||||
buf_info.len = len;
|
||||
|
||||
if (unlikely(mhi_chan->pre_alloc))
|
||||
return -EINVAL;
|
||||
|
||||
return mhi_queue(mhi_dev, &buf_info, dir, mflags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_queue_skb);
|
||||
|
|
@ -1472,45 +1450,6 @@ static int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
|
|||
if (ret)
|
||||
goto error_pm_state;
|
||||
|
||||
if (mhi_chan->dir == DMA_FROM_DEVICE)
|
||||
mhi_chan->pre_alloc = !!(flags & MHI_CH_INBOUND_ALLOC_BUFS);
|
||||
|
||||
/* Pre-allocate buffer for xfer ring */
|
||||
if (mhi_chan->pre_alloc) {
|
||||
int nr_el = get_nr_avail_ring_elements(mhi_cntrl,
|
||||
&mhi_chan->tre_ring);
|
||||
size_t len = mhi_cntrl->buffer_len;
|
||||
|
||||
while (nr_el--) {
|
||||
void *buf;
|
||||
struct mhi_buf_info info = { };
|
||||
|
||||
buf = kmalloc(len, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
ret = -ENOMEM;
|
||||
goto error_pre_alloc;
|
||||
}
|
||||
|
||||
/* Prepare transfer descriptors */
|
||||
info.v_addr = buf;
|
||||
info.cb_buf = buf;
|
||||
info.len = len;
|
||||
ret = mhi_gen_tre(mhi_cntrl, mhi_chan, &info, MHI_EOT);
|
||||
if (ret) {
|
||||
kfree(buf);
|
||||
goto error_pre_alloc;
|
||||
}
|
||||
}
|
||||
|
||||
read_lock_bh(&mhi_cntrl->pm_lock);
|
||||
if (MHI_DB_ACCESS_VALID(mhi_cntrl)) {
|
||||
read_lock_irq(&mhi_chan->lock);
|
||||
mhi_ring_chan_db(mhi_cntrl, mhi_chan);
|
||||
read_unlock_irq(&mhi_chan->lock);
|
||||
}
|
||||
read_unlock_bh(&mhi_cntrl->pm_lock);
|
||||
}
|
||||
|
||||
mutex_unlock(&mhi_chan->mutex);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1522,12 +1461,6 @@ error_pm_state:
|
|||
error_init_chan:
|
||||
mutex_unlock(&mhi_chan->mutex);
|
||||
|
||||
return ret;
|
||||
|
||||
error_pre_alloc:
|
||||
mutex_unlock(&mhi_chan->mutex);
|
||||
mhi_unprepare_channel(mhi_cntrl, mhi_chan);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1600,12 +1533,8 @@ static void mhi_reset_data_chan(struct mhi_controller *mhi_cntrl,
|
|||
mhi_del_ring_element(mhi_cntrl, buf_ring);
|
||||
mhi_del_ring_element(mhi_cntrl, tre_ring);
|
||||
|
||||
if (mhi_chan->pre_alloc) {
|
||||
kfree(buf_info->cb_buf);
|
||||
} else {
|
||||
result.buf_addr = buf_info->cb_buf;
|
||||
mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
|
||||
}
|
||||
result.buf_addr = buf_info->cb_buf;
|
||||
mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1666,12 +1595,6 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer);
|
||||
|
||||
int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev)
|
||||
{
|
||||
return __mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer_autoqueue);
|
||||
|
||||
void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev)
|
||||
{
|
||||
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
|
||||
|
|
|
|||
|
|
@ -94,22 +94,6 @@ struct mhi_pci_dev_info {
|
|||
.doorbell_mode_switch = false, \
|
||||
}
|
||||
|
||||
#define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring) \
|
||||
{ \
|
||||
.num = ch_num, \
|
||||
.name = ch_name, \
|
||||
.num_elements = el_count, \
|
||||
.event_ring = ev_ring, \
|
||||
.dir = DMA_FROM_DEVICE, \
|
||||
.ee_mask = BIT(MHI_EE_AMSS), \
|
||||
.pollcfg = 0, \
|
||||
.doorbell = MHI_DB_BRST_DISABLE, \
|
||||
.lpm_notify = false, \
|
||||
.offload_channel = false, \
|
||||
.doorbell_mode_switch = false, \
|
||||
.auto_queue = true, \
|
||||
}
|
||||
|
||||
#define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \
|
||||
{ \
|
||||
.num_elements = el_count, \
|
||||
|
|
@ -329,7 +313,7 @@ static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = {
|
|||
MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0),
|
||||
MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0),
|
||||
MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0),
|
||||
MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0),
|
||||
MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0),
|
||||
MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),
|
||||
MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
|
||||
MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2),
|
||||
|
|
@ -762,7 +746,7 @@ static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = {
|
|||
MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),
|
||||
MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),
|
||||
MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0),
|
||||
MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0),
|
||||
MHI_CHANNEL_CONFIG_DL(21, "IPCR", 16, 0),
|
||||
MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1),
|
||||
MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -249,32 +249,6 @@ config SONYPI
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called sonypi.
|
||||
|
||||
config MWAVE
|
||||
tristate "ACP Modem (Mwave) support"
|
||||
depends on X86 && TTY
|
||||
select SERIAL_8250
|
||||
help
|
||||
The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
|
||||
kernel driver and a user level application. Together these components
|
||||
support direct attachment to public switched telephone networks (PSTNs)
|
||||
and support selected world wide countries.
|
||||
|
||||
This version of the ACP Modem driver supports the IBM Thinkpad 600E,
|
||||
600, and 770 that include on board ACP modem hardware.
|
||||
|
||||
The modem also supports the standard communications port interface
|
||||
(ttySx) and is compatible with the Hayes AT Command Set.
|
||||
|
||||
The user level application needed to use this driver can be found at
|
||||
the IBM Linux Technology Center (LTC) web site:
|
||||
<http://www.ibm.com/linux/ltc/>.
|
||||
|
||||
If you own one of the above IBM Thinkpads which has the Mwave chipset
|
||||
in it, say Y.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called mwave.
|
||||
|
||||
config SCx200_GPIO
|
||||
tristate "NatSemi SCx200 GPIO Support"
|
||||
depends on SCx200
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
|
|||
obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
|
||||
obj-$(CONFIG_TELCLOCK) += tlclk.o
|
||||
|
||||
obj-$(CONFIG_MWAVE) += mwave/
|
||||
obj-y += agp/
|
||||
|
||||
obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ static void __init miscdev_test_can_open(struct kunit *test, struct miscdevice *
|
|||
KUNIT_FAIL(test, "failed to create node\n");
|
||||
|
||||
filp = filp_open(devname, O_RDONLY, 0);
|
||||
if (IS_ERR_OR_NULL(filp))
|
||||
if (IS_ERR(filp))
|
||||
KUNIT_FAIL(test, "failed to open misc device: %ld\n", PTR_ERR(filp));
|
||||
else
|
||||
fput(filp);
|
||||
|
|
|
|||
|
|
@ -1,536 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* 3780i.c -- helper routines for the 3780i DSP
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "3780i: " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/sched.h> /* cond_resched() */
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/irq.h>
|
||||
#include "smapi.h"
|
||||
#include "mwavedd.h"
|
||||
#include "3780i.h"
|
||||
|
||||
static DEFINE_SPINLOCK(dsp_lock);
|
||||
|
||||
static void PaceMsaAccess(unsigned short usDspBaseIO)
|
||||
{
|
||||
cond_resched();
|
||||
udelay(100);
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
|
||||
unsigned long ulMsaAddr)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short val;
|
||||
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
|
||||
val = InWordDsp(DSP_MsaDataDSISHigh);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
|
||||
unsigned long ulMsaAddr, unsigned short usValue)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
|
||||
OutWordDsp(DSP_MsaDataDSISHigh, usValue);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
}
|
||||
|
||||
static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
|
||||
unsigned char ucValue)
|
||||
{
|
||||
DSP_ISA_SLAVE_CONTROL rSlaveControl;
|
||||
DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
|
||||
|
||||
MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl);
|
||||
|
||||
rSlaveControl_Save = rSlaveControl;
|
||||
rSlaveControl.ConfigMode = true;
|
||||
|
||||
OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl));
|
||||
OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex);
|
||||
OutByteDsp(DSP_ConfigData, ucValue);
|
||||
OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save));
|
||||
}
|
||||
|
||||
int dsp3780I_EnableDSP(struct dsp_3780i_config_settings *pSettings,
|
||||
unsigned short *pIrqMap,
|
||||
unsigned short *pDmaMap)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
int i;
|
||||
DSP_UART_CFG_1 rUartCfg1;
|
||||
DSP_UART_CFG_2 rUartCfg2;
|
||||
DSP_HBRIDGE_CFG_1 rHBridgeCfg1;
|
||||
DSP_HBRIDGE_CFG_2 rHBridgeCfg2;
|
||||
DSP_BUSMASTER_CFG_1 rBusmasterCfg1;
|
||||
DSP_BUSMASTER_CFG_2 rBusmasterCfg2;
|
||||
DSP_ISA_PROT_CFG rIsaProtCfg;
|
||||
DSP_POWER_MGMT_CFG rPowerMgmtCfg;
|
||||
DSP_HBUS_TIMER_CFG rHBusTimerCfg;
|
||||
DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable;
|
||||
DSP_CHIP_RESET rChipReset;
|
||||
DSP_CLOCK_CONTROL_1 rClockControl1;
|
||||
DSP_CLOCK_CONTROL_2 rClockControl2;
|
||||
DSP_ISA_SLAVE_CONTROL rSlaveControl;
|
||||
DSP_HBRIDGE_CONTROL rHBridgeControl;
|
||||
unsigned short tval;
|
||||
|
||||
if (!pSettings->bDSPEnabled) {
|
||||
pr_err("%s: Error: DSP not enabled. Aborting.\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (pSettings->bModemEnabled) {
|
||||
rUartCfg1.Reserved = rUartCfg2.Reserved = 0;
|
||||
rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow;
|
||||
rUartCfg1.IrqPulse = pSettings->bUartIrqPulse;
|
||||
rUartCfg1.Irq =
|
||||
(unsigned char) pIrqMap[pSettings->usUartIrq];
|
||||
switch (pSettings->usUartBaseIO) {
|
||||
case 0x03F8:
|
||||
rUartCfg1.BaseIO = 0;
|
||||
break;
|
||||
case 0x02F8:
|
||||
rUartCfg1.BaseIO = 1;
|
||||
break;
|
||||
case 0x03E8:
|
||||
rUartCfg1.BaseIO = 2;
|
||||
break;
|
||||
case 0x02E8:
|
||||
rUartCfg1.BaseIO = 3;
|
||||
break;
|
||||
}
|
||||
rUartCfg2.Enable = true;
|
||||
}
|
||||
|
||||
rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0;
|
||||
rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow;
|
||||
rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse;
|
||||
rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq];
|
||||
rHBridgeCfg1.AccessMode = 1;
|
||||
rHBridgeCfg2.Enable = true;
|
||||
|
||||
|
||||
rBusmasterCfg2.Reserved = 0;
|
||||
rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma];
|
||||
rBusmasterCfg1.NumTransfers =
|
||||
(unsigned char) pSettings->usNumTransfers;
|
||||
rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest;
|
||||
rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16;
|
||||
rBusmasterCfg2.IsaMemCmdWidth =
|
||||
(unsigned char) pSettings->usIsaMemCmdWidth;
|
||||
|
||||
|
||||
rIsaProtCfg.Reserved = 0;
|
||||
rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY;
|
||||
|
||||
rPowerMgmtCfg.Reserved = 0;
|
||||
rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt;
|
||||
|
||||
rHBusTimerCfg.LoadValue =
|
||||
(unsigned char) pSettings->usHBusTimerLoadValue;
|
||||
|
||||
rLBusTimeoutDisable.Reserved = 0;
|
||||
rLBusTimeoutDisable.DisableTimeout =
|
||||
pSettings->bDisableLBusTimeout;
|
||||
|
||||
MKWORD(rChipReset) = ~pSettings->usChipletEnable;
|
||||
|
||||
rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0;
|
||||
rClockControl1.N_Divisor = pSettings->usN_Divisor;
|
||||
rClockControl1.M_Multiplier = pSettings->usM_Multiplier;
|
||||
|
||||
rClockControl2.Reserved = 0;
|
||||
rClockControl2.PllBypass = pSettings->bPllBypass;
|
||||
|
||||
/* Issue a soft reset to the chip */
|
||||
/* Note: Since we may be coming in with 3780i clocks suspended, we must keep
|
||||
* soft-reset active for 10ms.
|
||||
*/
|
||||
rSlaveControl.ClockControl = 0;
|
||||
rSlaveControl.SoftReset = true;
|
||||
rSlaveControl.ConfigMode = false;
|
||||
rSlaveControl.Reserved = 0;
|
||||
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
|
||||
MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);
|
||||
|
||||
for (i = 0; i < 11; i++)
|
||||
udelay(2000);
|
||||
|
||||
rSlaveControl.SoftReset = false;
|
||||
OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
|
||||
|
||||
MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);
|
||||
|
||||
/* Program our general configuration registers */
|
||||
WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1));
|
||||
WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2));
|
||||
WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1));
|
||||
WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2));
|
||||
WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg));
|
||||
WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg));
|
||||
WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg));
|
||||
|
||||
if (pSettings->bModemEnabled) {
|
||||
WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1));
|
||||
WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2));
|
||||
}
|
||||
|
||||
|
||||
rHBridgeControl.EnableDspInt = false;
|
||||
rHBridgeControl.MemAutoInc = true;
|
||||
rHBridgeControl.IoAutoInc = false;
|
||||
rHBridgeControl.DiagnosticMode = false;
|
||||
|
||||
OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable));
|
||||
WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1));
|
||||
WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2));
|
||||
WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset));
|
||||
|
||||
ReadMsaCfg(DSP_ChipID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dsp3780I_DisableDSP(struct dsp_3780i_config_settings *pSettings)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
DSP_ISA_SLAVE_CONTROL rSlaveControl;
|
||||
|
||||
rSlaveControl.ClockControl = 0;
|
||||
rSlaveControl.SoftReset = true;
|
||||
rSlaveControl.ConfigMode = false;
|
||||
rSlaveControl.Reserved = 0;
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
|
||||
|
||||
udelay(5);
|
||||
|
||||
rSlaveControl.ClockControl = 1;
|
||||
OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
udelay(5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dsp3780I_Reset(struct dsp_3780i_config_settings *pSettings)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
DSP_BOOT_DOMAIN rBootDomain;
|
||||
DSP_HBRIDGE_CONTROL rHBridgeControl;
|
||||
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
/* Mask DSP to PC interrupt */
|
||||
MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
|
||||
|
||||
rHBridgeControl.EnableDspInt = false;
|
||||
OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
/* Reset the core via the boot domain register */
|
||||
rBootDomain.ResetCore = true;
|
||||
rBootDomain.Halt = true;
|
||||
rBootDomain.NMI = true;
|
||||
rBootDomain.Reserved = 0;
|
||||
|
||||
WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
|
||||
|
||||
/* Reset all the chiplets and then reactivate them */
|
||||
WriteMsaCfg(DSP_ChipReset, 0xFFFF);
|
||||
udelay(5);
|
||||
WriteMsaCfg(DSP_ChipReset,
|
||||
(unsigned short) (~pSettings->usChipletEnable));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dsp3780I_Run(struct dsp_3780i_config_settings *pSettings)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
DSP_BOOT_DOMAIN rBootDomain;
|
||||
DSP_HBRIDGE_CONTROL rHBridgeControl;
|
||||
|
||||
/* Transition the core to a running state */
|
||||
rBootDomain.ResetCore = true;
|
||||
rBootDomain.Halt = false;
|
||||
rBootDomain.NMI = true;
|
||||
rBootDomain.Reserved = 0;
|
||||
WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
|
||||
|
||||
udelay(5);
|
||||
|
||||
rBootDomain.ResetCore = false;
|
||||
WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
|
||||
udelay(5);
|
||||
|
||||
rBootDomain.NMI = false;
|
||||
WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
|
||||
udelay(5);
|
||||
|
||||
/* Enable DSP to PC interrupt */
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
|
||||
rHBridgeControl.EnableDspInt = true;
|
||||
|
||||
OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short __user *pusBuffer = pvBuffer;
|
||||
unsigned short val;
|
||||
|
||||
/* Set the initial MSA address. No adjustments need to be made to data store addresses */
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
/* Transfer the memory block */
|
||||
while (uCount-- != 0) {
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
val = InWordDsp(DSP_MsaDataDSISHigh);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
if(put_user(val, pusBuffer++))
|
||||
return -EFAULT;
|
||||
|
||||
PaceMsaAccess(usDspBaseIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
|
||||
void __user *pvBuffer, unsigned uCount,
|
||||
unsigned long ulDSPAddr)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short __user *pusBuffer = pvBuffer;
|
||||
unsigned short val;
|
||||
|
||||
/* Set the initial MSA address. No adjustments need to be made to data store addresses */
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
/* Transfer the memory block */
|
||||
while (uCount-- != 0) {
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
val = InWordDsp(DSP_ReadAndClear);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
if(put_user(val, pusBuffer++))
|
||||
return -EFAULT;
|
||||
|
||||
PaceMsaAccess(usDspBaseIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short __user *pusBuffer = pvBuffer;
|
||||
|
||||
/* Set the initial MSA address. No adjustments need to be made to data store addresses */
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
/* Transfer the memory block */
|
||||
while (uCount-- != 0) {
|
||||
unsigned short val;
|
||||
if(get_user(val, pusBuffer++))
|
||||
return -EFAULT;
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaDataDSISHigh, val);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
PaceMsaAccess(usDspBaseIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short __user *pusBuffer = pvBuffer;
|
||||
|
||||
/*
|
||||
* Set the initial MSA address. To convert from an instruction store
|
||||
* address to an MSA address
|
||||
* shift the address two bits to the left and set bit 22
|
||||
*/
|
||||
ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
/* Transfer the memory block */
|
||||
while (uCount-- != 0) {
|
||||
unsigned short val_lo, val_hi;
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
val_lo = InWordDsp(DSP_MsaDataISLow);
|
||||
val_hi = InWordDsp(DSP_MsaDataDSISHigh);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
if(put_user(val_lo, pusBuffer++))
|
||||
return -EFAULT;
|
||||
if(put_user(val_hi, pusBuffer++))
|
||||
return -EFAULT;
|
||||
|
||||
PaceMsaAccess(usDspBaseIO);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned short __user *pusBuffer = pvBuffer;
|
||||
|
||||
/*
|
||||
* Set the initial MSA address. To convert from an instruction store
|
||||
* address to an MSA address
|
||||
* shift the address two bits to the left and set bit 22
|
||||
*/
|
||||
ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
|
||||
OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
/* Transfer the memory block */
|
||||
while (uCount-- != 0) {
|
||||
unsigned short val_lo, val_hi;
|
||||
if(get_user(val_lo, pusBuffer++))
|
||||
return -EFAULT;
|
||||
if(get_user(val_hi, pusBuffer++))
|
||||
return -EFAULT;
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
OutWordDsp(DSP_MsaDataISLow, val_lo);
|
||||
OutWordDsp(DSP_MsaDataDSISHigh, val_hi);
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
PaceMsaAccess(usDspBaseIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
|
||||
unsigned short *pusIPCSource)
|
||||
{
|
||||
unsigned long flags;
|
||||
DSP_HBRIDGE_CONTROL rHBridgeControl;
|
||||
|
||||
/*
|
||||
* Disable DSP to PC interrupts, read the interrupt register,
|
||||
* clear the pending IPC bits, and reenable DSP to PC interrupts
|
||||
*/
|
||||
spin_lock_irqsave(&dsp_lock, flags);
|
||||
MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
|
||||
rHBridgeControl.EnableDspInt = false;
|
||||
OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
|
||||
|
||||
*pusIPCSource = InWordDsp(DSP_Interrupt);
|
||||
OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource));
|
||||
|
||||
rHBridgeControl.EnableDspInt = true;
|
||||
OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
|
||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,358 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* 3780i.h -- declarations for 3780i.c
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_3780I_H
|
||||
#define _LINUX_3780I_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
/* DSP I/O port offsets and definitions */
|
||||
#define DSP_IsaSlaveControl 0x0000 /* ISA slave control register */
|
||||
#define DSP_IsaSlaveStatus 0x0001 /* ISA slave status register */
|
||||
#define DSP_ConfigAddress 0x0002 /* General config address register */
|
||||
#define DSP_ConfigData 0x0003 /* General config data register */
|
||||
#define DSP_HBridgeControl 0x0002 /* HBridge control register */
|
||||
#define DSP_MsaAddrLow 0x0004 /* MSP System Address, low word */
|
||||
#define DSP_MsaAddrHigh 0x0006 /* MSP System Address, high word */
|
||||
#define DSP_MsaDataDSISHigh 0x0008 /* MSA data register: d-store word or high byte of i-store */
|
||||
#define DSP_MsaDataISLow 0x000A /* MSA data register: low word of i-store */
|
||||
#define DSP_ReadAndClear 0x000C /* MSA read and clear data register */
|
||||
#define DSP_Interrupt 0x000E /* Interrupt register (IPC source) */
|
||||
|
||||
typedef struct {
|
||||
unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */
|
||||
unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */
|
||||
unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */
|
||||
unsigned short Reserved:13; /* 0: Reserved */
|
||||
} DSP_ISA_SLAVE_CONTROL;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short EnableDspInt:1; /* RW: Enable DSP to X86 ISA interrupt 0=mask it, 1=enable it */
|
||||
unsigned short MemAutoInc:1; /* RW: Memory address auto increment, 0=disable, 1=enable */
|
||||
unsigned short IoAutoInc:1; /* RW: I/O address auto increment, 0=disable, 1=enable */
|
||||
unsigned short DiagnosticMode:1; /* RW: Disgnostic mode 0=nromal, 1=diagnostic mode */
|
||||
unsigned short IsaPacingTimer:12; /* R: ISA access pacing timer: count of core cycles stolen */
|
||||
} DSP_HBRIDGE_CONTROL;
|
||||
|
||||
|
||||
/* DSP register indexes used with the configuration register address (index) register */
|
||||
#define DSP_UartCfg1Index 0x0003 /* UART config register 1 */
|
||||
#define DSP_UartCfg2Index 0x0004 /* UART config register 2 */
|
||||
#define DSP_HBridgeCfg1Index 0x0007 /* HBridge config register 1 */
|
||||
#define DSP_HBridgeCfg2Index 0x0008 /* HBridge config register 2 */
|
||||
#define DSP_BusMasterCfg1Index 0x0009 /* ISA bus master config register 1 */
|
||||
#define DSP_BusMasterCfg2Index 0x000A /* ISA bus master config register 2 */
|
||||
#define DSP_IsaProtCfgIndex 0x000F /* ISA protocol control register */
|
||||
#define DSP_PowerMgCfgIndex 0x0010 /* Low poser suspend/resume enable */
|
||||
#define DSP_HBusTimerCfgIndex 0x0011 /* HBUS timer load value */
|
||||
|
||||
typedef struct {
|
||||
unsigned char IrqActiveLow:1; /* RW: IRQ active high or low: 0=high, 1=low */
|
||||
unsigned char IrqPulse:1; /* RW: IRQ pulse or level: 0=level, 1=pulse */
|
||||
unsigned char Irq:3; /* RW: IRQ selection */
|
||||
unsigned char BaseIO:2; /* RW: Base I/O selection */
|
||||
unsigned char Reserved:1; /* 0: Reserved */
|
||||
} DSP_UART_CFG_1;
|
||||
|
||||
typedef struct {
|
||||
unsigned char Enable:1; /* RW: Enable I/O and IRQ: 0=false, 1=true */
|
||||
unsigned char Reserved:7; /* 0: Reserved */
|
||||
} DSP_UART_CFG_2;
|
||||
|
||||
typedef struct {
|
||||
unsigned char IrqActiveLow:1; /* RW: IRQ active high=0 or low=1 */
|
||||
unsigned char IrqPulse:1; /* RW: IRQ pulse=1 or level=0 */
|
||||
unsigned char Irq:3; /* RW: IRQ selection */
|
||||
unsigned char AccessMode:1; /* RW: 16-bit register access method 0=byte, 1=word */
|
||||
unsigned char Reserved:2; /* 0: Reserved */
|
||||
} DSP_HBRIDGE_CFG_1;
|
||||
|
||||
typedef struct {
|
||||
unsigned char Enable:1; /* RW: enable I/O and IRQ: 0=false, 1=true */
|
||||
unsigned char Reserved:7; /* 0: Reserved */
|
||||
} DSP_HBRIDGE_CFG_2;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char Dma:3; /* RW: DMA channel selection */
|
||||
unsigned char NumTransfers:2; /* RW: Maximum # of transfers once being granted the ISA bus */
|
||||
unsigned char ReRequest:2; /* RW: Minimum delay between releasing the ISA bus and requesting it again */
|
||||
unsigned char MEMCS16:1; /* RW: ISA signal MEMCS16: 0=disabled, 1=enabled */
|
||||
} DSP_BUSMASTER_CFG_1;
|
||||
|
||||
typedef struct {
|
||||
unsigned char IsaMemCmdWidth:2; /* RW: ISA memory command width */
|
||||
unsigned char Reserved:6; /* 0: Reserved */
|
||||
} DSP_BUSMASTER_CFG_2;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char GateIOCHRDY:1; /* RW: Enable IOCHRDY gating: 0=false, 1=true */
|
||||
unsigned char Reserved:7; /* 0: Reserved */
|
||||
} DSP_ISA_PROT_CFG;
|
||||
|
||||
typedef struct {
|
||||
unsigned char Enable:1; /* RW: Enable low power suspend/resume 0=false, 1=true */
|
||||
unsigned char Reserved:7; /* 0: Reserved */
|
||||
} DSP_POWER_MGMT_CFG;
|
||||
|
||||
typedef struct {
|
||||
unsigned char LoadValue:8; /* RW: HBUS timer load value */
|
||||
} DSP_HBUS_TIMER_CFG;
|
||||
|
||||
|
||||
|
||||
/* DSP registers that exist in MSA I/O space */
|
||||
#define DSP_ChipID 0x80000000
|
||||
#define DSP_MspBootDomain 0x80000580
|
||||
#define DSP_LBusTimeoutDisable 0x80000580
|
||||
#define DSP_ClockControl_1 0x8000058A
|
||||
#define DSP_ClockControl_2 0x8000058C
|
||||
#define DSP_ChipReset 0x80000588
|
||||
#define DSP_GpioModeControl_15_8 0x80000082
|
||||
#define DSP_GpioDriverEnable_15_8 0x80000076
|
||||
#define DSP_GpioOutputData_15_8 0x80000072
|
||||
|
||||
typedef struct {
|
||||
unsigned short NMI:1; /* RW: non maskable interrupt */
|
||||
unsigned short Halt:1; /* RW: Halt MSP clock */
|
||||
unsigned short ResetCore:1; /* RW: Reset MSP core interface */
|
||||
unsigned short Reserved:13; /* 0: Reserved */
|
||||
} DSP_BOOT_DOMAIN;
|
||||
|
||||
typedef struct {
|
||||
unsigned short DisableTimeout:1; /* RW: Disable LBus timeout */
|
||||
unsigned short Reserved:15; /* 0: Reserved */
|
||||
} DSP_LBUS_TIMEOUT_DISABLE;
|
||||
|
||||
typedef struct {
|
||||
unsigned short Memory:1; /* RW: Reset memory interface */
|
||||
unsigned short SerialPort1:1; /* RW: Reset serial port 1 interface */
|
||||
unsigned short SerialPort2:1; /* RW: Reset serial port 2 interface */
|
||||
unsigned short SerialPort3:1; /* RW: Reset serial port 3 interface */
|
||||
unsigned short Gpio:1; /* RW: Reset GPIO interface */
|
||||
unsigned short Dma:1; /* RW: Reset DMA interface */
|
||||
unsigned short SoundBlaster:1; /* RW: Reset soundblaster interface */
|
||||
unsigned short Uart:1; /* RW: Reset UART interface */
|
||||
unsigned short Midi:1; /* RW: Reset MIDI interface */
|
||||
unsigned short IsaMaster:1; /* RW: Reset ISA master interface */
|
||||
unsigned short Reserved:6; /* 0: Reserved */
|
||||
} DSP_CHIP_RESET;
|
||||
|
||||
typedef struct {
|
||||
unsigned short N_Divisor:6; /* RW: (N) PLL output clock divisor */
|
||||
unsigned short Reserved1:2; /* 0: reserved */
|
||||
unsigned short M_Multiplier:6; /* RW: (M) PLL feedback clock multiplier */
|
||||
unsigned short Reserved2:2; /* 0: reserved */
|
||||
} DSP_CLOCK_CONTROL_1;
|
||||
|
||||
typedef struct {
|
||||
unsigned short PllBypass:1; /* RW: PLL Bypass */
|
||||
unsigned short Reserved:15; /* 0: Reserved */
|
||||
} DSP_CLOCK_CONTROL_2;
|
||||
|
||||
typedef struct {
|
||||
unsigned short Latch8:1;
|
||||
unsigned short Latch9:1;
|
||||
unsigned short Latch10:1;
|
||||
unsigned short Latch11:1;
|
||||
unsigned short Latch12:1;
|
||||
unsigned short Latch13:1;
|
||||
unsigned short Latch14:1;
|
||||
unsigned short Latch15:1;
|
||||
unsigned short Mask8:1;
|
||||
unsigned short Mask9:1;
|
||||
unsigned short Mask10:1;
|
||||
unsigned short Mask11:1;
|
||||
unsigned short Mask12:1;
|
||||
unsigned short Mask13:1;
|
||||
unsigned short Mask14:1;
|
||||
unsigned short Mask15:1;
|
||||
} DSP_GPIO_OUTPUT_DATA_15_8;
|
||||
|
||||
typedef struct {
|
||||
unsigned short Enable8:1;
|
||||
unsigned short Enable9:1;
|
||||
unsigned short Enable10:1;
|
||||
unsigned short Enable11:1;
|
||||
unsigned short Enable12:1;
|
||||
unsigned short Enable13:1;
|
||||
unsigned short Enable14:1;
|
||||
unsigned short Enable15:1;
|
||||
unsigned short Mask8:1;
|
||||
unsigned short Mask9:1;
|
||||
unsigned short Mask10:1;
|
||||
unsigned short Mask11:1;
|
||||
unsigned short Mask12:1;
|
||||
unsigned short Mask13:1;
|
||||
unsigned short Mask14:1;
|
||||
unsigned short Mask15:1;
|
||||
} DSP_GPIO_DRIVER_ENABLE_15_8;
|
||||
|
||||
typedef struct {
|
||||
unsigned short GpioMode8:2;
|
||||
unsigned short GpioMode9:2;
|
||||
unsigned short GpioMode10:2;
|
||||
unsigned short GpioMode11:2;
|
||||
unsigned short GpioMode12:2;
|
||||
unsigned short GpioMode13:2;
|
||||
unsigned short GpioMode14:2;
|
||||
unsigned short GpioMode15:2;
|
||||
} DSP_GPIO_MODE_15_8;
|
||||
|
||||
/* Component masks that are defined in dspmgr.h */
|
||||
#define MW_ADC_MASK 0x0001
|
||||
#define MW_AIC2_MASK 0x0006
|
||||
#define MW_MIDI_MASK 0x0008
|
||||
#define MW_CDDAC_MASK 0x8001
|
||||
#define MW_AIC1_MASK 0xE006
|
||||
#define MW_UART_MASK 0xE00A
|
||||
#define MW_ACI_MASK 0xE00B
|
||||
|
||||
/*
|
||||
* Definition of 3780i configuration structure. Unless otherwise stated,
|
||||
* these values are provided as input to the 3780i support layer. At present,
|
||||
* the only values maintained by the 3780i support layer are the saved UART
|
||||
* registers.
|
||||
*/
|
||||
struct dsp_3780i_config_settings {
|
||||
|
||||
/* Location of base configuration register */
|
||||
unsigned short usBaseConfigIO;
|
||||
|
||||
/* Enables for various DSP components */
|
||||
int bDSPEnabled;
|
||||
int bModemEnabled;
|
||||
int bInterruptClaimed;
|
||||
|
||||
/* IRQ, DMA, and Base I/O addresses for various DSP components */
|
||||
unsigned short usDspIrq;
|
||||
unsigned short usDspDma;
|
||||
unsigned short usDspBaseIO;
|
||||
unsigned short usUartIrq;
|
||||
unsigned short usUartBaseIO;
|
||||
|
||||
/* IRQ modes for various DSP components */
|
||||
int bDspIrqActiveLow;
|
||||
int bUartIrqActiveLow;
|
||||
int bDspIrqPulse;
|
||||
int bUartIrqPulse;
|
||||
|
||||
/* Card abilities */
|
||||
unsigned uIps;
|
||||
unsigned uDStoreSize;
|
||||
unsigned uIStoreSize;
|
||||
unsigned uDmaBandwidth;
|
||||
|
||||
/* Adapter specific 3780i settings */
|
||||
unsigned short usNumTransfers;
|
||||
unsigned short usReRequest;
|
||||
int bEnableMEMCS16;
|
||||
unsigned short usIsaMemCmdWidth;
|
||||
int bGateIOCHRDY;
|
||||
int bEnablePwrMgmt;
|
||||
unsigned short usHBusTimerLoadValue;
|
||||
int bDisableLBusTimeout;
|
||||
unsigned short usN_Divisor;
|
||||
unsigned short usM_Multiplier;
|
||||
int bPllBypass;
|
||||
unsigned short usChipletEnable; /* Used with the chip reset register to enable specific chiplets */
|
||||
|
||||
/* Saved UART registers. These are maintained by the 3780i support layer. */
|
||||
int bUartSaved; /* True after a successful save of the UART registers */
|
||||
unsigned char ucIER; /* Interrupt enable register */
|
||||
unsigned char ucFCR; /* FIFO control register */
|
||||
unsigned char ucLCR; /* Line control register */
|
||||
unsigned char ucMCR; /* Modem control register */
|
||||
unsigned char ucSCR; /* Scratch register */
|
||||
unsigned char ucDLL; /* Divisor latch, low byte */
|
||||
unsigned char ucDLM; /* Divisor latch, high byte */
|
||||
};
|
||||
|
||||
|
||||
/* 3780i support functions */
|
||||
int dsp3780I_EnableDSP(struct dsp_3780i_config_settings *pSettings,
|
||||
unsigned short *pIrqMap,
|
||||
unsigned short *pDmaMap);
|
||||
int dsp3780I_DisableDSP(struct dsp_3780i_config_settings *pSettings);
|
||||
int dsp3780I_Reset(struct dsp_3780i_config_settings *pSettings);
|
||||
int dsp3780I_Run(struct dsp_3780i_config_settings *pSettings);
|
||||
int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr);
|
||||
int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
|
||||
void __user *pvBuffer, unsigned uCount,
|
||||
unsigned long ulDSPAddr);
|
||||
int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr);
|
||||
int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr);
|
||||
int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
|
||||
unsigned uCount, unsigned long ulDSPAddr);
|
||||
unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
|
||||
unsigned long ulMsaAddr);
|
||||
void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
|
||||
unsigned long ulMsaAddr, unsigned short usValue);
|
||||
int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
|
||||
unsigned short *pusIPCSource);
|
||||
|
||||
/* I/O port access macros */
|
||||
#define MKWORD(var) (*((unsigned short *)(&var)))
|
||||
#define MKBYTE(var) (*((unsigned char *)(&var)))
|
||||
|
||||
#define WriteMsaCfg(addr,value) dsp3780I_WriteMsaCfg(usDspBaseIO,addr,value)
|
||||
#define ReadMsaCfg(addr) dsp3780I_ReadMsaCfg(usDspBaseIO,addr)
|
||||
#define WriteGenCfg(index,value) dsp3780I_WriteGenCfg(usDspBaseIO,index,value)
|
||||
#define ReadGenCfg(index) dsp3780I_ReadGenCfg(usDspBaseIO,index)
|
||||
|
||||
#define InWordDsp(index) inw(usDspBaseIO+index)
|
||||
#define InByteDsp(index) inb(usDspBaseIO+index)
|
||||
#define OutWordDsp(index,value) outw(value,usDspBaseIO+index)
|
||||
#define OutByteDsp(index,value) outb(value,usDspBaseIO+index)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Makefile for ACP Modem (Mwave).
|
||||
#
|
||||
# See the README file in this directory for more info. <paulsch@us.ibm.com>
|
||||
#
|
||||
|
||||
obj-$(CONFIG_MWAVE) += mwave.o
|
||||
|
||||
mwave-y := mwavedd.o smapi.o tp3780i.o 3780i.o
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
Module options
|
||||
--------------
|
||||
|
||||
The mwave module takes the following options. Note that these options
|
||||
are not saved by the BIOS and so do not persist after unload and reload.
|
||||
|
||||
mwave_3780i_irq=5/7/10/11/15
|
||||
If the dsp irq has not been setup and stored in bios by the
|
||||
thinkpad configuration utility then this parameter allows the
|
||||
irq used by the dsp to be configured.
|
||||
|
||||
mwave_3780i_io=0x130/0x350/0x0070/0xDB0
|
||||
If the dsp io range has not been setup and stored in bios by the
|
||||
thinkpad configuration utility then this parameter allows the
|
||||
io range used by the dsp to be configured.
|
||||
|
||||
mwave_uart_irq=3/4
|
||||
If the mwave's uart irq has not been setup and stored in bios by the
|
||||
thinkpad configuration utility then this parameter allows the
|
||||
irq used by the mwave uart to be configured.
|
||||
|
||||
mwave_uart_io=0x3f8/0x2f8/0x3E8/0x2E8
|
||||
If the uart io range has not been setup and stored in bios by the
|
||||
thinkpad configuration utility then this parameter allows the
|
||||
io range used by the mwave uart to be configured.
|
||||
|
||||
Example to enable the 3780i DSP using ttyS1 resources:
|
||||
|
||||
insmod mwave mwave_3780i_irq=10 mwave_3780i_io=0x0130 mwave_uart_irq=3 mwave_uart_io=0x2f8
|
||||
|
||||
Accessing the driver
|
||||
--------------------
|
||||
|
||||
You must also create a node for the driver:
|
||||
mkdir -p /dev/modems
|
||||
mknod --mode=660 /dev/modems/mwave c 10 219
|
||||
|
||||
|
|
@ -1,432 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* mwavedd.c -- mwave device driver
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "mwavedd: " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/nospec.h>
|
||||
#include "smapi.h"
|
||||
#include "mwavedd.h"
|
||||
#include "3780i.h"
|
||||
#include "tp3780i.h"
|
||||
|
||||
MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
|
||||
MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
* These parameters support the setting of MWave resources. Note that no
|
||||
* checks are made against other devices (ie. superio) for conflicts.
|
||||
* We'll depend on users using the tpctl utility to do that for now
|
||||
*/
|
||||
static DEFINE_MUTEX(mwave_mutex);
|
||||
int mwave_3780i_irq = 0;
|
||||
int mwave_3780i_io = 0;
|
||||
int mwave_uart_irq = 0;
|
||||
int mwave_uart_io = 0;
|
||||
module_param_hw(mwave_3780i_irq, int, irq, 0);
|
||||
module_param_hw(mwave_3780i_io, int, ioport, 0);
|
||||
module_param_hw(mwave_uart_irq, int, irq, 0);
|
||||
module_param_hw(mwave_uart_io, int, ioport, 0);
|
||||
|
||||
struct mwave_device_data mwave_s_mdd;
|
||||
|
||||
static long mwave_ioctl(struct file *file, unsigned int iocmd,
|
||||
unsigned long ioarg)
|
||||
{
|
||||
unsigned int retval = 0;
|
||||
struct mwave_device_data *pDrvData = &mwave_s_mdd;
|
||||
void __user *arg = (void __user *)ioarg;
|
||||
|
||||
switch (iocmd) {
|
||||
|
||||
case IOCTL_MW_RESET:
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_ResetDSP(&pDrvData->rBDData);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
break;
|
||||
|
||||
case IOCTL_MW_RUN:
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_StartDSP(&pDrvData->rBDData);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
break;
|
||||
|
||||
case IOCTL_MW_DSP_ABILITIES: {
|
||||
struct mw_abilities rAbilities;
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_QueryAbilities(&pDrvData->rBDData,
|
||||
&rAbilities);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
if (retval == 0) {
|
||||
if (copy_to_user(arg, &rAbilities, sizeof(rAbilities)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_READ_DATA:
|
||||
case IOCTL_MW_READCLEAR_DATA: {
|
||||
struct mw_readwrite rReadData;
|
||||
unsigned short __user *pusBuffer = NULL;
|
||||
|
||||
if( copy_from_user(&rReadData, arg,
|
||||
sizeof(struct mw_readwrite)) )
|
||||
return -EFAULT;
|
||||
pusBuffer = (unsigned short __user *) (rReadData.pBuf);
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
|
||||
iocmd,
|
||||
pusBuffer,
|
||||
rReadData.ulDataLength,
|
||||
rReadData.usDspAddress);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_READ_INST: {
|
||||
struct mw_readwrite rReadData;
|
||||
unsigned short __user *pusBuffer = NULL;
|
||||
|
||||
if (copy_from_user(&rReadData, arg, sizeof(rReadData)))
|
||||
return -EFAULT;
|
||||
pusBuffer = (unsigned short __user *) (rReadData.pBuf);
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
|
||||
iocmd, pusBuffer,
|
||||
rReadData.ulDataLength / 2,
|
||||
rReadData.usDspAddress);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_WRITE_DATA: {
|
||||
struct mw_readwrite rWriteData;
|
||||
unsigned short __user *pusBuffer = NULL;
|
||||
|
||||
if (copy_from_user(&rWriteData, arg, sizeof(rWriteData)))
|
||||
return -EFAULT;
|
||||
pusBuffer = (unsigned short __user *) (rWriteData.pBuf);
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
|
||||
iocmd, pusBuffer,
|
||||
rWriteData.ulDataLength,
|
||||
rWriteData.usDspAddress);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_WRITE_INST: {
|
||||
struct mw_readwrite rWriteData;
|
||||
unsigned short __user *pusBuffer = NULL;
|
||||
|
||||
if (copy_from_user(&rWriteData, arg, sizeof(rWriteData)))
|
||||
return -EFAULT;
|
||||
pusBuffer = (unsigned short __user *)(rWriteData.pBuf);
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData,
|
||||
iocmd, pusBuffer,
|
||||
rWriteData.ulDataLength,
|
||||
rWriteData.usDspAddress);
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_REGISTER_IPC: {
|
||||
unsigned int ipcnum = (unsigned int) ioarg;
|
||||
|
||||
if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
|
||||
pr_err("%s: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n",
|
||||
__func__, ipcnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
ipcnum = array_index_nospec(ipcnum,
|
||||
ARRAY_SIZE(pDrvData->IPCs));
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
pDrvData->IPCs[ipcnum].bIsHere = false;
|
||||
pDrvData->IPCs[ipcnum].bIsEnabled = true;
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_GET_IPC: {
|
||||
unsigned int ipcnum = (unsigned int) ioarg;
|
||||
|
||||
if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
|
||||
pr_err("%s: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", __func__,
|
||||
ipcnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
ipcnum = array_index_nospec(ipcnum,
|
||||
ARRAY_SIZE(pDrvData->IPCs));
|
||||
|
||||
mutex_lock(&mwave_mutex);
|
||||
if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
|
||||
add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
|
||||
pDrvData->IPCs[ipcnum].bIsHere = true;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
/* check whether an event was signalled by */
|
||||
/* the interrupt handler while we were gone */
|
||||
if (pDrvData->IPCs[ipcnum].usIntCount == 1) { /* first int has occurred (race condition) */
|
||||
pDrvData->IPCs[ipcnum].usIntCount = 2; /* first int has been handled */
|
||||
} else { /* either 1st int has not yet occurred, or we have already handled the first int */
|
||||
schedule();
|
||||
if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
|
||||
pDrvData->IPCs[ipcnum].usIntCount = 2;
|
||||
}
|
||||
}
|
||||
pDrvData->IPCs[ipcnum].bIsHere = false;
|
||||
remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
}
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_MW_UNREGISTER_IPC: {
|
||||
unsigned int ipcnum = (unsigned int) ioarg;
|
||||
|
||||
if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
|
||||
pr_err("%s: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n",
|
||||
__func__, ipcnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
ipcnum = array_index_nospec(ipcnum,
|
||||
ARRAY_SIZE(pDrvData->IPCs));
|
||||
mutex_lock(&mwave_mutex);
|
||||
if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
|
||||
pDrvData->IPCs[ipcnum].bIsEnabled = false;
|
||||
if (pDrvData->IPCs[ipcnum].bIsHere == true) {
|
||||
wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&mwave_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTTY;
|
||||
} /* switch */
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int register_serial_portandirq(unsigned int port, int irq)
|
||||
{
|
||||
struct uart_8250_port uart;
|
||||
|
||||
switch ( port ) {
|
||||
case 0x3f8:
|
||||
case 0x2f8:
|
||||
case 0x3e8:
|
||||
case 0x2e8:
|
||||
/* OK */
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Error: Illegal port %x\n", __func__, port);
|
||||
return -1;
|
||||
} /* switch */
|
||||
/* port is okay */
|
||||
|
||||
switch ( irq ) {
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 7:
|
||||
/* OK */
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Error: Illegal irq %x\n", __func__, irq);
|
||||
return -1;
|
||||
} /* switch */
|
||||
/* irq is okay */
|
||||
|
||||
memset(&uart, 0, sizeof(uart));
|
||||
|
||||
uart.port.uartclk = 1843200;
|
||||
uart.port.iobase = port;
|
||||
uart.port.irq = irq;
|
||||
uart.port.iotype = UPIO_PORT;
|
||||
uart.port.flags = UPF_SHARE_IRQ;
|
||||
return serial8250_register_8250_port(&uart);
|
||||
}
|
||||
|
||||
static const struct file_operations mwave_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = mwave_ioctl,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops };
|
||||
|
||||
/*
|
||||
* mwave_init is called on module load
|
||||
*
|
||||
* mwave_exit is called on module unload
|
||||
* mwave_exit is also used to clean up after an aborted mwave_init
|
||||
*/
|
||||
static void mwave_exit(void)
|
||||
{
|
||||
struct mwave_device_data *pDrvData = &mwave_s_mdd;
|
||||
|
||||
if ( pDrvData->sLine >= 0 ) {
|
||||
serial8250_unregister_port(pDrvData->sLine);
|
||||
}
|
||||
if (pDrvData->bMwaveDevRegistered) {
|
||||
misc_deregister(&mwave_misc_dev);
|
||||
}
|
||||
if (pDrvData->bDSPEnabled) {
|
||||
tp3780I_DisableDSP(&pDrvData->rBDData);
|
||||
}
|
||||
if (pDrvData->bResourcesClaimed) {
|
||||
tp3780I_ReleaseResources(&pDrvData->rBDData);
|
||||
}
|
||||
if (pDrvData->bBDInitialized) {
|
||||
tp3780I_Cleanup(&pDrvData->rBDData);
|
||||
}
|
||||
}
|
||||
|
||||
module_exit(mwave_exit);
|
||||
|
||||
static int __init mwave_init(void)
|
||||
{
|
||||
int i;
|
||||
int retval = 0;
|
||||
struct mwave_device_data *pDrvData = &mwave_s_mdd;
|
||||
|
||||
memset(&mwave_s_mdd, 0, sizeof(mwave_s_mdd));
|
||||
|
||||
pDrvData->bBDInitialized = false;
|
||||
pDrvData->bResourcesClaimed = false;
|
||||
pDrvData->bDSPEnabled = false;
|
||||
pDrvData->bDSPReset = false;
|
||||
pDrvData->bMwaveDevRegistered = false;
|
||||
pDrvData->sLine = -1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pDrvData->IPCs); i++) {
|
||||
pDrvData->IPCs[i].bIsEnabled = false;
|
||||
pDrvData->IPCs[i].bIsHere = false;
|
||||
pDrvData->IPCs[i].usIntCount = 0; /* no ints received yet */
|
||||
init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue);
|
||||
}
|
||||
|
||||
retval = tp3780I_InitializeBoardData(&pDrvData->rBDData);
|
||||
if (retval) {
|
||||
pr_err("%s: Error: Failed to initialize board data\n", __func__);
|
||||
goto cleanup_error;
|
||||
}
|
||||
pDrvData->bBDInitialized = true;
|
||||
|
||||
retval = tp3780I_CalcResources(&pDrvData->rBDData);
|
||||
if (retval) {
|
||||
pr_err("%s: Error: Failed to calculate resources\n", __func__);
|
||||
goto cleanup_error;
|
||||
}
|
||||
|
||||
retval = tp3780I_ClaimResources(&pDrvData->rBDData);
|
||||
if (retval) {
|
||||
pr_err("%s: Error: Failed to claim resources\n", __func__);
|
||||
goto cleanup_error;
|
||||
}
|
||||
pDrvData->bResourcesClaimed = true;
|
||||
|
||||
retval = tp3780I_EnableDSP(&pDrvData->rBDData);
|
||||
if (retval) {
|
||||
pr_err("%s: Error: Failed to enable DSP\n", __func__);
|
||||
goto cleanup_error;
|
||||
}
|
||||
pDrvData->bDSPEnabled = true;
|
||||
|
||||
if (misc_register(&mwave_misc_dev) < 0) {
|
||||
pr_err("%s: Error: Failed to register misc device\n", __func__);
|
||||
goto cleanup_error;
|
||||
}
|
||||
pDrvData->bMwaveDevRegistered = true;
|
||||
|
||||
pDrvData->sLine = register_serial_portandirq(
|
||||
pDrvData->rBDData.rDspSettings.usUartBaseIO,
|
||||
pDrvData->rBDData.rDspSettings.usUartIrq
|
||||
);
|
||||
if (pDrvData->sLine < 0) {
|
||||
pr_err("%s: Error: Failed to register serial driver\n", __func__);
|
||||
goto cleanup_error;
|
||||
}
|
||||
/* uart is registered */
|
||||
|
||||
/* SUCCESS! */
|
||||
return 0;
|
||||
|
||||
cleanup_error:
|
||||
pr_err("%s: Error: Failed to initialize\n", __func__);
|
||||
mwave_exit(); /* clean up */
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
module_init(mwave_init);
|
||||
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* mwavedd.h -- declarations for mwave device driver
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MWAVEDD_H
|
||||
#define _LINUX_MWAVEDD_H
|
||||
#include "3780i.h"
|
||||
#include "tp3780i.h"
|
||||
#include "smapi.h"
|
||||
#include "mwavepub.h"
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
extern int mwave_3780i_irq;
|
||||
extern int mwave_3780i_io;
|
||||
extern int mwave_uart_irq;
|
||||
extern int mwave_uart_io;
|
||||
|
||||
struct mwave_ipc {
|
||||
unsigned short usIntCount; /* 0=none, 1=first, 2=greater than 1st */
|
||||
bool bIsEnabled;
|
||||
bool bIsHere;
|
||||
/* entry spin lock */
|
||||
wait_queue_head_t ipc_wait_queue;
|
||||
};
|
||||
|
||||
struct mwave_device_data {
|
||||
struct thinkpad_bd_data rBDData; /* board driver's data area */
|
||||
unsigned long ulIPCSource_ISR; /* IPC source bits for recently processed intr, set during ISR processing */
|
||||
unsigned long ulIPCSource_DPC; /* IPC source bits for recently processed intr, set during DPC processing */
|
||||
bool bBDInitialized;
|
||||
bool bResourcesClaimed;
|
||||
bool bDSPEnabled;
|
||||
bool bDSPReset;
|
||||
struct mwave_ipc IPCs[16];
|
||||
bool bMwaveDevRegistered;
|
||||
short sLine;
|
||||
int nr_registered_attrs;
|
||||
int device_registered;
|
||||
|
||||
};
|
||||
|
||||
extern struct mwave_device_data mwave_s_mdd;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* mwavepub.h -- PUBLIC declarations for the mwave driver
|
||||
* and applications using it
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MWAVEPUB_H
|
||||
#define _LINUX_MWAVEPUB_H
|
||||
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
|
||||
struct mw_abilities {
|
||||
unsigned long instr_per_sec;
|
||||
unsigned long data_size;
|
||||
unsigned long inst_size;
|
||||
unsigned long bus_dma_bw;
|
||||
unsigned short uart_enable;
|
||||
short component_count;
|
||||
unsigned long component_list[7];
|
||||
char mwave_os_name[16];
|
||||
char bios_task_name[16];
|
||||
};
|
||||
|
||||
|
||||
struct mw_readwrite {
|
||||
unsigned short usDspAddress; /* The dsp address */
|
||||
unsigned long ulDataLength; /* The size in bytes of the data or user buffer */
|
||||
void __user *pBuf; /* Input:variable sized buffer */
|
||||
};
|
||||
|
||||
#define IOCTL_MW_RESET _IO(MWAVE_MINOR,1)
|
||||
#define IOCTL_MW_RUN _IO(MWAVE_MINOR,2)
|
||||
#define IOCTL_MW_DSP_ABILITIES _IOR(MWAVE_MINOR,3,struct mw_abilities)
|
||||
#define IOCTL_MW_READ_DATA _IOR(MWAVE_MINOR,4,struct mw_readwrite)
|
||||
#define IOCTL_MW_READCLEAR_DATA _IOR(MWAVE_MINOR,5,struct mw_readwrite)
|
||||
#define IOCTL_MW_READ_INST _IOR(MWAVE_MINOR,6,struct mw_readwrite)
|
||||
#define IOCTL_MW_WRITE_DATA _IOW(MWAVE_MINOR,7,struct mw_readwrite)
|
||||
#define IOCTL_MW_WRITE_INST _IOW(MWAVE_MINOR,8,struct mw_readwrite)
|
||||
#define IOCTL_MW_REGISTER_IPC _IOW(MWAVE_MINOR,9,int)
|
||||
#define IOCTL_MW_UNREGISTER_IPC _IOW(MWAVE_MINOR,10,int)
|
||||
#define IOCTL_MW_GET_IPC _IOW(MWAVE_MINOR,11,int)
|
||||
#define IOCTL_MW_TRACE _IOR(MWAVE_MINOR,12,struct mw_readwrite)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,404 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* smapi.c -- SMAPI interface routines
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "smapi: " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mc146818rtc.h> /* CMOS defines */
|
||||
#include "smapi.h"
|
||||
#include "mwavedd.h"
|
||||
|
||||
static unsigned short g_usSmapiPort = 0;
|
||||
|
||||
|
||||
static int smapi_request(unsigned short inBX, unsigned short inCX,
|
||||
unsigned short inDI, unsigned short inSI,
|
||||
unsigned short *outAX, unsigned short *outBX,
|
||||
unsigned short *outCX, unsigned short *outDX,
|
||||
unsigned short *outDI, unsigned short *outSI)
|
||||
{
|
||||
unsigned short myoutAX = 2, *pmyoutAX = &myoutAX;
|
||||
unsigned short myoutBX = 3, *pmyoutBX = &myoutBX;
|
||||
unsigned short myoutCX = 4, *pmyoutCX = &myoutCX;
|
||||
unsigned short myoutDX = 5, *pmyoutDX = &myoutDX;
|
||||
unsigned short myoutDI = 6, *pmyoutDI = &myoutDI;
|
||||
unsigned short myoutSI = 7, *pmyoutSI = &myoutSI;
|
||||
unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK;
|
||||
unsigned int inBXCX = (inBX << 16) | inCX;
|
||||
unsigned int inDISI = (inDI << 16) | inSI;
|
||||
|
||||
__asm__ __volatile__("movw $0x5380,%%ax\n\t"
|
||||
"movl %7,%%ebx\n\t"
|
||||
"shrl $16, %%ebx\n\t"
|
||||
"movw %7,%%cx\n\t"
|
||||
"movl %8,%%edi\n\t"
|
||||
"shrl $16,%%edi\n\t"
|
||||
"movw %8,%%si\n\t"
|
||||
"movw %9,%%dx\n\t"
|
||||
"out %%al,%%dx\n\t"
|
||||
"out %%al,$0x4F\n\t"
|
||||
"cmpb $0x53,%%ah\n\t"
|
||||
"je 2f\n\t"
|
||||
"1:\n\t"
|
||||
"orb %%ah,%%ah\n\t"
|
||||
"jnz 2f\n\t"
|
||||
"movw %%ax,%0\n\t"
|
||||
"movw %%bx,%1\n\t"
|
||||
"movw %%cx,%2\n\t"
|
||||
"movw %%dx,%3\n\t"
|
||||
"movw %%di,%4\n\t"
|
||||
"movw %%si,%5\n\t"
|
||||
"movw $1,%6\n\t"
|
||||
"2:\n\t":"=m"(*(unsigned short *) pmyoutAX),
|
||||
"=m"(*(unsigned short *) pmyoutBX),
|
||||
"=m"(*(unsigned short *) pmyoutCX),
|
||||
"=m"(*(unsigned short *) pmyoutDX),
|
||||
"=m"(*(unsigned short *) pmyoutDI),
|
||||
"=m"(*(unsigned short *) pmyoutSI),
|
||||
"=m"(*(unsigned short *) pusSmapiOK)
|
||||
:"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort)
|
||||
:"%eax", "%ebx", "%ecx", "%edx", "%edi",
|
||||
"%esi");
|
||||
|
||||
*outAX = myoutAX;
|
||||
*outBX = myoutBX;
|
||||
*outCX = myoutCX;
|
||||
*outDX = myoutDX;
|
||||
*outDI = myoutDI;
|
||||
*outSI = myoutSI;
|
||||
|
||||
return usSmapiOK == 1 ? 0 : -EIO;
|
||||
}
|
||||
|
||||
|
||||
int smapi_query_DSP_cfg(struct smapi_dsp_settings *pSettings)
|
||||
{
|
||||
int bRC;
|
||||
unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
|
||||
static const unsigned short ausDspBases[] = {
|
||||
0x0030, 0x4E30, 0x8E30, 0xCE30,
|
||||
0x0130, 0x0350, 0x0070, 0x0DB0 };
|
||||
static const unsigned short ausUartBases[] = {
|
||||
0x03F8, 0x02F8, 0x03E8, 0x02E8 };
|
||||
|
||||
bRC = smapi_request(0x1802, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) {
|
||||
pr_err("%s: Error: Could not get DSP Settings. Aborting.\n", __func__);
|
||||
return bRC;
|
||||
}
|
||||
|
||||
pSettings->bDSPPresent = ((usBX & 0x0100) != 0);
|
||||
pSettings->bDSPEnabled = ((usCX & 0x0001) != 0);
|
||||
pSettings->usDspIRQ = usSI & 0x00FF;
|
||||
pSettings->usDspDMA = (usSI & 0xFF00) >> 8;
|
||||
if ((usDI & 0x00FF) < ARRAY_SIZE(ausDspBases)) {
|
||||
pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF];
|
||||
} else {
|
||||
pSettings->usDspBaseIO = 0;
|
||||
}
|
||||
|
||||
/* check for illegal values */
|
||||
if ( pSettings->usDspBaseIO == 0 )
|
||||
pr_err("%s: Worry: DSP base I/O address is 0\n", __func__);
|
||||
if ( pSettings->usDspIRQ == 0 )
|
||||
pr_err("%s: Worry: DSP IRQ line is 0\n", __func__);
|
||||
|
||||
bRC = smapi_request(0x1804, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) {
|
||||
pr_err("%s: Error: Could not get DSP modem settings. Aborting.\n", __func__);
|
||||
return bRC;
|
||||
}
|
||||
|
||||
pSettings->bModemEnabled = ((usCX & 0x0001) != 0);
|
||||
pSettings->usUartIRQ = usSI & 0x000F;
|
||||
if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) {
|
||||
pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8];
|
||||
} else {
|
||||
pSettings->usUartBaseIO = 0;
|
||||
}
|
||||
|
||||
/* check for illegal values */
|
||||
if ( pSettings->usUartBaseIO == 0 )
|
||||
pr_err("%s: Worry: UART base I/O address is 0\n", __func__);
|
||||
if ( pSettings->usUartIRQ == 0 )
|
||||
pr_err("%s: Worry: UART IRQ line is 0\n", __func__);
|
||||
|
||||
return bRC;
|
||||
}
|
||||
|
||||
|
||||
int smapi_set_DSP_cfg(void)
|
||||
{
|
||||
int bRC = -EIO;
|
||||
int i;
|
||||
unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
|
||||
static const unsigned short ausDspBases[] = {
|
||||
0x0030, 0x4E30, 0x8E30, 0xCE30,
|
||||
0x0130, 0x0350, 0x0070, 0x0DB0 };
|
||||
static const unsigned short ausUartBases[] = {
|
||||
0x03F8, 0x02F8, 0x03E8, 0x02E8 };
|
||||
static const unsigned short ausDspIrqs[] = {
|
||||
5, 7, 10, 11, 15 };
|
||||
static const unsigned short ausUartIrqs[] = {
|
||||
3, 4 };
|
||||
|
||||
unsigned short dspio_index = 0, uartio_index = 0;
|
||||
|
||||
if (mwave_3780i_io) {
|
||||
for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) {
|
||||
if (mwave_3780i_io == ausDspBases[i])
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(ausDspBases)) {
|
||||
pr_err("%s: Error: Invalid mwave_3780i_io address %x. Aborting.\n",
|
||||
__func__, mwave_3780i_io);
|
||||
return bRC;
|
||||
}
|
||||
dspio_index = i;
|
||||
}
|
||||
|
||||
if (mwave_3780i_irq) {
|
||||
for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) {
|
||||
if (mwave_3780i_irq == ausDspIrqs[i])
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(ausDspIrqs)) {
|
||||
pr_err("%s: Error: Invalid mwave_3780i_irq %x. Aborting.\n", __func__,
|
||||
mwave_3780i_irq);
|
||||
return bRC;
|
||||
}
|
||||
}
|
||||
|
||||
if (mwave_uart_io) {
|
||||
for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) {
|
||||
if (mwave_uart_io == ausUartBases[i])
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(ausUartBases)) {
|
||||
pr_err("%s: Error: Invalid mwave_uart_io address %x. Aborting.\n", __func__,
|
||||
mwave_uart_io);
|
||||
return bRC;
|
||||
}
|
||||
uartio_index = i;
|
||||
}
|
||||
|
||||
|
||||
if (mwave_uart_irq) {
|
||||
for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) {
|
||||
if (mwave_uart_irq == ausUartIrqs[i])
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(ausUartIrqs)) {
|
||||
pr_err("%s: Error: Invalid mwave_uart_irq %x. Aborting.\n", __func__,
|
||||
mwave_uart_irq);
|
||||
return bRC;
|
||||
}
|
||||
}
|
||||
|
||||
if (mwave_uart_irq || mwave_uart_io) {
|
||||
|
||||
/* Check serial port A */
|
||||
bRC = smapi_request(0x1402, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
/* bRC == 0 */
|
||||
if (usBX & 0x0100) { /* serial port A is present */
|
||||
if (usCX & 1) { /* serial port is enabled */
|
||||
if ((usSI & 0xFF) == mwave_uart_irq) {
|
||||
pr_err("%s: Serial port A irq %x conflicts with mwave_uart_irq %x\n",
|
||||
__func__, usSI & 0xFF, mwave_uart_irq);
|
||||
goto exit_conflict;
|
||||
} else {
|
||||
if ((usSI >> 8) == uartio_index) {
|
||||
pr_err("%s: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n",
|
||||
__func__, ausUartBases[usSI >> 8],
|
||||
ausUartBases[uartio_index]);
|
||||
goto exit_conflict;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check serial port B */
|
||||
bRC = smapi_request(0x1404, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
/* bRC == 0 */
|
||||
if (usBX & 0x0100) { /* serial port B is present */
|
||||
if (usCX & 1) { /* serial port is enabled */
|
||||
if ((usSI & 0xFF) == mwave_uart_irq) {
|
||||
pr_err("%s: Serial port B irq %x conflicts with mwave_uart_irq %x\n",
|
||||
__func__, usSI & 0xFF, mwave_uart_irq);
|
||||
goto exit_conflict;
|
||||
} else {
|
||||
if ((usSI >> 8) == uartio_index) {
|
||||
pr_err("%s: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n",
|
||||
__func__, ausUartBases[usSI >> 8],
|
||||
ausUartBases[uartio_index]);
|
||||
goto exit_conflict;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check IR port */
|
||||
bRC = smapi_request(0x1700, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
bRC = smapi_request(0x1704, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
/* bRC == 0 */
|
||||
if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
|
||||
if ((usCX & 0xff) == mwave_uart_irq) {
|
||||
pr_err("%s: IR port irq %x conflicts with mwave_uart_irq %x\n",
|
||||
__func__, usCX & 0xff, mwave_uart_irq);
|
||||
goto exit_conflict;
|
||||
} else {
|
||||
if ((usSI & 0xff) == uartio_index) {
|
||||
pr_err("%s: IR port base I/O address %x conflicts with mwave uart I/O %x\n",
|
||||
__func__, ausUartBases[usSI & 0xff],
|
||||
ausUartBases[uartio_index]);
|
||||
goto exit_conflict;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bRC = smapi_request(0x1802, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
|
||||
if (mwave_3780i_io) {
|
||||
usDI = dspio_index;
|
||||
}
|
||||
if (mwave_3780i_irq) {
|
||||
usSI = (usSI & 0xff00) | mwave_3780i_irq;
|
||||
}
|
||||
|
||||
bRC = smapi_request(0x1803, 0x0101, usDI, usSI,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
|
||||
bRC = smapi_request(0x1804, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
|
||||
if (mwave_uart_io) {
|
||||
usSI = (usSI & 0x00ff) | (uartio_index << 8);
|
||||
}
|
||||
if (mwave_uart_irq) {
|
||||
usSI = (usSI & 0xff00) | mwave_uart_irq;
|
||||
}
|
||||
bRC = smapi_request(0x1805, 0x0101, 0, usSI,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
|
||||
bRC = smapi_request(0x1802, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
|
||||
bRC = smapi_request(0x1804, 0x0000, 0, 0,
|
||||
&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
|
||||
if (bRC) goto exit_smapi_request_error;
|
||||
|
||||
/* normal exit: */
|
||||
return 0;
|
||||
|
||||
exit_conflict:
|
||||
/* Message has already been printed */
|
||||
return -EIO;
|
||||
|
||||
exit_smapi_request_error:
|
||||
pr_err("%s: exit on smapi_request error bRC %x\n", __func__, bRC);
|
||||
return bRC;
|
||||
}
|
||||
|
||||
|
||||
int smapi_set_DSP_power_state(bool bOn)
|
||||
{
|
||||
unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
|
||||
unsigned short usPowerFunction;
|
||||
|
||||
usPowerFunction = (bOn) ? 1 : 0;
|
||||
|
||||
return smapi_request(0x4901, 0x0000, 0, usPowerFunction, &usAX, &usBX, &usCX, &usDX, &usDI,
|
||||
&usSI);
|
||||
}
|
||||
|
||||
int smapi_init(void)
|
||||
{
|
||||
int retval = -EIO;
|
||||
unsigned short usSmapiID = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
usSmapiID = CMOS_READ(0x7C);
|
||||
usSmapiID |= (CMOS_READ(0x7D) << 8);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
if (usSmapiID == 0x5349) {
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
g_usSmapiPort = CMOS_READ(0x7E);
|
||||
g_usSmapiPort |= (CMOS_READ(0x7F) << 8);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
if (g_usSmapiPort == 0) {
|
||||
pr_err("%s: ERROR unable to read from SMAPI port\n", __func__);
|
||||
} else {
|
||||
retval = 0;
|
||||
//SmapiQuerySystemID();
|
||||
}
|
||||
} else {
|
||||
pr_err("%s: ERROR invalid usSmapiID\n", __func__);
|
||||
retval = -ENXIO;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* smapi.h -- declarations for SMAPI interface routines
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SMAPI_H
|
||||
#define _LINUX_SMAPI_H
|
||||
|
||||
struct smapi_dsp_settings {
|
||||
int bDSPPresent;
|
||||
int bDSPEnabled;
|
||||
int bModemEnabled;
|
||||
int bMIDIEnabled;
|
||||
int bSblstEnabled;
|
||||
unsigned short usDspIRQ;
|
||||
unsigned short usDspDMA;
|
||||
unsigned short usDspBaseIO;
|
||||
unsigned short usUartIRQ;
|
||||
unsigned short usUartBaseIO;
|
||||
unsigned short usMidiIRQ;
|
||||
unsigned short usMidiBaseIO;
|
||||
unsigned short usSndblstIRQ;
|
||||
unsigned short usSndblstDMA;
|
||||
unsigned short usSndblstBaseIO;
|
||||
};
|
||||
|
||||
int smapi_init(void);
|
||||
int smapi_query_DSP_cfg(struct smapi_dsp_settings *pSettings);
|
||||
int smapi_set_DSP_cfg(void);
|
||||
int smapi_set_DSP_power_state(bool bOn);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,477 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* tp3780i.c -- board driver for 3780i on ThinkPads
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "tp3780i: " fmt
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <asm/io.h>
|
||||
#include "smapi.h"
|
||||
#include "mwavedd.h"
|
||||
#include "tp3780i.h"
|
||||
#include "3780i.h"
|
||||
#include "mwavepub.h"
|
||||
|
||||
static unsigned short s_ausThinkpadIrqToField[16] =
|
||||
{ 0xFFFF, 0xFFFF, 0xFFFF, 0x0001, 0x0002, 0x0003, 0xFFFF, 0x0004,
|
||||
0xFFFF, 0xFFFF, 0x0005, 0x0006, 0xFFFF, 0xFFFF, 0xFFFF, 0x0007 };
|
||||
static unsigned short s_ausThinkpadDmaToField[8] =
|
||||
{ 0x0001, 0x0002, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0003, 0x0004 };
|
||||
static unsigned short s_numIrqs = 16, s_numDmas = 8;
|
||||
|
||||
|
||||
static void EnableSRAM(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
DSP_GPIO_OUTPUT_DATA_15_8 rGpioOutputData;
|
||||
DSP_GPIO_DRIVER_ENABLE_15_8 rGpioDriverEnable;
|
||||
DSP_GPIO_MODE_15_8 rGpioMode;
|
||||
|
||||
MKWORD(rGpioMode) = ReadMsaCfg(DSP_GpioModeControl_15_8);
|
||||
rGpioMode.GpioMode10 = 0;
|
||||
WriteMsaCfg(DSP_GpioModeControl_15_8, MKWORD(rGpioMode));
|
||||
|
||||
MKWORD(rGpioDriverEnable) = 0;
|
||||
rGpioDriverEnable.Enable10 = true;
|
||||
rGpioDriverEnable.Mask10 = true;
|
||||
WriteMsaCfg(DSP_GpioDriverEnable_15_8, MKWORD(rGpioDriverEnable));
|
||||
|
||||
MKWORD(rGpioOutputData) = 0;
|
||||
rGpioOutputData.Latch10 = 0;
|
||||
rGpioOutputData.Mask10 = true;
|
||||
WriteMsaCfg(DSP_GpioOutputData_15_8, MKWORD(rGpioOutputData));
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t UartInterrupt(int irq, void *dev_id)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t DspInterrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct mwave_device_data *pDrvData = &mwave_s_mdd;
|
||||
struct dsp_3780i_config_settings *pSettings = &pDrvData->rBDData.rDspSettings;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
unsigned short usIPCSource = 0, usIsolationMask, usPCNum;
|
||||
|
||||
if (dsp3780I_GetIPCSource(usDspBaseIO, &usIPCSource) == 0) {
|
||||
usIsolationMask = 1;
|
||||
for (usPCNum = 1; usPCNum <= 16; usPCNum++) {
|
||||
if (usIPCSource & usIsolationMask) {
|
||||
usIPCSource &= ~usIsolationMask;
|
||||
if (pDrvData->IPCs[usPCNum - 1].usIntCount == 0) {
|
||||
pDrvData->IPCs[usPCNum - 1].usIntCount = 1;
|
||||
}
|
||||
if (pDrvData->IPCs[usPCNum - 1].bIsEnabled == true) {
|
||||
wake_up_interruptible(&pDrvData->IPCs[usPCNum - 1].ipc_wait_queue);
|
||||
}
|
||||
}
|
||||
if (usIPCSource == 0)
|
||||
break;
|
||||
/* try next IPC */
|
||||
usIsolationMask = usIsolationMask << 1;
|
||||
}
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_InitializeBoardData(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
int retval = 0;
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
|
||||
pBDData->bDSPEnabled = false;
|
||||
pSettings->bInterruptClaimed = false;
|
||||
|
||||
retval = smapi_init();
|
||||
if (retval) {
|
||||
pr_err("%s: Error: SMAPI is not available on this machine\n", __func__);
|
||||
} else {
|
||||
if (mwave_3780i_irq || mwave_3780i_io || mwave_uart_irq || mwave_uart_io) {
|
||||
retval = smapi_set_DSP_cfg();
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void tp3780I_Cleanup(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
}
|
||||
|
||||
int tp3780I_CalcResources(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct smapi_dsp_settings rSmapiInfo;
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
|
||||
if (smapi_query_DSP_cfg(&rSmapiInfo)) {
|
||||
pr_err("%s: Error: Could not query DSP config. Aborting.\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
if (
|
||||
( rSmapiInfo.usDspIRQ == 0 )
|
||||
|| ( rSmapiInfo.usDspBaseIO == 0 )
|
||||
|| ( rSmapiInfo.usUartIRQ == 0 )
|
||||
|| ( rSmapiInfo.usUartBaseIO == 0 )
|
||||
) {
|
||||
pr_err("%s: Error: Illegal resource setting. Aborting.\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pSettings->bDSPEnabled = (rSmapiInfo.bDSPEnabled && rSmapiInfo.bDSPPresent);
|
||||
pSettings->bModemEnabled = rSmapiInfo.bModemEnabled;
|
||||
pSettings->usDspIrq = rSmapiInfo.usDspIRQ;
|
||||
pSettings->usDspDma = rSmapiInfo.usDspDMA;
|
||||
pSettings->usDspBaseIO = rSmapiInfo.usDspBaseIO;
|
||||
pSettings->usUartIrq = rSmapiInfo.usUartIRQ;
|
||||
pSettings->usUartBaseIO = rSmapiInfo.usUartBaseIO;
|
||||
|
||||
pSettings->uDStoreSize = TP_ABILITIES_DATA_SIZE;
|
||||
pSettings->uIStoreSize = TP_ABILITIES_INST_SIZE;
|
||||
pSettings->uIps = TP_ABILITIES_INTS_PER_SEC;
|
||||
|
||||
if (pSettings->bDSPEnabled && pSettings->bModemEnabled && pSettings->usDspIrq == pSettings->usUartIrq) {
|
||||
pBDData->bShareDspIrq = pBDData->bShareUartIrq = 1;
|
||||
} else {
|
||||
pBDData->bShareDspIrq = pBDData->bShareUartIrq = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_ClaimResources(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
int retval = 0;
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
struct resource *pres;
|
||||
|
||||
pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
|
||||
if ( pres == NULL ) retval = -EIO;
|
||||
|
||||
if (retval) {
|
||||
pr_err("%s: Error: Could not claim I/O region starting at %x\n", __func__,
|
||||
pSettings->usDspBaseIO);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int tp3780I_ReleaseResources(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
|
||||
release_region(pSettings->usDspBaseIO & (~3), 16);
|
||||
|
||||
if (pSettings->bInterruptClaimed) {
|
||||
free_irq(pSettings->usDspIrq, NULL);
|
||||
pSettings->bInterruptClaimed = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tp3780I_EnableDSP(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
bool bDSPPoweredUp = false, bInterruptAllocated = false;
|
||||
|
||||
if (pBDData->bDSPEnabled) {
|
||||
pr_err("%s: Error: DSP already enabled!\n", __func__);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
if (!pSettings->bDSPEnabled) {
|
||||
pr_err("%s: Error: pSettings->bDSPEnabled not set\n", __func__);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
if (
|
||||
(pSettings->usDspIrq >= s_numIrqs)
|
||||
|| (pSettings->usDspDma >= s_numDmas)
|
||||
|| (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF)
|
||||
|| (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF)
|
||||
) {
|
||||
pr_err("%s: Error: invalid irq %x\n", __func__, pSettings->usDspIrq);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
if (
|
||||
((pSettings->usDspBaseIO & 0xF00F) != 0)
|
||||
|| (pSettings->usDspBaseIO & 0x0FF0) == 0
|
||||
) {
|
||||
pr_err("%s: Error: Invalid DSP base I/O address %x\n", __func__,
|
||||
pSettings->usDspBaseIO);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
if (pSettings->bModemEnabled) {
|
||||
if (
|
||||
pSettings->usUartIrq >= s_numIrqs
|
||||
|| s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF
|
||||
) {
|
||||
pr_err("%s: Error: Invalid UART IRQ %x\n", __func__, pSettings->usUartIrq);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
switch (pSettings->usUartBaseIO) {
|
||||
case 0x03F8:
|
||||
case 0x02F8:
|
||||
case 0x03E8:
|
||||
case 0x02E8:
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("%s: Error: Invalid UART base I/O address %x\n", __func__,
|
||||
pSettings->usUartBaseIO);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
pSettings->bDspIrqActiveLow = pSettings->bDspIrqPulse = true;
|
||||
pSettings->bUartIrqActiveLow = pSettings->bUartIrqPulse = true;
|
||||
|
||||
if (pBDData->bShareDspIrq) {
|
||||
pSettings->bDspIrqActiveLow = false;
|
||||
}
|
||||
if (pBDData->bShareUartIrq) {
|
||||
pSettings->bUartIrqActiveLow = false;
|
||||
}
|
||||
|
||||
pSettings->usNumTransfers = TP_CFG_NumTransfers;
|
||||
pSettings->usReRequest = TP_CFG_RerequestTimer;
|
||||
pSettings->bEnableMEMCS16 = TP_CFG_MEMCS16;
|
||||
pSettings->usIsaMemCmdWidth = TP_CFG_IsaMemCmdWidth;
|
||||
pSettings->bGateIOCHRDY = TP_CFG_GateIOCHRDY;
|
||||
pSettings->bEnablePwrMgmt = TP_CFG_EnablePwrMgmt;
|
||||
pSettings->usHBusTimerLoadValue = TP_CFG_HBusTimerValue;
|
||||
pSettings->bDisableLBusTimeout = TP_CFG_DisableLBusTimeout;
|
||||
pSettings->usN_Divisor = TP_CFG_N_Divisor;
|
||||
pSettings->usM_Multiplier = TP_CFG_M_Multiplier;
|
||||
pSettings->bPllBypass = TP_CFG_PllBypass;
|
||||
pSettings->usChipletEnable = TP_CFG_ChipletEnable;
|
||||
|
||||
if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", NULL)) {
|
||||
pr_err("%s: Error: Could not get UART IRQ %x\n", __func__, pSettings->usUartIrq);
|
||||
goto exit_cleanup;
|
||||
} else { /* no conflict just release */
|
||||
free_irq(pSettings->usUartIrq, NULL);
|
||||
}
|
||||
|
||||
if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", NULL)) {
|
||||
pr_err("%s: Error: Could not get 3780i IRQ %x\n", __func__, pSettings->usDspIrq);
|
||||
goto exit_cleanup;
|
||||
} else {
|
||||
bInterruptAllocated = true;
|
||||
pSettings->bInterruptClaimed = true;
|
||||
}
|
||||
|
||||
smapi_set_DSP_power_state(false);
|
||||
if (smapi_set_DSP_power_state(true)) {
|
||||
pr_err("%s: Error: smapi_set_DSP_power_state(true) failed\n", __func__);
|
||||
goto exit_cleanup;
|
||||
} else {
|
||||
bDSPPoweredUp = true;
|
||||
}
|
||||
|
||||
if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
|
||||
pr_err("%s: Error: dsp7880I_EnableDSP() failed\n", __func__);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
EnableSRAM(pBDData);
|
||||
|
||||
pBDData->bDSPEnabled = true;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_cleanup:
|
||||
pr_err("%s: Cleaning up\n", __func__);
|
||||
if (bDSPPoweredUp)
|
||||
smapi_set_DSP_power_state(false);
|
||||
if (bInterruptAllocated) {
|
||||
free_irq(pSettings->usDspIrq, NULL);
|
||||
pSettings->bInterruptClaimed = false;
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_DisableDSP(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
|
||||
if (pBDData->bDSPEnabled) {
|
||||
dsp3780I_DisableDSP(&pBDData->rDspSettings);
|
||||
if (pSettings->bInterruptClaimed) {
|
||||
free_irq(pSettings->usDspIrq, NULL);
|
||||
pSettings->bInterruptClaimed = false;
|
||||
}
|
||||
smapi_set_DSP_power_state(false);
|
||||
pBDData->bDSPEnabled = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_ResetDSP(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
|
||||
if (dsp3780I_Reset(pSettings) == 0) {
|
||||
EnableSRAM(pBDData);
|
||||
return 0;
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_StartDSP(struct thinkpad_bd_data *pBDData)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
|
||||
if (dsp3780I_Run(pSettings) == 0) {
|
||||
// @BUG @TBD EnableSRAM(pBDData);
|
||||
} else {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_QueryAbilities(struct thinkpad_bd_data *pBDData, struct mw_abilities *pAbilities)
|
||||
{
|
||||
memset(pAbilities, 0, sizeof(*pAbilities));
|
||||
/* fill out standard constant fields */
|
||||
pAbilities->instr_per_sec = pBDData->rDspSettings.uIps;
|
||||
pAbilities->data_size = pBDData->rDspSettings.uDStoreSize;
|
||||
pAbilities->inst_size = pBDData->rDspSettings.uIStoreSize;
|
||||
pAbilities->bus_dma_bw = pBDData->rDspSettings.uDmaBandwidth;
|
||||
|
||||
/* fill out dynamically determined fields */
|
||||
pAbilities->component_list[0] = 0x00010000 | MW_ADC_MASK;
|
||||
pAbilities->component_list[1] = 0x00010000 | MW_ACI_MASK;
|
||||
pAbilities->component_list[2] = 0x00010000 | MW_AIC1_MASK;
|
||||
pAbilities->component_list[3] = 0x00010000 | MW_AIC2_MASK;
|
||||
pAbilities->component_list[4] = 0x00010000 | MW_CDDAC_MASK;
|
||||
pAbilities->component_list[5] = 0x00010000 | MW_MIDI_MASK;
|
||||
pAbilities->component_list[6] = 0x00010000 | MW_UART_MASK;
|
||||
pAbilities->component_count = 7;
|
||||
|
||||
/* Fill out Mwave OS and BIOS task names */
|
||||
|
||||
memcpy(pAbilities->mwave_os_name, TP_ABILITIES_MWAVEOS_NAME,
|
||||
sizeof(TP_ABILITIES_MWAVEOS_NAME));
|
||||
memcpy(pAbilities->bios_task_name, TP_ABILITIES_BIOSTASK_NAME,
|
||||
sizeof(TP_ABILITIES_BIOSTASK_NAME));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tp3780I_ReadWriteDspDStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode,
|
||||
void __user *pvBuffer, unsigned int uCount,
|
||||
unsigned long ulDSPAddr)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
bool bRC = 0;
|
||||
|
||||
if (pBDData->bDSPEnabled) {
|
||||
switch (uOpcode) {
|
||||
case IOCTL_MW_READ_DATA:
|
||||
bRC = dsp3780I_ReadDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
|
||||
break;
|
||||
|
||||
case IOCTL_MW_READCLEAR_DATA:
|
||||
bRC = dsp3780I_ReadAndClearDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
|
||||
break;
|
||||
|
||||
case IOCTL_MW_WRITE_DATA:
|
||||
bRC = dsp3780I_WriteDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bRC ? -EIO : 0;
|
||||
}
|
||||
|
||||
|
||||
int tp3780I_ReadWriteDspIStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode,
|
||||
void __user *pvBuffer, unsigned int uCount,
|
||||
unsigned long ulDSPAddr)
|
||||
{
|
||||
struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings;
|
||||
unsigned short usDspBaseIO = pSettings->usDspBaseIO;
|
||||
bool bRC = 0;
|
||||
|
||||
if (pBDData->bDSPEnabled) {
|
||||
switch (uOpcode) {
|
||||
case IOCTL_MW_READ_INST:
|
||||
bRC = dsp3780I_ReadIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
|
||||
break;
|
||||
|
||||
case IOCTL_MW_WRITE_INST:
|
||||
bRC = dsp3780I_WriteIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bRC ? -EIO : 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* tp3780i.h -- declarations for tp3780i.c
|
||||
*
|
||||
*
|
||||
* Written By: Mike Sullivan IBM Corporation
|
||||
*
|
||||
* Copyright (C) 1999 IBM Corporation
|
||||
*
|
||||
* 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 Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
*
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* 10/23/2000 - Alpha Release
|
||||
* First release to the public
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_TP3780I_H
|
||||
#define _LINUX_TP3780I_H
|
||||
|
||||
#include <asm/io.h>
|
||||
#include "mwavepub.h"
|
||||
|
||||
|
||||
/* DSP abilities constants for 3780i based Thinkpads */
|
||||
#define TP_ABILITIES_INTS_PER_SEC 39160800
|
||||
#define TP_ABILITIES_DATA_SIZE 32768
|
||||
#define TP_ABILITIES_INST_SIZE 32768
|
||||
#define TP_ABILITIES_MWAVEOS_NAME "mwaveos0700.dsp"
|
||||
#define TP_ABILITIES_BIOSTASK_NAME "mwbio701.dsp"
|
||||
|
||||
|
||||
/* DSP configuration values for 3780i based Thinkpads */
|
||||
#define TP_CFG_NumTransfers 3 /* 16 transfers */
|
||||
#define TP_CFG_RerequestTimer 1 /* 2 usec */
|
||||
#define TP_CFG_MEMCS16 0 /* Disabled, 16-bit memory assumed */
|
||||
#define TP_CFG_IsaMemCmdWidth 3 /* 295 nsec (16-bit) */
|
||||
#define TP_CFG_GateIOCHRDY 0 /* No IOCHRDY gating */
|
||||
#define TP_CFG_EnablePwrMgmt 1 /* Enable low poser suspend/resume */
|
||||
#define TP_CFG_HBusTimerValue 255 /* HBus timer load value */
|
||||
#define TP_CFG_DisableLBusTimeout 0 /* Enable LBus timeout */
|
||||
#define TP_CFG_N_Divisor 32 /* Clock = 39.1608 Mhz */
|
||||
#define TP_CFG_M_Multiplier 37 /* " */
|
||||
#define TP_CFG_PllBypass 0 /* don't bypass */
|
||||
#define TP_CFG_ChipletEnable 0xFFFF /* Enable all chiplets */
|
||||
|
||||
struct thinkpad_bd_data {
|
||||
int bDSPEnabled;
|
||||
int bShareDspIrq;
|
||||
int bShareUartIrq;
|
||||
struct dsp_3780i_config_settings rDspSettings;
|
||||
};
|
||||
|
||||
int tp3780I_InitializeBoardData(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_CalcResources(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_ClaimResources(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_ReleaseResources(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_EnableDSP(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_DisableDSP(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_ResetDSP(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_StartDSP(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_QueryAbilities(struct thinkpad_bd_data *pBDData, struct mw_abilities *pAbilities);
|
||||
void tp3780I_Cleanup(struct thinkpad_bd_data *pBDData);
|
||||
int tp3780I_ReadWriteDspDStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode,
|
||||
void __user *pvBuffer, unsigned int uCount,
|
||||
unsigned long ulDSPAddr);
|
||||
int tp3780I_ReadWriteDspIStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode,
|
||||
void __user *pvBuffer, unsigned int uCount,
|
||||
unsigned long ulDSPAddr);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */
|
||||
|
||||
/**
|
||||
/*
|
||||
* HwIcap Device Interrupt Status/Enable Registers
|
||||
*
|
||||
* Interrupt Status Register (IPISR) : This register holds the
|
||||
|
|
@ -102,6 +102,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
|
|||
* @drvdata: a pointer to the drvdata.
|
||||
*
|
||||
* This function will silently fail if the fifo is empty.
|
||||
*
|
||||
* Returns: 32-bit data from the Read FIFO
|
||||
**/
|
||||
static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
|
||||
{
|
||||
|
|
@ -156,6 +158,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
|
|||
* D2 - Always 1
|
||||
* D1 - Always 1
|
||||
* D0 - Done bit
|
||||
*
|
||||
* Returns: the 32-bit ICAP status register
|
||||
**/
|
||||
u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata)
|
||||
{
|
||||
|
|
@ -165,8 +169,11 @@ u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata)
|
|||
}
|
||||
|
||||
/**
|
||||
* fifo_icap_busy - Return true if the ICAP is still processing a transaction.
|
||||
* fifo_icap_busy - Check the ICAP busy status.
|
||||
* @drvdata: a pointer to the drvdata.
|
||||
*
|
||||
* Returns: %true if the ICAP is still processing a transaction,
|
||||
* otherwise %false
|
||||
**/
|
||||
static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
|
||||
{
|
||||
|
|
@ -178,7 +185,7 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
|
|||
* fifo_icap_write_fifo_vacancy - Query the write fifo available space.
|
||||
* @drvdata: a pointer to the drvdata.
|
||||
*
|
||||
* Return the number of words that can be safely pushed into the write fifo.
|
||||
* Returns: the number of words that can be safely pushed into the write fifo.
|
||||
**/
|
||||
static inline u32 fifo_icap_write_fifo_vacancy(
|
||||
struct hwicap_drvdata *drvdata)
|
||||
|
|
@ -190,7 +197,7 @@ static inline u32 fifo_icap_write_fifo_vacancy(
|
|||
* fifo_icap_read_fifo_occupancy - Query the read fifo available data.
|
||||
* @drvdata: a pointer to the drvdata.
|
||||
*
|
||||
* Return the number of words that can be safely read from the read fifo.
|
||||
* Returns: the number of words that can be safely read from the read fifo.
|
||||
**/
|
||||
static inline u32 fifo_icap_read_fifo_occupancy(
|
||||
struct hwicap_drvdata *drvdata)
|
||||
|
|
@ -205,10 +212,12 @@ static inline u32 fifo_icap_read_fifo_occupancy(
|
|||
* ICAP device.
|
||||
* @num_words: the number of words (32 bit) to write to the ICAP
|
||||
* device.
|
||||
|
||||
*
|
||||
* This function writes the given user data to the Write FIFO in
|
||||
* polled mode and starts the transfer of the data to
|
||||
* the ICAP device.
|
||||
*
|
||||
* Returns: %0 on success or %-errno on failure.
|
||||
**/
|
||||
int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
|
||||
u32 *frame_buffer, u32 num_words)
|
||||
|
|
@ -280,11 +289,13 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
|
|||
/**
|
||||
* fifo_icap_get_configuration - Read configuration data from the device.
|
||||
* @drvdata: a pointer to the drvdata.
|
||||
* @data: Address of the data representing the partial bitstream
|
||||
* @size: the size of the partial bitstream in 32 bit words.
|
||||
* @frame_buffer: Address of the data representing the partial bitstream
|
||||
* @num_words: the size of the partial bitstream in 32 bit words.
|
||||
*
|
||||
* This function reads the specified number of words from the ICAP device in
|
||||
* the polled mode.
|
||||
*
|
||||
* Returns: %0 on success or %-errno on failure.
|
||||
*/
|
||||
int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
|
||||
u32 *frame_buffer, u32 num_words)
|
||||
|
|
@ -347,7 +358,7 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
|
|||
}
|
||||
|
||||
/**
|
||||
* buffer_icap_reset - Reset the logic of the icap device.
|
||||
* fifo_icap_reset - Reset the logic of the icap device.
|
||||
* @drvdata: a pointer to the drvdata.
|
||||
*
|
||||
* This function forces the software reset of the complete HWICAP device.
|
||||
|
|
|
|||
|
|
@ -1169,6 +1169,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
|
|||
* COMEDI_BUFINFO ioctl
|
||||
* buffer information
|
||||
*
|
||||
* Note that the comedi device's mutex has not been locked for this ioctl.
|
||||
*
|
||||
* arg:
|
||||
* pointer to comedi_bufinfo structure
|
||||
*
|
||||
|
|
@ -1186,24 +1188,42 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
|
|||
struct comedi_async *async;
|
||||
unsigned int runflags;
|
||||
int retval = 0;
|
||||
unsigned int old_detach_count;
|
||||
unsigned int cmd_flags;
|
||||
bool become_nonbusy = false;
|
||||
bool attach_locked;
|
||||
|
||||
lockdep_assert_held(&dev->mutex);
|
||||
if (copy_from_user(&bi, arg, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
|
||||
if (bi.subdevice >= dev->n_subdevices)
|
||||
return -EINVAL;
|
||||
/* Protect against device detachment during operation. */
|
||||
down_read(&dev->attach_lock);
|
||||
attach_locked = true;
|
||||
old_detach_count = dev->detach_count;
|
||||
|
||||
if (!dev->attached) {
|
||||
dev_dbg(dev->class_dev, "no driver attached\n");
|
||||
retval = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bi.subdevice >= dev->n_subdevices) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
s = &dev->subdevices[bi.subdevice];
|
||||
|
||||
async = s->async;
|
||||
|
||||
if (!async || s->busy != file)
|
||||
return -EINVAL;
|
||||
if (!async || s->busy != file) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
runflags = comedi_get_subdevice_runflags(s);
|
||||
if (!(async->cmd.flags & CMDF_WRITE)) {
|
||||
cmd_flags = async->cmd.flags;
|
||||
if (!(cmd_flags & CMDF_WRITE)) {
|
||||
/* command was set up in "read" direction */
|
||||
if (bi.bytes_read) {
|
||||
_comedi_buf_read_alloc(s, bi.bytes_read);
|
||||
|
|
@ -1243,8 +1263,41 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
|
|||
bi.buf_read_count = async->buf_read_count;
|
||||
bi.buf_read_ptr = async->buf_read_ptr;
|
||||
|
||||
if (become_nonbusy)
|
||||
do_become_nonbusy(dev, s);
|
||||
if (become_nonbusy) {
|
||||
struct comedi_subdevice *new_s = NULL;
|
||||
|
||||
/*
|
||||
* To avoid deadlock, cannot acquire dev->mutex
|
||||
* while dev->attach_lock is held.
|
||||
*/
|
||||
up_read(&dev->attach_lock);
|
||||
attach_locked = false;
|
||||
mutex_lock(&dev->mutex);
|
||||
/*
|
||||
* Check device hasn't become detached behind our back.
|
||||
* Checking dev->detach_count is unchanged ought to be
|
||||
* sufficient, but check the subdevice pointer as well,
|
||||
* and check the subdevice is still in a suitable state
|
||||
* to become non-busy. It should still be "busy" after
|
||||
* running an asynchronous commands, which should now have
|
||||
* stopped, and for a command in the "read" direction, all
|
||||
* available data should have been read.
|
||||
*/
|
||||
if (dev->attached && old_detach_count == dev->detach_count &&
|
||||
bi.subdevice < dev->n_subdevices)
|
||||
new_s = &dev->subdevices[bi.subdevice];
|
||||
if (s == new_s && new_s->async == async && s->busy == file &&
|
||||
async->cmd.flags == cmd_flags &&
|
||||
!comedi_is_subdevice_running(s) &&
|
||||
((cmd_flags & CMDF_WRITE) != 0 ||
|
||||
_comedi_buf_read_n_available(s) == 0))
|
||||
do_become_nonbusy(dev, s);
|
||||
mutex_unlock(&dev->mutex);
|
||||
}
|
||||
|
||||
out:
|
||||
if (attach_locked)
|
||||
up_read(&dev->attach_lock);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
|
@ -2225,6 +2278,13 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
|
|||
struct comedi_device *dev = cfp->dev;
|
||||
int rc;
|
||||
|
||||
/* Handle COMEDI_BUFINFO without locking the mutex first. */
|
||||
if (cmd == COMEDI_BUFINFO) {
|
||||
return do_bufinfo_ioctl(dev,
|
||||
(struct comedi_bufinfo __user *)arg,
|
||||
file);
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
|
||||
/*
|
||||
|
|
@ -2294,11 +2354,6 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
|
|||
rc = do_rangeinfo_ioctl(dev, &it);
|
||||
break;
|
||||
}
|
||||
case COMEDI_BUFINFO:
|
||||
rc = do_bufinfo_ioctl(dev,
|
||||
(struct comedi_bufinfo __user *)arg,
|
||||
file);
|
||||
break;
|
||||
case COMEDI_LOCK:
|
||||
rc = do_lock_ioctl(dev, arg, file);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -692,6 +692,44 @@ static int waveform_ao_insn_config(struct comedi_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int waveform_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
u32 driven_low;
|
||||
u16 wires;
|
||||
|
||||
/* Update the channel outputs. */
|
||||
comedi_dio_update_state(s, data);
|
||||
/*
|
||||
* We are modelling the outputs as NPN open collector (0 = driven low,
|
||||
* 1 = high impedance), with the lower 16 channels wired to the upper
|
||||
* 16 channels in pairs (0 to 16, 1 to 17, ..., 15 to 31), with a
|
||||
* pull-up resistor on each wire. When reading back each channel, we
|
||||
* read back the state of the wire to which it is connected.
|
||||
*
|
||||
* The state of each wire and the value read back from both channels
|
||||
* connected to it will be logic 1 unless either channel connected to
|
||||
* the wire is configured as an output in the logic 0 state.
|
||||
*/
|
||||
driven_low = s->io_bits & ~s->state;
|
||||
wires = 0xFFFF & ~driven_low & ~(driven_low >> 16);
|
||||
/* Read back the state of the wires for each pair of channels. */
|
||||
data[1] = wires | (wires << 16);
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int waveform_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
/* configure each channel as input or output individually */
|
||||
return comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
}
|
||||
|
||||
static int waveform_common_attach(struct comedi_device *dev,
|
||||
int amplitude, int period)
|
||||
{
|
||||
|
|
@ -707,7 +745,7 @@ static int waveform_common_attach(struct comedi_device *dev,
|
|||
devpriv->wf_amplitude = amplitude;
|
||||
devpriv->wf_period = period;
|
||||
|
||||
ret = comedi_alloc_subdevices(dev, 2);
|
||||
ret = comedi_alloc_subdevices(dev, 3);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -746,6 +784,16 @@ static int waveform_common_attach(struct comedi_device *dev,
|
|||
for (i = 0; i < s->n_chan; i++)
|
||||
devpriv->ao_loopbacks[i] = s->maxdata / 2;
|
||||
|
||||
s = &dev->subdevices[2];
|
||||
/* digital input/output subdevice */
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
|
||||
s->n_chan = 32;
|
||||
s->maxdata = 1;
|
||||
s->range_table = &range_digital;
|
||||
s->insn_bits = waveform_dio_insn_bits;
|
||||
s->insn_config = waveform_dio_insn_config;
|
||||
|
||||
devpriv->dev = dev;
|
||||
timer_setup(&devpriv->ai_timer, waveform_ai_timer, 0);
|
||||
timer_setup(&devpriv->ao_timer, waveform_ao_timer, 0);
|
||||
|
|
|
|||
|
|
@ -1317,7 +1317,7 @@ int stratix10_svc_async_send(struct stratix10_svc_chan *chan, void *msg,
|
|||
dev_dbg(ctrl->dev,
|
||||
"Async message sent with transaction_id 0x%02x\n",
|
||||
handle->transaction_id);
|
||||
*handler = handle;
|
||||
*handler = handle;
|
||||
return 0;
|
||||
case INTEL_SIP_SMC_STATUS_BUSY:
|
||||
dev_warn(ctrl->dev, "Mailbox is busy, try after some time\n");
|
||||
|
|
@ -1702,12 +1702,12 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg)
|
|||
kthread_run_on_cpu(svc_normal_to_secure_thread,
|
||||
(void *)chan->ctrl,
|
||||
cpu, "svc_smc_hvc_thread");
|
||||
if (IS_ERR(chan->ctrl->task)) {
|
||||
dev_err(chan->ctrl->dev,
|
||||
"failed to create svc_smc_hvc_thread\n");
|
||||
kfree(p_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (IS_ERR(chan->ctrl->task)) {
|
||||
dev_err(chan->ctrl->dev,
|
||||
"failed to create svc_smc_hvc_thread\n");
|
||||
kfree(p_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("%s: sent P-va=%p, P-com=%x, P-size=%u\n", __func__,
|
||||
|
|
|
|||
|
|
@ -2018,7 +2018,7 @@ static void __exit dfl_fpga_exit(void)
|
|||
bus_unregister(&dfl_bus_type);
|
||||
}
|
||||
|
||||
module_init(dfl_fpga_init);
|
||||
subsys_initcall(dfl_fpga_init);
|
||||
module_exit(dfl_fpga_exit);
|
||||
|
||||
MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
#define DFH_TYPE_FIU 4
|
||||
|
||||
/*
|
||||
* DFHv1 Register Offset definitons
|
||||
* DFHv1 Register Offset definitions
|
||||
* In DHFv1, DFH + GUID + CSR_START + CSR_SIZE_GROUP + PARAM_HDR + PARAM_DATA
|
||||
* as common header registers
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static struct fpga_manager *of_fpga_region_get_mgr(struct device_node *np)
|
|||
* done with the bridges.
|
||||
*
|
||||
* Return: 0 for success (even if there are no bridges specified)
|
||||
* or -EBUSY if any of the bridges are in use.
|
||||
* or an error code if any of the bridges are not available.
|
||||
*/
|
||||
static int of_fpga_region_get_bridges(struct fpga_region *region)
|
||||
{
|
||||
|
|
@ -130,10 +130,10 @@ static int of_fpga_region_get_bridges(struct fpga_region *region)
|
|||
®ion->bridge_list);
|
||||
of_node_put(br);
|
||||
|
||||
/* If any of the bridges are in use, give up */
|
||||
if (ret == -EBUSY) {
|
||||
/* If any of the bridges are not available, give up */
|
||||
if (ret) {
|
||||
fpga_bridges_put(®ion->bridge_list);
|
||||
return -EBUSY;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -173,5 +173,5 @@ module_platform_driver(xlnx_pr_decoupler_driver);
|
|||
|
||||
MODULE_DESCRIPTION("Xilinx Partial Reconfiguration Decoupler");
|
||||
MODULE_AUTHOR("Moritz Fischer <mdf@kernel.org>");
|
||||
MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
|
||||
MODULE_AUTHOR("Michal Simek <michal.simek@amd.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
|
|
@ -652,6 +652,6 @@ static struct platform_driver zynq_fpga_driver = {
|
|||
module_platform_driver(zynq_fpga_driver);
|
||||
|
||||
MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
|
||||
MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
|
||||
MODULE_AUTHOR("Michal Simek <michal.simek@amd.com>");
|
||||
MODULE_DESCRIPTION("Xilinx Zynq FPGA Manager");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
|
|
@ -100,6 +100,61 @@ static int fsi_master_write(struct fsi_master *master, int link,
|
|||
uint8_t slave_id, uint32_t addr, const void *val, size_t size);
|
||||
static int fsi_master_break(struct fsi_master *master, int link);
|
||||
|
||||
/* FSI core & Linux bus type definitions */
|
||||
|
||||
static int fsi_bus_match(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
struct fsi_device *fsi_dev = to_fsi_dev(dev);
|
||||
const struct fsi_driver *fsi_drv = to_fsi_drv(drv);
|
||||
const struct fsi_device_id *id;
|
||||
|
||||
if (!fsi_drv->id_table)
|
||||
return 0;
|
||||
|
||||
for (id = fsi_drv->id_table; id->engine_type; id++) {
|
||||
if (id->engine_type != fsi_dev->engine_type)
|
||||
continue;
|
||||
if (id->version == FSI_VERSION_ANY ||
|
||||
id->version == fsi_dev->version) {
|
||||
if (drv->of_match_table) {
|
||||
if (of_driver_match_device(dev, drv))
|
||||
return 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsi_probe(struct device *dev)
|
||||
{
|
||||
struct fsi_device *fsidev = to_fsi_dev(dev);
|
||||
struct fsi_driver *fsidrv = to_fsi_drv(dev->driver);
|
||||
|
||||
if (fsidrv->probe)
|
||||
return fsidrv->probe(fsidev);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fsi_remove(struct device *dev)
|
||||
{
|
||||
struct fsi_device *fsidev = to_fsi_dev(dev);
|
||||
struct fsi_driver *fsidrv = to_fsi_drv(dev->driver);
|
||||
|
||||
if (fsidrv->remove)
|
||||
fsidrv->remove(fsidev);
|
||||
}
|
||||
|
||||
static const struct bus_type fsi_bus_type = {
|
||||
.name = "fsi",
|
||||
.match = fsi_bus_match,
|
||||
.probe = fsi_probe,
|
||||
.remove = fsi_remove,
|
||||
};
|
||||
|
||||
/*
|
||||
* fsi_device_read() / fsi_device_write() / fsi_device_peek()
|
||||
*
|
||||
|
|
@ -1359,32 +1414,23 @@ void fsi_master_unregister(struct fsi_master *master)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(fsi_master_unregister);
|
||||
|
||||
/* FSI core & Linux bus type definitions */
|
||||
|
||||
static int fsi_bus_match(struct device *dev, const struct device_driver *drv)
|
||||
static int fsi_legacy_probe(struct fsi_device *fsidev)
|
||||
{
|
||||
struct fsi_device *fsi_dev = to_fsi_dev(dev);
|
||||
const struct fsi_driver *fsi_drv = to_fsi_drv(drv);
|
||||
const struct fsi_device_id *id;
|
||||
struct device *dev = &fsidev->dev;
|
||||
struct device_driver *driver = dev->driver;
|
||||
|
||||
if (!fsi_drv->id_table)
|
||||
return 0;
|
||||
return driver->probe(dev);
|
||||
}
|
||||
|
||||
for (id = fsi_drv->id_table; id->engine_type; id++) {
|
||||
if (id->engine_type != fsi_dev->engine_type)
|
||||
continue;
|
||||
if (id->version == FSI_VERSION_ANY ||
|
||||
id->version == fsi_dev->version) {
|
||||
if (drv->of_match_table) {
|
||||
if (of_driver_match_device(dev, drv))
|
||||
return 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void fsi_legacy_remove(struct fsi_device *fsidev)
|
||||
{
|
||||
struct device *dev = &fsidev->dev;
|
||||
struct device_driver *driver = dev->driver;
|
||||
int ret;
|
||||
|
||||
return 0;
|
||||
ret = driver->remove(dev);
|
||||
if (unlikely(ret))
|
||||
dev_warn(dev, "Ignoring return value of remove callback (%pe)\n", ERR_PTR(ret));
|
||||
}
|
||||
|
||||
int fsi_driver_register(struct fsi_driver *fsi_drv)
|
||||
|
|
@ -1394,6 +1440,17 @@ int fsi_driver_register(struct fsi_driver *fsi_drv)
|
|||
if (!fsi_drv->id_table)
|
||||
return -EINVAL;
|
||||
|
||||
fsi_drv->drv.bus = &fsi_bus_type;
|
||||
|
||||
/*
|
||||
* This driver needs updating. Note that driver_register() warns about
|
||||
* this, so we're not adding another warning here.
|
||||
*/
|
||||
if (!fsi_drv->probe && fsi_drv->drv.probe)
|
||||
fsi_drv->probe = fsi_legacy_probe;
|
||||
if (!fsi_drv->remove && fsi_drv->drv.remove)
|
||||
fsi_drv->remove = fsi_legacy_remove;
|
||||
|
||||
return driver_register(&fsi_drv->drv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsi_driver_register);
|
||||
|
|
@ -1404,12 +1461,6 @@ void fsi_driver_unregister(struct fsi_driver *fsi_drv)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(fsi_driver_unregister);
|
||||
|
||||
const struct bus_type fsi_bus_type = {
|
||||
.name = "fsi",
|
||||
.match = fsi_bus_match,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(fsi_bus_type);
|
||||
|
||||
static int __init fsi_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
|
|
|||
|
|
@ -192,9 +192,9 @@ static int hub_master_init(struct fsi_master_hub *hub)
|
|||
return fsi_device_write(dev, FSI_MRESB0, ®, sizeof(reg));
|
||||
}
|
||||
|
||||
static int hub_master_probe(struct device *dev)
|
||||
static int hub_master_probe(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct fsi_device *fsi_dev = to_fsi_dev(dev);
|
||||
struct device *dev = &fsi_dev->dev;
|
||||
struct fsi_master_hub *hub;
|
||||
uint32_t reg, links;
|
||||
__be32 __reg;
|
||||
|
|
@ -235,7 +235,7 @@ static int hub_master_probe(struct device *dev)
|
|||
hub->master.send_break = hub_master_break;
|
||||
hub->master.link_enable = hub_master_link_enable;
|
||||
|
||||
dev_set_drvdata(dev, hub);
|
||||
fsi_set_drvdata(fsi_dev, hub);
|
||||
|
||||
hub_master_init(hub);
|
||||
|
||||
|
|
@ -259,9 +259,9 @@ err_release:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int hub_master_remove(struct device *dev)
|
||||
static void hub_master_remove(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct fsi_master_hub *hub = dev_get_drvdata(dev);
|
||||
struct fsi_master_hub *hub = fsi_get_drvdata(fsi_dev);
|
||||
|
||||
fsi_master_unregister(&hub->master);
|
||||
fsi_slave_release_range(hub->upstream->slave, hub->addr, hub->size);
|
||||
|
|
@ -272,8 +272,6 @@ static int hub_master_remove(struct device *dev)
|
|||
* the hub
|
||||
*/
|
||||
put_device(&hub->master.dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct fsi_device_id hub_master_ids[] = {
|
||||
|
|
@ -286,11 +284,10 @@ static const struct fsi_device_id hub_master_ids[] = {
|
|||
|
||||
static struct fsi_driver hub_master_driver = {
|
||||
.id_table = hub_master_ids,
|
||||
.probe = hub_master_probe,
|
||||
.remove = hub_master_remove,
|
||||
.drv = {
|
||||
.name = "fsi-master-hub",
|
||||
.bus = &fsi_bus_type,
|
||||
.probe = hub_master_probe,
|
||||
.remove = hub_master_remove,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1022,9 +1022,9 @@ static void sbefifo_free(struct device *dev)
|
|||
* Probe/remove
|
||||
*/
|
||||
|
||||
static int sbefifo_probe(struct device *dev)
|
||||
static int sbefifo_probe(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct fsi_device *fsi_dev = to_fsi_dev(dev);
|
||||
struct device *dev = &fsi_dev->dev;
|
||||
struct sbefifo *sbefifo;
|
||||
struct device_node *np;
|
||||
struct platform_device *child;
|
||||
|
|
@ -1045,7 +1045,7 @@ static int sbefifo_probe(struct device *dev)
|
|||
|
||||
sbefifo->magic = SBEFIFO_MAGIC;
|
||||
sbefifo->fsi_dev = fsi_dev;
|
||||
dev_set_drvdata(dev, sbefifo);
|
||||
fsi_set_drvdata(fsi_dev, sbefifo);
|
||||
mutex_init(&sbefifo->lock);
|
||||
sbefifo->timeout_in_cmd_ms = SBEFIFO_TIMEOUT_IN_CMD;
|
||||
sbefifo->timeout_start_rsp_ms = SBEFIFO_TIMEOUT_START_RSP;
|
||||
|
|
@ -1101,9 +1101,10 @@ static int sbefifo_unregister_child(struct device *dev, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sbefifo_remove(struct device *dev)
|
||||
static void sbefifo_remove(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct sbefifo *sbefifo = dev_get_drvdata(dev);
|
||||
struct device *dev = &fsi_dev->dev;
|
||||
struct sbefifo *sbefifo = fsi_get_drvdata(fsi_dev);
|
||||
|
||||
dev_dbg(dev, "Removing sbefifo device...\n");
|
||||
|
||||
|
|
@ -1117,8 +1118,6 @@ static int sbefifo_remove(struct device *dev)
|
|||
fsi_free_minor(sbefifo->dev.devt);
|
||||
device_for_each_child(dev, NULL, sbefifo_unregister_child);
|
||||
put_device(&sbefifo->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct fsi_device_id sbefifo_ids[] = {
|
||||
|
|
@ -1131,26 +1130,14 @@ static const struct fsi_device_id sbefifo_ids[] = {
|
|||
|
||||
static struct fsi_driver sbefifo_drv = {
|
||||
.id_table = sbefifo_ids,
|
||||
.probe = sbefifo_probe,
|
||||
.remove = sbefifo_remove,
|
||||
.drv = {
|
||||
.name = DEVICE_NAME,
|
||||
.bus = &fsi_bus_type,
|
||||
.probe = sbefifo_probe,
|
||||
.remove = sbefifo_remove,
|
||||
}
|
||||
};
|
||||
|
||||
static int sbefifo_init(void)
|
||||
{
|
||||
return fsi_driver_register(&sbefifo_drv);
|
||||
}
|
||||
|
||||
static void sbefifo_exit(void)
|
||||
{
|
||||
fsi_driver_unregister(&sbefifo_drv);
|
||||
}
|
||||
|
||||
module_init(sbefifo_init);
|
||||
module_exit(sbefifo_exit);
|
||||
module_fsi_driver(sbefifo_drv);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Brad Bishop <bradleyb@fuzziesquirrel.com>");
|
||||
MODULE_AUTHOR("Eddie James <eajames@linux.vnet.ibm.com>");
|
||||
|
|
|
|||
|
|
@ -527,16 +527,16 @@ static void scom_free(struct device *dev)
|
|||
kfree(scom);
|
||||
}
|
||||
|
||||
static int scom_probe(struct device *dev)
|
||||
static int scom_probe(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct fsi_device *fsi_dev = to_fsi_dev(dev);
|
||||
struct device *dev = &fsi_dev->dev;
|
||||
struct scom_device *scom;
|
||||
int rc, didx;
|
||||
|
||||
scom = kzalloc(sizeof(*scom), GFP_KERNEL);
|
||||
if (!scom)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(dev, scom);
|
||||
fsi_set_drvdata(fsi_dev, scom);
|
||||
mutex_init(&scom->lock);
|
||||
|
||||
/* Grab a reference to the device (parent of our cdev), we'll drop it later */
|
||||
|
|
@ -574,9 +574,9 @@ static int scom_probe(struct device *dev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int scom_remove(struct device *dev)
|
||||
static void scom_remove(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct scom_device *scom = dev_get_drvdata(dev);
|
||||
struct scom_device *scom = fsi_get_drvdata(fsi_dev);
|
||||
|
||||
mutex_lock(&scom->lock);
|
||||
scom->dead = true;
|
||||
|
|
@ -584,8 +584,6 @@ static int scom_remove(struct device *dev)
|
|||
cdev_device_del(&scom->cdev, &scom->dev);
|
||||
fsi_free_minor(scom->dev.devt);
|
||||
put_device(&scom->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id scom_of_ids[] = {
|
||||
|
|
@ -604,26 +602,14 @@ static const struct fsi_device_id scom_ids[] = {
|
|||
|
||||
static struct fsi_driver scom_drv = {
|
||||
.id_table = scom_ids,
|
||||
.probe = scom_probe,
|
||||
.remove = scom_remove,
|
||||
.drv = {
|
||||
.name = "scom",
|
||||
.bus = &fsi_bus_type,
|
||||
.of_match_table = scom_of_ids,
|
||||
.probe = scom_probe,
|
||||
.remove = scom_remove,
|
||||
}
|
||||
};
|
||||
|
||||
static int scom_init(void)
|
||||
{
|
||||
return fsi_driver_register(&scom_drv);
|
||||
}
|
||||
|
||||
static void scom_exit(void)
|
||||
{
|
||||
fsi_driver_unregister(&scom_drv);
|
||||
}
|
||||
|
||||
module_init(scom_init);
|
||||
module_exit(scom_exit);
|
||||
module_fsi_driver(scom_drv);
|
||||
MODULE_DESCRIPTION("SCOM FSI Client device driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ static const struct file_operations i2cr_scom_fops = {
|
|||
.write = i2cr_scom_write,
|
||||
};
|
||||
|
||||
static int i2cr_scom_probe(struct device *dev)
|
||||
static int i2cr_scom_probe(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct fsi_device *fsi_dev = to_fsi_dev(dev);
|
||||
struct device *dev = &fsi_dev->dev;
|
||||
struct i2cr_scom *scom;
|
||||
int didx;
|
||||
int ret;
|
||||
|
|
@ -115,14 +115,12 @@ static int i2cr_scom_probe(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int i2cr_scom_remove(struct device *dev)
|
||||
static void i2cr_scom_remove(struct fsi_device *fsi_dev)
|
||||
{
|
||||
struct i2cr_scom *scom = dev_get_drvdata(dev);
|
||||
struct i2cr_scom *scom = dev_get_drvdata(&fsi_dev->dev);
|
||||
|
||||
cdev_device_del(&scom->cdev, &scom->dev);
|
||||
fsi_free_minor(scom->dev.devt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id i2cr_scom_of_ids[] = {
|
||||
|
|
@ -137,13 +135,12 @@ static const struct fsi_device_id i2cr_scom_ids[] = {
|
|||
};
|
||||
|
||||
static struct fsi_driver i2cr_scom_driver = {
|
||||
.probe = i2cr_scom_probe,
|
||||
.remove = i2cr_scom_remove,
|
||||
.id_table = i2cr_scom_ids,
|
||||
.drv = {
|
||||
.name = "i2cr_scom",
|
||||
.bus = &fsi_bus_type,
|
||||
.of_match_table = i2cr_scom_of_ids,
|
||||
.probe = i2cr_scom_probe,
|
||||
.remove = i2cr_scom_remove,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -599,8 +599,9 @@ static int agilent_82350b_generic_attach(struct gpib_board *board,
|
|||
|
||||
board->status = 0;
|
||||
|
||||
if (agilent_82350b_allocate_private(board))
|
||||
return -ENOMEM;
|
||||
retval = agilent_82350b_allocate_private(board);
|
||||
if (retval)
|
||||
return retval;
|
||||
a_priv = board->private_data;
|
||||
a_priv->using_fifos = use_fifos;
|
||||
tms_priv = &a_priv->tms9914_priv;
|
||||
|
|
|
|||
|
|
@ -1316,7 +1316,7 @@ static int agilent_82357a_attach(struct gpib_board *board, const struct gpib_boa
|
|||
return -ERESTARTSYS;
|
||||
|
||||
retval = agilent_82357a_allocate_private(board);
|
||||
if (retval < 0) {
|
||||
if (retval) {
|
||||
mutex_unlock(&agilent_82357a_hotplug_lock);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -856,11 +856,10 @@ static int cb7210_allocate_private(struct gpib_board *board)
|
|||
{
|
||||
struct cb7210_priv *priv;
|
||||
|
||||
board->private_data = kmalloc(sizeof(struct cb7210_priv), GFP_KERNEL);
|
||||
board->private_data = kzalloc(sizeof(struct cb7210_priv), GFP_KERNEL);
|
||||
if (!board->private_data)
|
||||
return -ENOMEM;
|
||||
priv = board->private_data;
|
||||
memset(priv, 0, sizeof(struct cb7210_priv));
|
||||
init_nec7210_private(&priv->nec7210_priv);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -876,11 +875,13 @@ static int cb7210_generic_attach(struct gpib_board *board)
|
|||
{
|
||||
struct cb7210_priv *cb_priv;
|
||||
struct nec7210_priv *nec_priv;
|
||||
int retval;
|
||||
|
||||
board->status = 0;
|
||||
|
||||
if (cb7210_allocate_private(board))
|
||||
return -ENOMEM;
|
||||
retval = cb7210_allocate_private(board);
|
||||
if (retval)
|
||||
return retval;
|
||||
cb_priv = board->private_data;
|
||||
nec_priv = &cb_priv->nec7210_priv;
|
||||
nec_priv->read_byte = nec7210_locking_ioport_read_byte;
|
||||
|
|
|
|||
|
|
@ -220,11 +220,10 @@ static int cec_allocate_private(struct gpib_board *board)
|
|||
{
|
||||
struct cec_priv *priv;
|
||||
|
||||
board->private_data = kmalloc(sizeof(struct cec_priv), GFP_KERNEL);
|
||||
board->private_data = kzalloc(sizeof(struct cec_priv), GFP_KERNEL);
|
||||
if (!board->private_data)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
priv = board->private_data;
|
||||
memset(priv, 0, sizeof(struct cec_priv));
|
||||
init_nec7210_private(&priv->nec7210_priv);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -239,11 +238,13 @@ static int cec_generic_attach(struct gpib_board *board)
|
|||
{
|
||||
struct cec_priv *cec_priv;
|
||||
struct nec7210_priv *nec_priv;
|
||||
int retval;
|
||||
|
||||
board->status = 0;
|
||||
|
||||
if (cec_allocate_private(board))
|
||||
return -ENOMEM;
|
||||
retval = cec_allocate_private(board);
|
||||
if (retval)
|
||||
return retval;
|
||||
cec_priv = board->private_data;
|
||||
nec_priv = &cec_priv->nec7210_priv;
|
||||
nec_priv->read_byte = nec7210_ioport_read_byte;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue