This case involves some changes to the AC'97 interfaces delivered as part of
PSARC 2008/318.  However, since these interfaces are Consolidation Private,
backwards compatibility is supplied, and since the original interfaces were
never fully specified in the materials for PSARC 2008/318 (due to an error
on my part, oops!) despite having been delivered, I believe that it is
reasonable for this case to qualify as self review.

This case contains the full details for both the already delivered interfaces,
as well as the changes we are proposing.

While there is not a specific business need for an self-review case,
I'd like to get these changes into the next build.  That said, if anyone
believes this case warrants promotion to a fast track, please let me know.

        - Garrett

Template Version: @(#)sac_nextcase 1.68 02/23/09 SMI
This information is Copyright 2009 Sun Microsystems
1. Introduction
    1.1. Project/Component Working Name:
         AC'97 DDI Update
    1.2. Name of Document Author/Supplier:
         Author:  Garrett D'Amore
    1.3  Date of This Document:
        27 August, 2009
4. Technical Description


Problem:
--------

The interfaces that were originally supplied as part of the Boomer case
(PSARC 2008/318) for AC'97 have proven to be limiting for some devices,
which use AC'97 codecs in "unconventional ways".  Such devices may have
more than one AC'97 codec, or may use AC'97 only for a particular purpose.
(For example, Creative Audigy LS devices use AC'97 only to manage the
capture data; I2S DACs are used for playback.)

For these situations, we need an update to the AC'97 DDI so that devices have
more control over which audio controls an AC'97 codec supports are exposed
through the Boomer framework.  We would also like devices to be able to
access the underlying AC'97 controls so that they can use, or extend, them
without necessarily exposing them directly to Boomer.

Furthermore, due to an oversight, the AC'97 DDI details were never supplied
as part of the original Boomer case, although it was listed as Consolidation
Private in the interface table.

Despite this, a number of existing drivers make use of the AC'97 DDI.


Solution
--------

We propose a new AC'97 DDI, which is free from the limitations of the first
AC'97 DDI.  The previous DDI will remain supported (as Obsolete Consolidation
Private) until the drivers can be updated to the new one.

New AC'97 DDI
-------------

The new AC'97 DDI is as follows:

typedef struct ac97 ac97_t;
typedef void (*ac97_wr_t)(void *, uint8_t, uint16_t);
typedef uint16_t (*ac97_rd_t)(void *, uint8_t);
typedef struct ac97_ctrl ac97_ctrl_t;
typedef boolean_t (*ac97_ctrl_walk_t)(ac97_ctrl_t *, void *);

ac97_t *ac97_allocate(audio_dev_t *, dev_info_t *, ac97_rd_t, ac97_wr_t,
        void *);

    This function allocates a new AC'97 handle for the given audio device
    and devinfo node.  The register access functions are supplied.  The last
    void * argument is a pointer to the driver's private state, which will
    be passed to the register access routines.

void ac97_probe_controls(ac97_t *);

    This function must be called during attach.  It initializes the hardware
    and probes for the various AC'97 controls that might be present on the
    codec.  It can only be called once, and must be called before the
    driver calls audio_dev_register(), and after ac97_allocate().

void ac97_register_controls(ac97_t *);

    This function can only be called once, after ac97_probe_controls() is
    called, and before audio_dev_register() is called.  If used, it will
    register all of the codec controls with the audio framework.  (A driver
    need not execute this if it wants more fine grained control over which
    controls are exposed to the framework.)

void ac97_unregister_controls(ac97_t *);

    This function unregisters all controls from the audio framework.  Its use
    is optional, as ac97_free() also performs this step.  It should only be
    called during detach() processing.

void ac97_walk_controls(ac97_t *, ac97_ctrl_walk_t, void *);

    This function walks a list of all controls known to the codec.  The
    walk function is executed once for each control, until the end of the
    list of controls is reached, or the walk function returns B_FALSE.

ac97_ctrl_t *ac97_control_find(ac97_t *, const char *);

    This function is used to find a named control (using the control's name
    such as AUDIO_CTRL_ID_VOLUME).

void ac97_control_register(ac97_ctrl_t *);

    This function may be used to individually register a provided control
    with the audio framework.  It should only be called once for a given
    control, and its use is mutually exclusive with ac97_register_controls().

void ac97_control_unregister(ac97_ctrl_t *);

    This function may be used to individually unregister a provided control
    from the audio framework.  Few, if any, drivers are likely to need this.

void ac97_control_remove(ac97_ctrl_t *);

    This function removes a control entirely.  It will also unregister the
    control if it has already been registered.  The best use of this function
    is to eliminate controls *before* calling ac97_register_controls().   It
    may *only* be called during attach or detach processing, when the driver
    is otherwise single threaded.  (It will safely unregister the control
    from the audio framework though, so the driver need not be concerned about
    accesses originating from the audio framework itself.)

    This function is implicitly executed for each control by ac97_free().

const char *ac97_control_name(ac97_ctrl_t *);

    This function returns the name of a control, such as AUDIO_CTRL_ID_VOLUME.
    This wll be most useful in conjunction with ac97_walk_controls().

int ac97_control_get(ac97_ctrl_t *, uint64_t *);
int ac97_control_set(ac97_ctrl_t *, uint64_t);

    These functions are used to retrieve or change the value associated with
    the control.

void ac97_free(ac97_t *);

    This function is used to tear down and free all state associated with the
    AC'97 codec.  The driver must be single threaded when it calls this
    function.

void ac97_suspend(ac97_t *);

    This function is to be called during DDI_SUSPEND handling.  After it
    returns, changes to control values will be deferred until the device
    is resumed.  (Control changes will be made to shadowed state, which will
    be "replayed" when ac97_resume is called.) 

void ac97_resume(ac97_t *);

    This restores all codec settings and resumes normal operation as part
    of DDI_RESUME handling.

void ac97_reset(ac97_t *);

    This is used to perform a master reset of the codec.

int ac97_num_channels(ac97_t *);

    This returns the number of channels (2, 4, 6, or even 8) that the codec
    supports.  This can be useful for drivers to avoid allocating resources
    for more channels than the codec can support.  It can only be executed
    after ac97_probe_controls() has finished.


Obsolete Interfaces
-------------------

These interfaces are left in place for now, to avoid changing the the
half dozen or so drivers that still use them.  Eventually those drivers will
be updated and these interfaces can be removed.  They are now Obsolete
Consolidation Private.

ac97_t *ac97_alloc(dev_info_t *, ac97_rd_t, ac97_wr_t, void *);

   This function is almost identical to ac97_allocate(), except that the
   audio_dev is elided.  It is supplied with the ac97_init() call instead.
 
int ac97_init(ac97_t *, audio_dev_t *);

   This function sets up the audio_dev pointer, and performs the logical
   equivalent of ac97_probe_controls() followed immediately by
   ac97_register_controls().  Its use is incompatible with any direct access
   to the list of controls or to controls themselves by device drivers.

Interface Tables
----------------
_____________________________________________________________________________
|                            Interfaces Exported                             |
|_________________________|_______________________|__________________________|
|Interface                |  Classification       |  Comments                |
|_________________________|_______________________|__________________________|
|ac97_alloc               | Obs. Consol. Private  | Old DDI                  |
|ac97_init                | Obs. Consol. Private  |  "   "                   |
|ac97_allocate            | Consolidation Private | New DDI                  |
|ac97_probe_controls      |      "          "     |  "   "                   |
|ac97_register_controls   |      "          "     |  "   "                   |
|ac97_unregister_controls |      "          "     |  "   "                   |
|ac97_walk_controls       |      "          "     |  "   "                   |
|ac97_control_register    |      "          "     |  "   "                   |
|ac97_control_unregister  |      "          "     |  "   "                   |
|ac97_control_find        |      "          "     |  "   "                   |
|ac97_control_name        |      "          "     |  "   "                   |
|ac97_control_set         |      "          "     |  "   "                   |
|ac97_control_get         |      "          "     |  "   "                   |
|ac97_control_remove      |      "          "     |  "   "                   |
|ac97_free                |      "          "     | Unchanged DDI            |
|ac97_suspend             |      "          "     |  "   "                   |
|ac97_resume              |      "          "     |  "   "                   |
|ac97_num_channels        |      "          "     |  "   "                   |
|ac97_t                   |      "          "     | Codec handle (unchanged) |
|ac97_rd_t, ac97_wr_t     |      "          "     | Reg access funcs (unchg) |
|ac97_ctrl_t              |      "          "     | Control handle (new)     |
|ac97_walk_t              |      "          "     | Walk function (new)      |
|_________________________|_______________________|__________________________|


______________________________________________________________________________
|                             Interfaces Imported                            |
|_________________________|_______________________|__________________________|
|Interface                |  Classification       |  Comments                |
|_________________________|_______________________|__________________________|
|audio_dev_t              | Consolidation Private | PSARC 2008/318           |
|audio_ctrl_t             |      "          "     |   "    "                 |
|audio_ctrl_desc_t        |      "          "     |   "    "                 |
|audio_dev_warn           |      "          "     |   "    "                 |
|audio_dev_add_control    |      "          "     |   "    "                 |
|audio_dev_del_control    |      "          "     |   "    "                 |
|Control names            |      "          "     |   "    "                 |
|_________________________|_______________________|__________________________|

6. Resources and Schedule
    6.4. Steering Committee requested information
        6.4.1. Consolidation C-team Name:
                ON
    6.5. ARC review type: Automatic
    6.6. ARC Exposure: open


Reply via email to