272 Commits

Author SHA1 Message Date
Ian Lepore
c5fe9c7b20 Allow i2c hardware drivers to declare their own relationships to ofw_iicbus
rather than relying on a set of canned EARLY_DRIVER_MODULE() statements in
the ofw_iicbus source.  This means hw drivers will no longer be required to
use one of a few predefined driver names.  They will also now be able to
decide themselves if they want to use DRIVER_MODULE or EARLY_DRIVER_MODULE
and to set which pass to attach on for early modules.

Mainly, this adds extern declarations for the driver and devclass variables.
It also renames ofwiicbus_devclass to ofw_iicbus_devclass to be consistant
with the way we use ofw_ prefixes on this stuff.
2018-02-18 19:33:28 +00:00
Ian Lepore
8917c34a82 Follow changes in r328307 by using new IIC_RECURSIVE flag.
The driver now ensures only one thread at a time is running in the API
functions (clock_gettime() and clock_settime()) by specifically requesting
ownership of the i2c bus without using IIC_RECURSIVE, then it does all IO
using IIC_RECURSIVE so that each individual IO operation doesn't try to
re-acquire the bus.

The other IO done by the driver happens at attach or intr_config_hooks time,
when there can't be multiple threads running with the same device instance.
So, the IIC_RECURSIVE flag can be safely ORed into the wait flags for all IO
done by the driver, because it's all either done in a single-threaded
environment, or protected within a block bounded by explict
iicbus_acquire_bus() and iicbus_release_bus() calls.
2018-01-24 03:09:56 +00:00
Ian Lepore
548778ed13 Follow changes in r328307 by using new IIC_RECURSIVE flag.
The driver now ensures only one thread at a time is running in the API
functions (clock_gettime() and clock_settime()) by specifically requesting
ownership of the i2c bus without using IIC_RECURSIVE, then it does all IO
using IIC_RECURSIVE so that each individual IO operation doesn't try to
re-acquire the bus.

The other IO done by the driver happens at attach or intr_config_hooks time,
when there can't be multiple threads running with the same device instance.
So, the IIC_RECURSIVE flag can be safely ORed into the wait flags for all IO
done by the driver, because it's all either done in a single-threaded
environment, or protected within a block bounded by explict
iicbus_acquire_bus() and iicbus_release_bus() calls.
2018-01-24 03:09:41 +00:00
Ian Lepore
ac8f374abf Fix a bug introduced with recursive bus ownership support in r321584.
The recursive ownership support added in r321584 was unconditionally in
effect all the time -- whenever a given i2c slave device instance tried to
lock the i2c bus for exclusive use when it already owned the bus, the call
returned immediately without waiting.  However, many i2c slave drivers use
bus ownership to enforce that only a single thread at a time can be using
the slave device.  The recursive locking changes broke this use case.

Now there is a new flag, IIC_RECURSIVE, which can be mixed in with the
other flags passed to iicbus_acquire_bus() to allow drivers to indicate
when recursive locking is desired.  Using the flag implies that the driver
is managing concurrent access to the device by different threads in some way.

This immediately fixes all existing i2c slave drivers except for the two
i2c RTC drivers which use the recursive locking feature; those will be
fixed in a followup commit.
2018-01-23 23:30:19 +00:00
Ian Lepore
18d61b59bf Switch to using the bcd_clocktime conversion functions that validate the BCD
data without panicking, and have common code for handling AM/PM mode.
2018-01-23 21:36:26 +00:00
Ian Lepore
e324bd4bd6 Switch to using the bcd_clocktime conversion functions that validate the BCD
data without panicking, and have common code for handling AM/PM mode.
2018-01-23 21:31:43 +00:00
Ian Lepore
234add65f7 Switch to using the bcd_clocktime conversion functinos that validate the BCD
data without panicking, and have common code for handling AM/PM mode.
2018-01-23 21:18:15 +00:00
Ian Lepore
a369070143 Convert a collection of unrelated bitwise flags to a collection of boolean
vars in the softc.  It makes the code more compact and readable, and
actually uses less memory too.
2018-01-10 02:57:03 +00:00
Ian Lepore
b33d84e005 Bugfix: don't lose the am/pm mode flag when setting the time. Unlike most
RTC chips that have a control register bit for am/pm mode, the DS13xx series
uses one of the high bits in the hour register.  Thus, when setting the time
in am/pm mode, the am/pm mode flag has to be ORed into the hour.
2018-01-10 02:31:59 +00:00
Ian Lepore
b93c58e168 Bugfix: on RTC chips with a 32-bit binary counter, after reading the time,
return immediately rather than falling through to the logic that reads
BCD-encoded time.
2018-01-10 02:28:10 +00:00
Emmanuel Vadot
b6d40d9394 Change the remaining files using my personnal email address to my freebsd one 2017-12-25 22:09:25 +00:00
Ian Lepore
3102bbe940 Do not give up if writing to the chip's control and status registers fails
during startup.  When a brand new chip leaves the factory, it is in a
special power-saving mode that disables most functions on the chip to
save battery power.  The chip is stuck in this mode until the first write
to the time registers, which automatically clears the special power-saving
mode and starts the oscillator.

Also, the day-of-week register in this chip counts 1-7, not 0-6, so write
the values accordingly.

These changes are based on the patch submitted by Brian Scott, but I
elimated warnings since this condition is expected, and added some comments,
and so in general blame me for any mistakes.

PR:		223642
2017-12-10 18:55:42 +00:00
Pedro F. Giffuni
718cf2ccb9 sys/dev: further adoption of SPDX licensing ID tags.
Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
2017-11-27 14:52:40 +00:00
Justin Hibbits
9a7a0683b1 DS1307: Add the mcp7941x enable bit
Summary:
Existing code recognizes the mcp7941x RTC, but this RTC has an
enable bit at the same location as the "Clock Halt" bit on the ds1307, with an
opposite assertion (set == on, whereas CH set == clock stopped).  Thus the
current code halts the clock, with no way to enable it.

Reviewed By:	ian
MFC after:	2 weeks
Differential Revision: https://reviews.freebsd.org/D12961
2017-11-08 01:28:20 +00:00
Michael Zhilin
be04c94e1e [i2c/clock] add support for EPSON RTC-8583
RTC-8583 is time-of-day clock used in some SOHO routers. This clock has
only 2 bits for year values, but thanks to user SRAM it's possible to save
year value and keep it up to date via driver code.

Tested on Planex_MZK-W300NAG (SoC is RT2880)

Submitted by:	Hiroki Mori <yamori83@yahoo.co.jp>
Differential Revision:	https://reviews.freebsd.org/D12833
2017-10-31 12:15:00 +00:00
Ian Lepore
d18915fadb Give icee(4) a detach() method so it can be used as a module. Add a
module makefile for it.
2017-09-17 22:58:13 +00:00
Ian Lepore
813c1b27fe Add a default implementation that returns ENODEV for start, repeat_start,
stop, read, and write methods.  Some controllers don't implement these
individual operations and have only a transfer method.  In that case, we
should return an indication that the device is present but doesn't support
the method, as opposed to the kobj default error ENXIO which makes it
look like the whole device is missing.  Userland tools such as i2c(8) can
use the differing return values to switch between the two different i2c
IO mechanisms.
2017-09-11 23:47:49 +00:00
Ian Lepore
a6e709f29c Add hinted attachment for non-FDT systems. Also, print a message if
setting up the timer fails, because on some types of chips that's the
first attempt to access the device.  If the chip is missing/non-responsive
then you'd get a driver that attached and didn't register the rtc, with
no clue about why.  On other chip types there are inits that come before
timer setup, and they already print messages about errors.
2017-08-14 02:23:10 +00:00
Ian Lepore
098f6cb6e6 Minor fixes and enhancements for the s35390a i2c RTC driver...
- Add FDT probe code.
- Do i2c transfers with exclusive bus ownership.
- Use config_intrhook_oneshot() to defer chip setup because some i2c
  busses can't do transfers without interrupts.
- Add a detach() routine.
- Add to module build.
2017-08-14 00:00:24 +00:00
Ian Lepore
90cff13c3c Remove the old ds1374 driver and use the ds13rtc driver instead. Adjust
several mips config files accordingly.
2017-08-13 22:07:42 +00:00
Ian Lepore
3777ed4378 Change "chiptype" to "compatible". Making the hint name the same as the FDT
property name should make it easier to document the list of names accepted
by both configuration mechanisms.
2017-08-13 21:45:46 +00:00
Ian Lepore
bb2e8108e1 Add a new driver, ds13rtc, that handles all DS13xx series i2c RTC chips.
This driver supports only basic timekeeping functionality.  It completely
replaces the ds133x driver.  It can also replace the ds1374 driver, but that
will take a few other changes in MIPS code and config, and will be committed
separately.  It does NOT replace the existing ds1307 driver, which provides
access to some of the extended features on the 1307 chip, such as controlling
the square wave output signal.  If both ds1307 and ds13rtc drivers are
present, the ds1307 driver will outbid and win control of the device.

This driver can be configured with FDT data, or by using hints on non-FDT
systems.  In addition to the standard hints for i2c devices, it requires
a "chiptype" string of the form "dallas,ds13xx" where 'xx' is the chip id
(i.e., the same format as FDT compat strings).
2017-08-13 21:02:40 +00:00
Ian Lepore
4541b9aab6 Bid for the device with BUS_PROBE_GENERIC, because this is very much a
generic driver with minimal feature support for a large number of chips.
More featureful per-chip drivers might exist (especially out-of-tree) and
those should win the bidding even if they use BUS_PROBE_DEFAULT.
2017-08-12 17:39:32 +00:00
Ian Lepore
94759a2448 Add a driver for the Intersil ISL12xx family of i2c RTC chips.
Supports ISL1209, ISL1218, ISL1219, ISL1220, ISL1221 (just basic RTC
functionality, not all the other fancy stuff the chips can do).
2017-08-01 04:16:52 +00:00
Ian Lepore
012e41a7a8 Bugfixes and enhancements...
Don't enable the oscillator when it is found to be stopped at init time,
just let the first setting of valid time start it.  But still report a dead
battery if it's stopped at init time.

Don't force the chip into 24hr mode, just cope with whatever mode it is
already in.

Schedule the clock_settime() callbacks to align the RTC clock to top of
second when setting it.
2017-07-31 22:00:00 +00:00
Ian Lepore
13fd9ff767 No need to call getnanotime() now that the waiting is done by the central
subr_rtc code, switch from CLOCKF_SETTIME_NO_TS to CLOCKF_SETTIME_NO_ADJ
so that we get fed a timestamp, but it's not adjusted to compensate for
inaccuracy in setting time.
2017-07-31 21:53:00 +00:00
Ian Lepore
def6c0c3ee Restore a few rather important lines of code that got fumbled in r321746. 2017-07-31 16:46:16 +00:00
Ian Lepore
bf9c1267f3 Check the clock-halted flag every time the clock is read, not just once
at startup.  The flag stays set until the clock is loaded with good time,
so we need to keep saying the time is invalid until that happens.
2017-07-31 15:24:40 +00:00
Ian Lepore
ccf32b9887 Add a detach() method. 2017-07-31 14:58:01 +00:00
Ian Lepore
cf24e991a6 Switch from using iic_transfer() to iicdev_readfrom/writeto(), mostly so
that transfers will be done with proper ownership of the bus. No
behavioral changes.  Also add a detach() method.
2017-07-31 14:57:02 +00:00
Ian Lepore
4c0c8a36da Remove now-unused variable. 2017-07-31 03:19:16 +00:00
Ian Lepore
02d094ff04 Use the new clock_schedule() to arrange for clock_settime() to be called
at the right time to keep the RTC hardware time in sync, instead of using
pause_sbt() to sleep until the right time.
2017-07-31 01:36:51 +00:00
Ian Lepore
2e639013ed Fix AM/PM mode handling. The bits to mask off in the hours register changes
between 12/24 hour mode.  Also fix conversion between 12 and 24 hour mode.
It's not as easy as adding/subtracting 12, because the clock doesn't roll
over 11->0, it rolls over 12->1; 0 isn't a valid hour in AM/PM mode.
2017-07-30 19:58:31 +00:00
Ian Lepore
d0462804d4 Bugfixes and enhancements...
Don't enable the oscillator when it is found to be stopped at init time,
just let the first setting of valid time start it.  But still report a dead
battery if it's stopped at init time.

Don't force the chip into 24hr mode, just cope with whatever mode it is
already in.

Align the RTC clock to top of second when setting it.
2017-07-30 18:46:38 +00:00
Ian Lepore
723a81dec6 Switch from using iic_transfer() to iicdev_readfrom/writeto(), mostly so
that transfers will be done with proper ownership of the bus. No
behavioral changes.
2017-07-30 16:17:06 +00:00
Ian Lepore
e25f1cf5be Fix building this driver on non-FDT platforms. 2017-07-30 00:00:30 +00:00
Ian Lepore
207fe81ea8 Replace the pcf8563 i2c RTC driver with a new nxprtc driver which handles
all the chips in the NXP PCA212x and PCA/PCF85xx series.  In addition to
supporting more chips, this driver uses the countdown timer on the chips as
a fractional seconds counter, giving it a resolution of about 15 milliseconds.
2017-07-29 23:45:57 +00:00
Ian Lepore
34199ee049 Add support for tracking nested calls to iicbus_request/release_bus().
Usually it is sufficient to use iicbus_transfer_excl(), or one of the
higher-level convenience functions that use it, to reserve the bus for the
duration of each register access.  Occasionally it is important that a
series of accesses or read-modify-write operations must be done without any
other intervening access to the device, to prevent corrupting state.

Without support for nested request/release, slave device drivers would have
to stop using high-level convenience functions and resort to working with
arrays of iic_msg structs just for a few operations (often involving
one-time device setup or infrequent configuration changes).

The changes here appear large from a glance at the diff, but in fact they're
nearly trivial, and the large diff is because of changes in indentation and
the re-wrapping of comments caused by that.  One notable change is that
iicbus_release_bus() now ignores the IICBUS_CALLBACK(IIC_RELEASE_BUS) return
value.  The old error handling left the bus in a kind of limbo state where
it was still owned at the iicbus layer, but drivers rarely check the return
of the release call, and it's unclear what they would do to recover from an
error return anyway.  No existing low-level drivers return any kind of error
from IIC_RELEASE_BUS except one EINVAL for "you don't own the bus", to which
the right response is probably to carry on with the process of releasing the
reference to the bus anyway.
2017-07-26 21:06:26 +00:00
Ian Lepore
7ec74c580d Add a pair of convenience routines for doing simple "register" read/writes
on i2c devices, where the "register" can be any length.

Many (perhaps most) common i2c devices are organized as a collection of
(usually 1-byte-wide) registers, and are accessed by first writing a 1-byte
register index/offset number, then by reading or writing the data.
Generally there is an auto-increment feature so the when multiple bytes
are read or written, multiple contiguous registers are accessed.

Most existing slave device drivers allocate an array of iic_msg structures,
fill in all the transfer info, and invoke iicbus_transfer().  These new
functions commonize all that and reduce register access to a simple call
with a few arguments.
2017-07-26 20:40:24 +00:00
Ian Lepore
a14af83085 Fix drivers that assume ticks starts at zero. These drivers all have logic
similar to "if (ticks > localvar+interval) {localvar=ticks; ...}" where
localvar is initialized to zero.  Ticks is initialized to a negative value
since r278230, and that leads to these if statements never being true.
2017-07-06 17:03:22 +00:00
Ian Lepore
930b312319 Add iic_recover_bus(), a helper function that can be used by any i2c driver
which is able to manipulate the clock and data lines directly.

When an i2c bus is hung by a slave device stuck in the middle of a
transaction that didn't complete properly, this function manipulates the
clock and data lines in a sequence known to reliably reset slave devices.
The most common cause of a hung i2c bus is a system reboot in the middle of
an i2c transfer (so it doesnt' happen often, but now there is a way other
than power cycling to recover from it).
2017-06-29 01:50:58 +00:00
Ian Lepore
f03b277259 If an i2c transfer ends due to error, issue a stop on the bus even if the
nostop option is set, if a start was issued.

The nostop option doesn't mean "never issue a stop" it means "only issue
a stop after the last in a series of transfers".  If the transfer ends
due to error, then that was the last transfer in the series, and a stop
is required.

Before this change, any error during a transfer when nostop is set would
effectively hang the bus, because sc->started would never get cleared,
and that caused all future calls to iicbus_start() to return an error
because it looked like the bus was already active.  (Unrelated errors in
handling the nostop option, to be addressed separately, could lead to
this bus hang condition even on busses that don't set the nostop option.)
2017-06-29 00:29:15 +00:00
Luiz Otavio O Souza
aee2c3a86a Always ignore the START and STOP bits whenever the control register is
being overwritten, they are set only bits (cleared by hardware).

Disable the Acknowledge of the controller slave address.  The slave mode is
not supported.

Make sure the interrupt flag bit is being cleared as recommended, add a
delay() _after_ clear the interrupt bit.

Sponsored by:	Rubicon Communications, LLC (Netgate)
2017-06-20 18:38:51 +00:00
Luiz Otavio O Souza
872625501b Make ofw_iicbus attach to twsi I2C controllers.
Add the ofw_bus_get_node() callback in mv_twsi, it is mandatory for the
ofw_iicbus usage.

Sponsored by:	Rubicon Communications, LLC (Netgate)
2017-06-20 18:25:27 +00:00
Pedro F. Giffuni
4d24901ac9 sys/dev: Replace zero with NULL for pointers.
Makes things easier to read, plus architectures may set NULL to something
different than zero.

Found with:	devel/coccinelle
MFC after:	3 weeks
2017-02-20 03:43:12 +00:00
Andriy Gapon
88cc0bb940 iicsmb: SMB_MAXBLOCKSIZE can be used again
The constant was set to the correct value in r308242.
While there, fix iicsmb_bread() to not use a value of an out parameter
'count'.

MFC after:	3 weeks
X-MFC after:	r308242
2016-11-11 15:11:54 +00:00
Andriy Gapon
448897d366 add iic interface to ig4 driver, move isl and cyapa to iicbus
Summary:
The hardware does not expose a classic SMBus interface.
Instead it has a lower level interface that can express a far richer
I2C protocol than what smbus offers.  However, the interface does not
provide a way to explicitly generate the I2C stop and start conditions.
It's only possible to request that the stop condition is generated
after transferring the next byte in either direction.  So, at least
one data byte must always be transferred.
Thus, some I2C sequences are impossible to generate, e.g., an equivalent
of smbus quick command (<start>-<slave addr>-<r/w bit>-<stop>).

At the same time isl(4) and cyapa(4) are moved to iicbus and now they use
iicbus_transfer for communication.  Previously they used smbus_trans()
interface that is not defined by the SMBus protocol and was implemented
only by ig4(4).  In fact, that interface was impossible to implement
for the typical SMBus controllers like intpm(4) or ichsmb(4) where
a type of the SMBus command must be programmed.

The plan is to remove smbus_trans() and all its uses.
As an aside, the smbus_trans() method deviates from the standard,
but perhaps backwards, FreeBSD convention of using 8-bit slave
addresses (shifted by 1 bit to the left).  The method expects
7-bit addresses.

There is a user facing consequence of this change.
A user must now provide device hints for isl and cyapa that specify an iicbus to use
and a slave address on it.
On Chromebook hardware where isl and cyapa devices are commonly found
it is also possible to use a new chromebook_platform(4) driver that
automatically configures isl and cyapa devices.  There is no need to
provide the device hints in that case,

Right now smbus(4) driver tries to discover all slaves on the bus.
That is very dangerous.  Fortunately, the probing code uses smbus_trans()
to do its job, so it is really enabled for ig4 only.
The plan is to remove that auto-probing code and smbus_trans().

Tested by:	grembo, Matthias Apitz <guru@unixarea.de> (w/o
		chromebook_platform)
Discussed with:	grembo, imp
Reviewed by:	wblock (docs)
MFC after:	1 month
Relnotes:	yes
Differential Revision: https://reviews.freebsd.org/D8172
2016-10-30 12:15:33 +00:00
Andriy Gapon
f1519c0157 convert iicsmb to use iicbus_transfer for all operations
Previously the driver used more low level operations like iicbus_start
and iicbus_write.  The problem is that those operations are not
implemented by iicbus(4) and the calls were effectively routed to
a driver to which the bus is attached.
But not all of the controllers implement such low level operations
while all of the drivers are expected to have iicbus_transfer.

While there fix incorrect implementation of iicsmb_bwrite and iicsmb_bread.
The former should send a byte count before the actual bytes, while the
latter should first receive the byte count and then receive the bytes.

I have tested only these commands:
- quick (r/w)
- send byte
- receive byte
- read byte
- write byte

MFC after:	1 month
Differential Revision: https://reviews.freebsd.org/D8170
2016-10-13 07:25:18 +00:00
Warner Losh
604d83bdce Implement iicbus_write_ivar and impelemnt the NOSTOP ivar in both read
and write.
2016-10-02 17:36:55 +00:00
Justin Hibbits
4332304f56 Fix ds1307 probing
'compat' can never be NULL, because the compatible check loop ends when
compat->ocd_str is NULL.  This causes ds1307 to attach to any unclaimed i2c
device.
2016-09-24 05:27:12 +00:00