linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nathan Royer <nroyer@invensense.com>
To: Nathan Royer <nroyer@invensense.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Greg Kroah-Hartman <gregkh@suse.de>,
	Jonathan Cameron <jic23@cam.ac.uk>, Jiri Kosina <jkosina@suse.cz>,
	Alan Cox <alan@linux.intel.com>,
	Jean Delvare <khali@linux-fr.org>,
	linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
	Chris Wolfe <cwolfe@chromium.org>
Subject: RE: [PATCH 05/11] misc: MPU3050 and slave device configuration.
Date: Fri, 1 Jul 2011 10:55:56 -0700	[thread overview]
Message-ID: <ccc4b7a8a3186c130a97bcf5f11ee9ff@mail.gmail.com> (raw)
In-Reply-To: <1309486707-1658-5-git-send-email-nroyer@invensense.com>

Regarding the secondary slave, I've decided to explain it in more detail
in this patch thread since this is where the high level configuration
happens.  I've clipped a number of the details to highlight just the high
level activity.  For the 3050 master i2c, configuration only occurs with
the accelerometer, but with the 6050 (not included in this patch), it can
support both an accel (external or internal), and compass, and pressure.

The first function here sets the bypass mode.  When in bypass mode, the
device master I2C of the mpu3050 is off and the slave chip (accelerometer
for the 3050) can be accessed directly on the same bus as the mpu3050.
When enable is set to false, the slave is disconnected from the bus, and
at that point the only operation that can occur is for the mpu3050 master
i2c to do a block read into the memory of the DMP.  The DMP then makes
this data available through its FIFO after some processing with the gyro
data.

Because of the bypass functionality, we designed all acces to the slave to
be through the MPU driver instead of stand alone.  That way we can first
put the mpu3050 into bypass before calling any of the slave functions that
will communicate directly with the chip.  For example the config functions
with apply == false do not enable bypass mode.
> +/**
> + *  @brief  enables/disables the I2C bypass to an external device
> + *          connected to MPU's secondary I2C bus.
> + *  @param  enable
> + *              Non-zero to enable pass through.
> + *  @return INV_SUCCESS if successful, a non-zero error code
> otherwise.
> + */
> +static int mpu_set_i2c_bypass(struct mldl_cfg *mldl_cfg,
> +			      void *mlsl_handle, unsigned char enable)
> +{
> +	return mpu3050_set_i2c_bypass(mldl_cfg, mlsl_handle, enable);
> +}
> +

This next function sets up the before mentioned block read, by setting the
slave I2C address, the slave I2C starting register, and the size of the
read.

> +
> +static int mpu_set_slave(struct mldl_cfg *mldl_cfg,
> +			 void *gyro_handle,
> +			 struct ext_slave_descr *slave,
> +			 struct ext_slave_platform_data *slave_pdata,
> +			 int slave_id)
> +{
> +	return mpu_set_slave_mpu3050(mldl_cfg, gyro_handle, slave,
> +				     slave_pdata, slave_id);
> +}

The rest of the work happens in the suspend and resume functions:

> +int inv_mpu_resume(struct mldl_cfg *mldl_cfg,
> +		   void *gyro_handle,
> +		   void *accel_handle,
> +		   void *compass_handle,
> +		   void *pressure_handle,
> +		   unsigned long sensors)
> +{

...

> +	for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) {
> +		if (!mldl_cfg->slave[ii] ||
> +		    !mldl_cfg->pdata_slave[ii] ||
> +		    !resume_slave[ii] ||
> +		    !(mldl_cfg->inv_mpu_state->status & (1 << ii)))
> +			continue;
> +

This loop is intended to also support the mpu6050 where multiple slaves
can be on the secondary bus, so each slave is checked to see if it is on
the secondary bus.  If it is, switch to bypass mode and resume the device.

> +		if (EXT_SLAVE_BUS_SECONDARY ==
> +		    mldl_cfg->pdata_slave[ii]->bus) {
> +			result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle,
> +						    true);
> +			if (result) {
> +				LOG_RESULT_LOCATION(result);
> +				return result;
> +			}
> +		}
> +		result = mldl_cfg->slave[ii]->resume(slave_handle[ii],
> +						mldl_cfg->slave[ii],
> +
mldl_cfg->pdata_slave[ii]);
> +		if (result) {
> +			LOG_RESULT_LOCATION(result);
> +			return result;
> +		}
> +		mldl_cfg->inv_mpu_state->status &= ~(1 << ii);
> +	}

Here is where the slave is set up.

> +	for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) {
> +		if (resume_dmp &&
> +		    !(mldl_cfg->inv_mpu_state->status & (1 << ii)) &&
> +		    mldl_cfg->pdata_slave[ii] &&
> +		    EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata_slave[ii]-
> >bus) {
> +			result = mpu_set_slave(mldl_cfg,
> +					gyro_handle,
> +					mldl_cfg->slave[ii],
> +					mldl_cfg->pdata_slave[ii],
> +					mldl_cfg->slave[ii]->type);
> +			if (result) {
> +				LOG_RESULT_LOCATION(result);
> +				return result;
> +			}
> +		}
> +	}
> +
> +	/* Turn on the master i2c iterface if necessary */
> +	if (resume_dmp) {

Here is where the bypass mode removed if the DMP needs the data.  If this
is done access to the slave cannot occur unless the mpu3050 is first
bypassed.

> +		result = mpu_set_i2c_bypass(
> +			mldl_cfg, gyro_handle,
> +			!(mldl_cfg->inv_mpu_state->i2c_slaves_enabled));
> +		if (result) {
> +			LOG_RESULT_LOCATION(result);
> +			return result;
> +		}
> +
> +		/* Now start */
> +		result = dmp_start(mldl_cfg, gyro_handle);
> +		if (result) {
> +			LOG_RESULT_LOCATION(result);
> +			return result;
> +		}
> +	}
> +	mldl_cfg->inv_mpu_cfg->requested_sensors = sensors;
> +
> +	return result;
> +}

We weren't interested in standalone drivers at the time we started writing
the driver, but I think now is the time to start thinking about how to
merge the two sets of requirements.  We currently support each sensor in a
standalone fashion, but in our own unique way, I just need to figure out
the right way.

The feedback I've seen so far suggest that the iio layer is where this
driver belongs and how the standalone interface should look.  Today was
the first I heard of the iio layer, so I have some significant research to
do on how to do this.  From my brief look this morning, it looks like
there is a lot of stuff already in place that we can make use of.

Again, everybody thank you for the feedback.  Very helpful!

  reply	other threads:[~2011-07-01 17:56 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-01  2:18 [PATCH 01/11] misc: inv_mpu primary header file and README file Nathan Royer
2011-07-01  2:18 ` [PATCH 02/11] misc: mpu3050 Register definition and Private data Nathan Royer
2011-07-01  2:18 ` [PATCH 03/11] misc: mpu3050 /dev/mpu implementation Nathan Royer
2011-07-01  2:18 ` [PATCH 04/11] misc: IRQ handling for MPU3050 and slave devices Nathan Royer
2011-07-01  2:18 ` [PATCH 05/11] misc: MPU3050 and slave device configuration Nathan Royer
2011-07-01 17:55   ` Nathan Royer [this message]
2011-07-01  2:18 ` [PATCH 06/11] misc: inv_mpu logging and debugging support Nathan Royer
2011-07-01  2:18 ` [PATCH 07/11] misc: I2C communication with the MPU3050 and slave devices Nathan Royer
2011-07-01  2:18 ` [PATCH 08/11] misc: Kconfig and Makefile changes for inv_mpu driver Nathan Royer
2011-07-01 17:10   ` Randy Dunlap
2011-07-01  2:18 ` [PATCH 09/11] misc: Add slave driver for kxtf9 accelerometer Nathan Royer
2011-07-01  2:18 ` [PATCH 10/11] misc: Add slave driver for ak8975 compass driver Nathan Royer
2011-07-01  2:18 ` [PATCH 11/11] misc: Add slave driver for bma085 pressure sensor Nathan Royer
2011-07-01  7:56   ` Alan Cox
2011-07-01  8:47     ` Jean Delvare
2011-07-01 14:28     ` Chris Wolfe
2011-07-01 14:41       ` Alan Cox
2011-07-01 15:52         ` Chris Wolfe
2011-07-01 17:00           ` Alan Cox
2011-07-01 17:56             ` Nathan Royer
2011-07-01 16:09         ` Jean Delvare
2011-07-01  9:05   ` Jonathan Cameron
2011-07-01 10:35     ` Manuel Stahl
2011-07-01  3:09 ` [PATCH 01/11] misc: inv_mpu primary header file and README file Greg KH
2011-07-01  7:29   ` Alan Cox
2011-07-01  9:00   ` Jonathan Cameron
2011-07-01  3:59 ` Chris Wolfe
2011-07-05 18:08   ` Nathan Royer
2011-07-01  7:53 ` Alan Cox
2011-07-01  9:08 ` Jonathan Cameron
2011-07-01 16:39   ` Nathan Royer
2011-07-03 11:29     ` Jonathan Cameron
2011-07-04  8:16       ` Alan Cox
2011-07-06  1:49         ` Nathan Royer
2011-07-06  9:07           ` Jonathan Cameron
2011-07-06 20:25             ` Nathan Royer
2011-07-06 10:54           ` Alan Cox
2011-07-06 21:27             ` Nathan Royer
2011-07-07  7:40               ` Alan Cox
2011-07-08  1:25                 ` Nathan Royer
2011-07-08 11:21                   ` Jonathan Cameron
2011-07-08 16:24                     ` Nathan Royer
2011-07-04 20:06       ` Eric Andersson
2011-07-01 21:04 ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ccc4b7a8a3186c130a97bcf5f11ee9ff@mail.gmail.com \
    --to=nroyer@invensense.com \
    --cc=akpm@linux-foundation.org \
    --cc=alan@linux.intel.com \
    --cc=cwolfe@chromium.org \
    --cc=gregkh@suse.de \
    --cc=jic23@cam.ac.uk \
    --cc=jkosina@suse.cz \
    --cc=khali@linux-fr.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).