1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/*
* @(#)drv_toshiba.c 1.6 03 Jun 1995
*
* Vendor-specific drive control routines for Toshiba XM-3401 series.
*/
static char *ident = "@(#)drv_toshiba.c 1.6 03 Jun 1995";
#include <stdio.h>
#include <errno.h>
#include "struct.h"
#define SCMD_TOSH_EJECT 0xc4
static int tosh_init(), tosh_eject(), tosh_closetray(), tosh_set_volume(), tosh_get_volume();
int wm_scsi2_get_volume(), wm_scsi2_set_volume();
struct wm_drive toshiba_proto = {
-1, /* fd */
"Toshiba", /* vendor */
"", /* model */
NULL, /* aux */
NULL, /* daux */
tosh_init, /* functions... */
gen_get_trackcount,
gen_get_cdlen,
gen_get_trackinfo,
gen_get_drive_status,
tosh_get_volume,
tosh_set_volume,
gen_pause,
gen_resume,
gen_stop,
gen_play,
tosh_eject,
tosh_closetray
};
/*
* Initialize the driver.
*/
static int
tosh_init(d)
struct wm_drive *d;
{
extern int min_volume;
min_volume = 0;
}
/*
* Send the Toshiba code to eject the CD.
*/
static int
tosh_eject(d)
struct wm_drive *d;
{
return (sendscsi(d, NULL, 0, 0, SCMD_TOSH_EJECT, 1, 0,0,0,0,0,0,0,0));
}
/*
* Close tray
* Dummie function only, return error
*/
static int
tosh_closetray(d)
struct wm_drive *d;
{
return(-1);
}
/*
* Set the volume. The low end of the scale is more sensitive than the high
* end, so make up for that by transforming the volume parameters to a square
* curve.
*/
static int
tosh_set_volume(d, left, right)
struct wm_drive *d;
int left, right;
{
left = (left * left * left) / 10000;
right = (right * right * right) / 10000;
return (gen_set_volume(d, left, right));
}
/*
* Undo the transformation above using a binary search (so no floating-point
* math is required.)
*/
static int
unscale_volume(cd_vol, max)
int cd_vol, max;
{
int vol = 0, top = max, bot = 0, scaled;
/*cd_vol = (cd_vol * 100 + (max_volume - 1)) / max_volume;*/
while (bot <= top)
{
vol = (top + bot) / 2;
scaled = (vol * vol) / max;
if (cd_vol <= scaled)
top = vol - 1;
else
bot = vol + 1;
}
/* Might have looked down too far for repeated scaled values */
if (cd_vol < scaled)
vol++;
if (vol < 0)
vol = 0;
else if (vol > max)
vol = max;
return (vol);
}
/*
* Get the volume.
*/
static int
tosh_get_volume(d, left, right)
struct wm_drive *d;
int *left, *right;
{
int status;
status = gen_get_volume(d, left, right);
if (status < 0)
return (status);
*left = unscale_volume(*left, 100);
*right = unscale_volume(*right, 100);
return (0);
}
|